From 176433a56eabe227ef8d78e620b434e676a4c0c5 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 18:18:30 +0200 Subject: [PATCH 001/417] =?UTF-8?q?tweaker:=20click-again=20climbs=20the?= =?UTF-8?q?=20pick=20=E2=80=94=20the=20container=20under=20the=20children?= =?UTF-8?q?=20is=20reachable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The deepest-wins pick could never land on a container its children fully cover (the chat panel, any rounded-bg pane). Now clicking inside the pinned widget again walks the pin up one ancestor per click, skipping design-transparent views, zero-rect wrappers and ancestors whose area misses the click (a splitter's grab bar); at the window the climb wraps back to the deepest pick. The window itself is never borrowed — it is mid-dispatch when the handler runs (tree lookups decide before any widget borrow). Co-Authored-By: Claude Fable 5 --- widgets/src/tweaker.rs | 105 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/widgets/src/tweaker.rs b/widgets/src/tweaker.rs index 822436ce9..57a3b1440 100644 --- a/widgets/src/tweaker.rs +++ b/widgets/src/tweaker.rs @@ -599,6 +599,89 @@ fn resolve_pick( }) } +/// A TweakPick for a KNOWN widget (the climb's steps), same fields as a +/// resolved one. +fn pick_of_widget( + cx: &mut Cx, + widget: &WidgetRef, + abs: Vec2d, + window_id: usize, +) -> Option { + let uid = widget.widget_uid(); + let rect = widget.area().clipped_rect_union(cx); + if rect.size.x <= 0.0 || rect.size.y <= 0.0 { + return None; + } + let level = cx.sploded_depth_of(uid.0).unwrap_or(0); + let path_ids = cx.widget_tree().path_to(uid); + let path = if path_ids.is_empty() { + format!("uid:{}", uid.0) + } else { + path_ids + .iter() + .map(|id| live_id_token(*id)) + .collect::>() + .join(".") + }; + let ty = widget + .widget_type_id() + .and_then(|type_id| widget_type_names(cx).get(&type_id).copied()) + .map(live_id_token) + .unwrap_or_else(|| "-".to_string()); + let band = resolve_band(cx, widget, rect, abs); + Some(TweakPick { uid: uid.0, path, ty, rect, window_id, band, level }) +} + +/// Is `ancestor` on `uid`'s parent chain? +fn is_ancestor_of(cx: &mut Cx, ancestor: u64, uid: u64) -> bool { + let mut cur = cx.widget_tree().parent_of(WidgetUid(uid)); + for _ in 0..64 { + match cur { + Some(u) if u.0 == ancestor => return true, + Some(u) => cur = cx.widget_tree().parent_of(u), + None => return false, + } + } + false +} + +/// The pin's next ancestor worth pinning: skips design-transparent views and +/// zero-rect wrappers; `None` at the top (the caller wraps to the deepest). +fn ancestor_pick( + cx: &mut Cx, + pin: &TweakPick, + abs: Vec2d, + window_id: usize, +) -> Option { + let mut cur = cx.widget_tree().parent_of(WidgetUid(pin.uid)); + for _ in 0..64 { + let u = cur?; + // The window and above are chrome, not content — and the window is + // mutably borrowed mid-dispatch, so it must not even be touched + // (tree lookups only, no widget borrow, before deciding). + let above = cx.widget_tree().parent_of(u)?; + if cx.widget_tree().parent_of(above).is_none() { + return None; + } + let widget = cx.widget_tree().widget(u); + if widget.is_empty() { + return None; + } + if !is_design_transparent(&widget) { + if let Some(pick) = pick_of_widget(cx, &widget, abs, window_id) { + // An ancestor whose area misses the click (a splitter whose + // rect is only its grab bar) would throw the brackets to a + // far-away sliver — climb past it. + if pick.rect.contains(abs) { + return Some(pick); + } + } + } + cur = cx.widget_tree().parent_of(u); + } + None +} + // --------------------------------------------------------------------------- // the Window seam — swallow pointer events before ordinary dispatch while // the overlay is on, so picking can never activate the app's widgets. @@ -1010,6 +1093,28 @@ pub fn window_intercept( session().lock().unwrap().live_stroke = Some(stroke); } else { let pick = resolve_pick(cx, &body, abs, window_id.id()); + // CLICK-TO-CLIMB: clicking inside the pinned widget again + // walks the pin UP one ancestor per click — the only way a + // container fully covered by its children (the pane that + // draws the rounded background) can ever be reached. At the + // top the climb wraps back to the deepest pick. + let pick = { + let pinned = session().lock().unwrap().pinned.clone(); + match (pick, pinned) { + (Some(deep), Some(pin)) + if pin.window_id == window_id.id() + && pin.rect.contains(abs) + && (deep.uid == pin.uid + || is_ancestor_of(cx, pin.uid, deep.uid)) => + { + Some( + ancestor_pick(cx, &pin, abs, window_id.id()) + .unwrap_or(deep), + ) + } + (deep, _) => deep, + } + }; let mut s = session().lock().unwrap(); match &pick { Some(pick) => { From 6251f7c6156c743e91a7920e4472515c0b2c93a4 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 19:05:34 +0200 Subject: [PATCH 002/417] =?UTF-8?q?ai-hub:=20body=20domain=20=E2=80=94=20l?= =?UTF-8?q?ive=20pose=20packets=20ride=20the=20realtime=20session?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New `body` backend (sam3dbody-ref): a persistent length-prefixed-PNG / JSON-lines worker subprocess seam with ready handshake, per-frame timeout, bounded restarts. LiveFrameOut grows aux_json — structured per-frame JSON sent to the client before the frame — and output_encoding "none" makes a session pose-only (refused with loop_mode feedback, also on control flips, which upgraded apply_control to Result). Worker code+model stay box-provisioned via MAKEPAD_SAM3DBODY_WORKER; the repo carries only the MIT seam. Codex lane + Fable review (ready handshake, spawn timeout). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_0165w1ZL1f1TruX5u2qC7mSX --- libs/ai/hub/Cargo.toml | 5 + libs/ai/hub/registry.json | 16 + libs/ai/hub/src/backend.rs | 35 ++- libs/ai/hub/src/body_backend.rs | 486 +++++++++++++++++++++++++++++++ libs/ai/hub/src/flux2_backend.rs | 1 + libs/ai/hub/src/lib.rs | 1 + libs/ai/hub/src/protocol.rs | 12 +- libs/ai/hub/src/realtime.rs | 97 +++++- libs/ai/hub/src/realtime_wire.rs | 21 ++ libs/ai/hub/src/registry.rs | 15 +- libs/ai/hub/src/testpattern.rs | 1 + libs/ai/hub/tests/body_worker.rs | 219 ++++++++++++++ 12 files changed, 892 insertions(+), 17 deletions(-) create mode 100644 libs/ai/hub/src/body_backend.rs create mode 100644 libs/ai/hub/tests/body_worker.rs diff --git a/libs/ai/hub/Cargo.toml b/libs/ai/hub/Cargo.toml index f19c02fa8..962ffe022 100644 --- a/libs/ai/hub/Cargo.toml +++ b/libs/ai/hub/Cargo.toml @@ -136,6 +136,11 @@ makepad-live-id = { path = "../../live_id" } # internally (behind the crate's own optional/default `video` feature). makepad-video = { path = "../../../platform/video" } +[[test]] +name = "body_worker" +path = "tests/body_worker.rs" +harness = false + # The standing "is chat slow right now?" check. Its own code is std-only — # no HTTP or JSON crate — so what it measures is the box, not a client # library, and it keeps working when the wire grows fields it has never diff --git a/libs/ai/hub/registry.json b/libs/ai/hub/registry.json index d7f4fbcf1..deb1c88d9 100644 --- a/libs/ai/hub/registry.json +++ b/libs/ai/hub/registry.json @@ -1741,6 +1741,22 @@ } ] }, + { + "id": "sam3dbody-ref", + "domain": "body", + "backend": "body", + "available": true, + "gated": false, + "license": { + "name": "SAM 3D Body License", + "url": "https://github.com/facebookresearch/sam-3d-body", + "summary": "SAM 3D Body is served by an externally provisioned worker. Review and comply with the upstream model and checkpoint terms before production use.", + "restriction": "community" + }, + "vram_gb": 4.0, + "note": "SAM 3D Body reference worker: live or single-image RGB input -> application/json human pose packet. The Rust hub only owns the persistent length-prefixed PNG/JSON-lines process seam; the worker and model remain box-provisioned through MAKEPAD_SAM3DBODY_WORKER. Warm reference inference is approximately 0.6-0.9 seconds per frame and uses approximately 3.5 GiB VRAM.", + "files": [] + }, { "id": "sam3-1-multiplex", "domain": "segment", diff --git a/libs/ai/hub/src/backend.rs b/libs/ai/hub/src/backend.rs index ab33e3165..a710c782c 100644 --- a/libs/ai/hub/src/backend.rs +++ b/libs/ai/hub/src/backend.rs @@ -589,6 +589,9 @@ pub fn img2img_start_step(strength: f32, steps: u32) -> u32 { /// enforced (it picks what the session itself encodes and pushes). #[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] pub enum OutputEncoding { + /// Do not send output frames. JSON stats/aux/error/stopped messages still + /// flow, making this suitable for structured per-frame backends. + None, /// Raw RGB8, no compression — cheapest on a LAN, always available. #[default] Raw, @@ -606,14 +609,16 @@ impl OutputEncoding { "" | "raw" => Ok(OutputEncoding::Raw), "png" => Ok(OutputEncoding::Png), "h264" => Ok(OutputEncoding::H264), + "none" => Ok(OutputEncoding::None), other => Err(AssetAiError::Params(format!( - "unknown output_encoding {other:?} (expected \"raw\", \"png\" or \"h264\")" + "unknown output_encoding {other:?} (expected \"none\", \"raw\", \"png\" or \"h264\")" ))), } } pub fn as_str(&self) -> &'static str { match self { + OutputEncoding::None => "none", OutputEncoding::Raw => "raw", OutputEncoding::Png => "png", OutputEncoding::H264 => "h264", @@ -625,7 +630,7 @@ impl OutputEncoding { /// hardware codec seam); `Raw`/`Png` are always available. pub fn is_supported_in_this_build(&self) -> bool { match self { - OutputEncoding::Raw | OutputEncoding::Png => true, + OutputEncoding::None | OutputEncoding::Raw | OutputEncoding::Png => true, OutputEncoding::H264 => cfg!(feature = "video"), } } @@ -979,6 +984,12 @@ impl LiveParams { input_encoding.as_str() ))); } + if loop_mode == LoopMode::Feedback && output_encoding == OutputEncoding::None { + return Err(AssetAiError::Params( + "realtime: loop_mode \"feedback\" requires output frames; output_encoding \"none\" is not allowed" + .to_string(), + )); + } let max_fps = request .max_fps .filter(|v| v.is_finite() && *v >= 0.0) @@ -1051,13 +1062,15 @@ pub struct LiveFrameIn<'a> { pub config: &'a LiveConfig, } -/// One `ContentBackend::live_step` call's output: the produced frame plus -/// the backend's own wall-clock cost (surfaced in the `stats` message's -/// `stage_ms.model`) and, inside that, the share the text encoder took -/// (`stage_ms.text_encode`; 0 for backends without one, and near 0 on the -/// frames where `flux2_backend` served the prompt embeds from its cache). +/// One `ContentBackend::live_step` call's output: the produced frame, an +/// optional structured JSON packet sent before that frame, plus the backend's +/// own wall-clock cost (surfaced in the `stats` message's `stage_ms.model`) +/// and, inside that, the share the text encoder took (`stage_ms.text_encode`; +/// 0 for backends without one, and near 0 on frames where `flux2_backend` +/// served the prompt embeds from its cache). pub struct LiveFrameOut { pub image: RgbImage, + pub aux_json: Option, pub model_ms: f64, pub text_encode_ms: f64, } @@ -1546,6 +1559,7 @@ pub fn backend_live_supported(spec: &ModelSpec) -> bool { pub fn backend_compiled(name: &str) -> bool { match name { "testpattern" => true, + "body" => true, "flux" | "flux2" | "control" | "flux-fill" => cfg!(feature = "flux"), "llm" => cfg!(feature = "llm"), // The vision domain rides the same llama session + the mmproj tower, @@ -1621,6 +1635,7 @@ pub fn backend_provisioned(name: &str) -> bool { // on macOS, CUDA on Windows/Linux, probed once and memoised. "vision" => crate::vision_backend::vision_provisioned(), "ocr" => crate::vision_backend::vision_provisioned(), + "body" => crate::body_backend::body_provisioned(), "depth-native" => cfg!(feature = "depth-native"), "segment-native" => cfg!(feature = "segment-native"), "upscale-native" => cfg!(feature = "upscale-native"), @@ -1752,6 +1767,7 @@ pub fn create_backend(spec: &ModelSpec) -> Result, Asset "testpattern" => Ok(Box::new(crate::testpattern::TestPatternBackend::new( &spec.id, ))), + "body" => Ok(Box::new(crate::body_backend::BodyBackend::new(&spec.id))), #[cfg(feature = "flux")] "flux" => Ok(Box::new(crate::flux_backend::FluxBackend::new(&spec.id))), #[cfg(not(feature = "flux"))] @@ -2044,6 +2060,11 @@ mod tests { assert!(model_availability(&model, &GpuInfo::default(), 2 * 1024).is_ok()); } + #[test] + fn body_backend_is_compiled() { + assert!(backend_compiled("body")); + } + #[test] fn declared_gpu_requirements_fail_closed_at_exact_boundaries() { let mut model = spec("testpattern", true, Some(20.0)); diff --git a/libs/ai/hub/src/body_backend.rs b/libs/ai/hub/src/body_backend.rs new file mode 100644 index 000000000..1838391a2 --- /dev/null +++ b/libs/ai/hub/src/body_backend.rs @@ -0,0 +1,486 @@ +//! SAM 3D Body worker backend for the `body` domain. +//! +//! The worker returns one JSON object per input frame. Its pose packet schema +//! is `{"n_people":N,"people":[{"mhr":[204 f32],"global_rot":[3], +//! "cam_t":[3],"shape":[45],"expr":[72],"focal":f32,"bbox":[4], +//! "joints":[[x,y,z] x127]?}]}`. Rust validates only that the line is JSON +//! with a top-level `n_people` field and otherwise forwards it opaquely. + +use crate::backend::{ + ArtifactData, BackendCtx, CancelToken, ContentBackend, GenerateParams, LiveFrameIn, + LiveFrameOut, ProgressSink, +}; +use crate::error::AssetAiError; +use makepad_strict_json::Value; +use std::io::{BufRead, BufReader, Write}; +use std::process::{Child, ChildStdin, Command, Stdio}; +use std::sync::mpsc::{self, Receiver, RecvTimeoutError}; +use std::thread::JoinHandle; +use std::time::{Duration, Instant}; + +pub const BODY_WORKER_ENV: &str = "MAKEPAD_SAM3DBODY_WORKER"; +pub const BODY_TIMEOUT_ENV: &str = "MAKEPAD_SAM3DBODY_TIMEOUT_S"; +pub const BODY_SPAWN_TIMEOUT_ENV: &str = "MAKEPAD_SAM3DBODY_SPAWN_TIMEOUT_S"; +const DEFAULT_TIMEOUT_S: f64 = 10.0; +// The real worker loads its model at spawn (~12s reference, more on a cold +// disk) and only then emits its `{"ready":true}` line — the per-frame +// timeout must not start until that handshake, or the first frame kills a +// still-loading worker and the restart loop reloads it forever. +const DEFAULT_SPAWN_TIMEOUT_S: f64 = 120.0; +const MAX_RESTARTS: u8 = 3; + +pub fn body_provisioned() -> bool { + std::env::var(BODY_WORKER_ENV) + .ok() + .is_some_and(|command| !command.trim().is_empty()) +} + +fn configured_command() -> Result, AssetAiError> { + let command = std::env::var(BODY_WORKER_ENV).map_err(|_| { + AssetAiError::Unavailable(format!( + "sam3dbody worker is not configured; set {BODY_WORKER_ENV}" + )) + })?; + let parts: Vec = command + .split_whitespace() + .map(str::to_string) + .collect(); + if parts.is_empty() { + return Err(AssetAiError::Unavailable(format!( + "sam3dbody worker command in {BODY_WORKER_ENV} is empty" + ))); + } + Ok(parts) +} + +fn positive_seconds_env(env: &str, default_s: f64) -> Result { + let Some(text) = std::env::var(env).ok() else { + return Ok(Duration::from_secs_f64(default_s)); + }; + let seconds = text.parse::().ok().filter(|s| s.is_finite() && *s > 0.0); + match seconds { + Some(seconds) => Ok(Duration::from_secs_f64(seconds)), + None => Err(AssetAiError::Unavailable(format!( + "{env} must be a positive number of seconds, got {text:?}" + ))), + } +} + +fn configured_timeout() -> Result { + positive_seconds_env(BODY_TIMEOUT_ENV, DEFAULT_TIMEOUT_S) +} + +fn configured_spawn_timeout() -> Result { + positive_seconds_env(BODY_SPAWN_TIMEOUT_ENV, DEFAULT_SPAWN_TIMEOUT_S) +} + +enum WorkerRead { + Line(String), + Eof, + Error(String), +} + +struct WorkerProcess { + child: Child, + stdin: Option, + lines: Receiver, + reader: Option>, + // The worker's first stdout line must be its ready handshake (a JSON + // object with a `ready` field), emitted after its model finishes + // loading; frames sent before it are only buffered by the OS pipe. + ready_seen: bool, +} + +impl Drop for WorkerProcess { + fn drop(&mut self) { + self.stdin.take(); + let _ = crate::child_process::kill_tree(&mut self.child); + let _ = self.child.wait(); + if let Some(reader) = self.reader.take() { + let _ = reader.join(); + } + } +} + +/// Persistent length-prefixed PNG / JSON-lines worker connection. +pub struct BodyWorker { + command: Vec, + timeout: Duration, + spawn_timeout: Duration, + process: Option, + restarts: u8, +} + +impl BodyWorker { + pub fn new() -> Result { + let mut worker = Self { + command: configured_command()?, + timeout: configured_timeout()?, + spawn_timeout: configured_spawn_timeout()?, + process: None, + restarts: 0, + }; + worker.spawn_process()?; + Ok(worker) + } + + fn spawn_process(&mut self) -> Result<(), AssetAiError> { + let mut command = Command::new(&self.command[0]); + command + .args(&self.command[1..]) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::inherit()); + let mut child = crate::child_process::spawn(&mut command).map_err(|error| { + AssetAiError::Unavailable(format!( + "spawn sam3dbody worker {:?}: {error}", + self.command + )) + })?; + let stdin = child.stdin.take().ok_or_else(|| { + AssetAiError::Backend("sam3dbody worker has no piped stdin".to_string()) + })?; + let stdout = child.stdout.take().ok_or_else(|| { + AssetAiError::Backend("sam3dbody worker has no piped stdout".to_string()) + })?; + let (line_tx, lines) = mpsc::channel(); + let reader = std::thread::spawn(move || { + let mut stdout = BufReader::new(stdout); + loop { + let mut line = String::new(); + match stdout.read_line(&mut line) { + Ok(0) => { + let _ = line_tx.send(WorkerRead::Eof); + return; + } + Ok(_) => { + while line.ends_with('\n') || line.ends_with('\r') { + line.pop(); + } + if line_tx.send(WorkerRead::Line(line)).is_err() { + return; + } + } + Err(error) => { + let _ = line_tx.send(WorkerRead::Error(error.to_string())); + return; + } + } + } + }); + self.process = Some(WorkerProcess { + child, + stdin: Some(stdin), + lines, + reader: Some(reader), + ready_seen: false, + }); + Ok(()) + } + + /// Waits for the worker's `{"ready":true}` handshake line under the + /// spawn timeout. Returns Ok(true) when ready, Ok(false) after a + /// restart (caller re-enters its loop), Err on cancel/timeout/limit. + fn await_ready(&mut self, cancel: &CancelToken) -> Result { + if self.process.as_ref().unwrap().ready_seen { + return Ok(true); + } + let deadline = Instant::now() + self.spawn_timeout; + loop { + if cancel.is_cancelled() { + self.stop_process(); + return Err(AssetAiError::Cancelled); + } + let now = Instant::now(); + if now >= deadline { + self.stop_process(); + return Err(AssetAiError::Backend(format!( + "sam3dbody worker not ready after {:.0} seconds", + self.spawn_timeout.as_secs_f64() + ))); + } + let wait = (deadline - now).min(Duration::from_millis(50)); + match self.process.as_ref().unwrap().lines.recv_timeout(wait) { + Ok(WorkerRead::Line(line)) => { + let is_ready = makepad_strict_json::parse(line.as_bytes()) + .ok() + .is_some_and(|value| value.get("ready").is_some()); + if is_ready { + self.process.as_mut().unwrap().ready_seen = true; + return Ok(true); + } + self.restart_after_death(&format!( + "first line was not the ready handshake: {line:.120}" + ))?; + return Ok(false); + } + Ok(WorkerRead::Eof) => { + self.restart_after_death("exited before ready handshake")?; + return Ok(false); + } + Ok(WorkerRead::Error(error)) => { + self.restart_after_death(&format!("stdout read failed: {error}"))?; + return Ok(false); + } + Err(RecvTimeoutError::Timeout) => {} + Err(RecvTimeoutError::Disconnected) => { + self.restart_after_death("stdout reader stopped")?; + return Ok(false); + } + } + } + } + + fn stop_process(&mut self) { + self.process.take(); + } + + fn restart_after_death(&mut self, reason: &str) -> Result<(), AssetAiError> { + self.stop_process(); + if self.restarts >= MAX_RESTARTS { + return Err(AssetAiError::Backend(format!( + "sam3dbody worker died after {MAX_RESTARTS} restarts: {reason}" + ))); + } + self.restarts += 1; + self.spawn_process() + } + + pub fn ensure_started(&mut self) -> Result<(), AssetAiError> { + if self.process.is_none() { + self.spawn_process()?; + } + Ok(()) + } + + pub fn is_started(&self) -> bool { + self.process.is_some() + } + + pub fn restart_count(&self) -> u8 { + self.restarts + } + + fn begin_session(&mut self) { + self.restarts = 0; + } + + /// Sends one PNG and waits for the matching pose JSON line. + pub fn process_png( + &mut self, + png: &[u8], + cancel: &CancelToken, + ) -> Result { + cancel.check()?; + let length = u32::try_from(png.len()).map_err(|_| { + AssetAiError::Params("sam3dbody input png exceeds 4 GiB".to_string()) + })?; + + loop { + self.ensure_started()?; + let exited = self + .process + .as_mut() + .unwrap() + .child + .try_wait() + .map_err(|error| { + AssetAiError::Backend(format!( + "sam3dbody worker status check failed: {error}" + )) + })?; + if let Some(status) = exited { + self.restart_after_death(&format!("exited with {status}"))?; + continue; + } + if !self.await_ready(cancel)? { + continue; + } + + // KNOWN GAP (P2): this write has no deadline — a worker that + // wedges mid-frame-read can block us in write_all. The lock-step + // protocol (one frame in flight) makes that window small; the + // full fix is a writer thread symmetrical to the reader. + let write_result = { + let process = self.process.as_mut().unwrap(); + let stdin = process.stdin.as_mut().unwrap(); + stdin + .write_all(&length.to_le_bytes()) + .and_then(|_| stdin.write_all(png)) + .and_then(|_| stdin.flush()) + }; + if let Err(error) = write_result { + self.restart_after_death(&format!("stdin write failed: {error}"))?; + continue; + } + + let deadline = Instant::now() + self.timeout; + loop { + if cancel.is_cancelled() { + self.stop_process(); + return Err(AssetAiError::Cancelled); + } + let now = Instant::now(); + if now >= deadline { + self.stop_process(); + return Err(AssetAiError::Backend(format!( + "sam3dbody worker timed out after {:.3} seconds", + self.timeout.as_secs_f64() + ))); + } + let wait = (deadline - now).min(Duration::from_millis(50)); + let event = self.process.as_ref().unwrap().lines.recv_timeout(wait); + match event { + Ok(WorkerRead::Line(line)) => { + validate_pose_packet(&line)?; + return Ok(line); + } + Ok(WorkerRead::Eof) => { + self.restart_after_death("stdout closed")?; + break; + } + Ok(WorkerRead::Error(error)) => { + self.restart_after_death(&format!("stdout read failed: {error}"))?; + break; + } + Err(RecvTimeoutError::Timeout) => {} + Err(RecvTimeoutError::Disconnected) => { + self.restart_after_death("stdout reader stopped")?; + break; + } + } + } + } + } +} + +pub fn validate_pose_packet(line: &str) -> Result<(), AssetAiError> { + let value = makepad_strict_json::parse(line.as_bytes()).map_err(|error| { + AssetAiError::Backend(format!("sam3dbody worker returned invalid json: {error}")) + })?; + if !matches!(&value, Value::Obj(_)) || value.get("n_people").is_none() { + return Err(AssetAiError::Backend( + "sam3dbody worker json is missing top-level n_people".to_string(), + )); + } + Ok(()) +} + +pub struct BodyBackend { + model_id: String, + worker: Option, +} + +impl BodyBackend { + pub fn new(model_id: &str) -> Self { + Self { + model_id: model_id.to_string(), + worker: None, + } + } + + pub fn with_worker(model_id: &str, worker: BodyWorker) -> Self { + Self { + model_id: model_id.to_string(), + worker: Some(worker), + } + } + + fn worker_mut(&mut self) -> Result<&mut BodyWorker, AssetAiError> { + self.worker.as_mut().ok_or_else(|| { + AssetAiError::Backend("sam3dbody backend used before ensure_loaded".to_string()) + }) + } +} + +impl ContentBackend for BodyBackend { + fn model_id(&self) -> &str { + &self.model_id + } + + fn ensure_loaded(&mut self, ctx: &mut BackendCtx) -> Result<(), AssetAiError> { + ctx.ensure_files()?; + ctx.cancel.check()?; + (ctx.progress)("body: worker", 0.5); + match self.worker.as_mut() { + Some(worker) => worker.ensure_started()?, + None => self.worker = Some(BodyWorker::new()?), + } + (ctx.progress)("body: ready", 1.0); + Ok(()) + } + + fn is_resident(&self) -> bool { + self.worker + .as_ref() + .is_some_and(BodyWorker::is_started) + } + + fn unload(&mut self) -> Result<(), AssetAiError> { + self.worker = None; + Ok(()) + } + + fn generate( + &mut self, + params: &GenerateParams, + progress: ProgressSink, + cancel: &CancelToken, + ) -> Result, AssetAiError> { + if params.input_bytes.is_empty() { + return Err(AssetAiError::Params(format!( + "{} needs an input image (input_b64 png)", + self.model_id + ))); + } + if crate::subproc_img::png_header(¶ms.input_bytes).is_none() { + return Err(AssetAiError::Params( + "sam3dbody input_b64 is not a png".to_string(), + )); + } + cancel.check()?; + progress("body: infer", 0.05); + let worker = self.worker_mut()?; + worker.begin_session(); + let pose = worker.process_png(¶ms.input_bytes, cancel)?; + progress("done", 1.0); + Ok(vec![ArtifactData { + content_type: "application/json", + ext: "json", + bytes: pose.into_bytes(), + }]) + } + + fn live_supported(&self) -> bool { + true + } + + fn live_step( + &mut self, + frame: LiveFrameIn<'_>, + cancel: &CancelToken, + ) -> Result { + cancel.check()?; + let start = Instant::now(); + let init = frame.init.ok_or_else(|| { + AssetAiError::Params("sam3dbody live step requires an input frame".to_string()) + })?; + let png = crate::testpattern::encode_png_rgb8( + &init.data, + init.width as usize, + init.height as usize, + )?; + let worker = self.worker_mut()?; + if frame.frame_index == 0 { + worker.begin_session(); + } + let pose = worker.process_png(&png, cancel)?; + cancel.check()?; + Ok(LiveFrameOut { + image: init.clone(), + aux_json: Some(pose), + model_ms: start.elapsed().as_secs_f64() * 1000.0, + text_encode_ms: 0.0, + }) + } +} diff --git a/libs/ai/hub/src/flux2_backend.rs b/libs/ai/hub/src/flux2_backend.rs index 60f85e4ee..561d6d319 100644 --- a/libs/ai/hub/src/flux2_backend.rs +++ b/libs/ai/hub/src/flux2_backend.rs @@ -486,6 +486,7 @@ impl ContentBackend for Flux2Backend { let (rgb, width, height) = crate::testpattern::decode_png_rgb8(&result.png)?; Ok(LiveFrameOut { image: RgbImage { width, height, data: rgb }, + aux_json: None, model_ms: start.elapsed().as_secs_f64() * 1000.0, text_encode_ms: if embeds_cached { 0.0 } else { result.te_ms }, }) diff --git a/libs/ai/hub/src/lib.rs b/libs/ai/hub/src/lib.rs index 1656bb8dc..03f4a0ce6 100644 --- a/libs/ai/hub/src/lib.rs +++ b/libs/ai/hub/src/lib.rs @@ -32,6 +32,7 @@ //! see `protocol.rs`'s wire doc block and `crate::realtime`. pub mod backend; +pub mod body_backend; pub mod chat_wire; pub use makepad_base64; pub mod client; diff --git a/libs/ai/hub/src/protocol.rs b/libs/ai/hub/src/protocol.rs index 9236e1a73..363a23b56 100644 --- a/libs/ai/hub/src/protocol.rs +++ b/libs/ai/hub/src/protocol.rs @@ -808,8 +808,9 @@ pub struct LiveStatusJson { // increments (see the `stats` message). // Server -> client: an output frame; `kind` follows the session's // `output_encoding` (`{"type":"control","output_encoding":"png"}` switches -// it; default is "h264" when the service was built with the `video` cargo -// feature, "raw" otherwise — see `RealtimeRequestJson::output_encoding`). +// it; `"none"` sends no output frames while JSON messages continue; default +// is "h264" when the service was built with the `video` cargo feature, +// "raw" otherwise - see `RealtimeRequestJson::output_encoding`). // `frame_index` is the session's output counter. When a NEW socket // connects to an H.264-output session, the encoder is asked for a fresh // keyframe (SPS/PPS + IDR) so the new client can start decoding @@ -846,6 +847,9 @@ pub struct LiveStatusJson { // above 0.75 the init is never encoded and every frame is a fresh edit. // // JSON messages, server -> client: +// {"type":"aux", "frame_index":N, "data":} +// (when a backend produces structured per-frame data; sent before that +// frame, and still sent when output_encoding is "none") // {"type":"stats", "frame_index":N, "fps":.., "frame_ms":.., // "stage_ms":{"prep":..,"model":..,"text_encode":..,"post":..}, // "frames_in":.., "frames_out":.., "dropped":.., @@ -891,7 +895,9 @@ pub struct RealtimeRequestJson { /// "feed" (default): wait for client-pushed input frames. "feedback": /// the session's own previous output (camera-warped) is the next init. pub loop_mode: Option, - /// "raw" | "png" | "h264" — output frame payload format. Default: + /// "none" | "raw" | "png" | "h264" - output frame payload format. + /// "none" suppresses output frames while stats/aux/error/stopped continue + /// and is refused with `loop_mode = "feedback"`. Default: /// "h264" when this service was built with the `video` cargo feature /// (`makepad-video`'s hardware H.264 codec), "raw" otherwise. Requesting /// "h264" on a build without that feature is refused (400). diff --git a/libs/ai/hub/src/realtime.rs b/libs/ai/hub/src/realtime.rs index 71e485a6a..35799851b 100644 --- a/libs/ai/hub/src/realtime.rs +++ b/libs/ai/hub/src/realtime.rs @@ -269,8 +269,30 @@ impl RealtimeSession { /// Merges a partial `{"type":"control", ...}` update: only the fields /// present in `update` change anything (see [`apply_control_to_config`] /// for the `LiveConfig` subset; the session-only knobs are merged here). - pub fn apply_control(&self, update: &realtime_wire::ControlUpdateJson) { + pub fn apply_control( + &self, + update: &realtime_wire::ControlUpdateJson, + ) -> Result<(), AssetAiError> { let mut state = self.state.lock().unwrap(); + let next_loop_mode = update + .loop_mode + .as_deref() + .and_then(|text| LoopMode::parse(text).ok()) + .unwrap_or(state.loop_mode); + let next_output_encoding = update + .output_encoding + .as_deref() + .and_then(|text| OutputEncoding::parse(text).ok()) + .filter(OutputEncoding::is_supported_in_this_build) + .unwrap_or(state.output_encoding); + if next_loop_mode == LoopMode::Feedback + && next_output_encoding == OutputEncoding::None + { + return Err(AssetAiError::Params( + "realtime: loop_mode \"feedback\" requires output frames; output_encoding \"none\" is not allowed" + .to_string(), + )); + } apply_control_to_config(&mut state.config, update); if let Some(mode) = update .loop_mode @@ -314,6 +336,7 @@ impl RealtimeSession { if update.reset == Some(true) { self.reset_requested.store(true, Ordering::Relaxed); } + Ok(()) } /// `{"type":"reference", "slot":N, ...}`: grows `references` with black @@ -396,7 +419,7 @@ impl RealtimeSession { /// Handles one client -> server text message: control / reference / stop. pub fn handle_text(&self, text: &str) -> Result<(), AssetAiError> { match realtime_wire::parse_client_message(text)? { - ClientMessage::Control(update) => self.apply_control(&update), + ClientMessage::Control(update) => self.apply_control(&update)?, ClientMessage::Reference(reference) => { let slot = reference.slot.unwrap_or(0) as usize; let png_b64 = reference.png_b64.as_deref().unwrap_or(""); @@ -422,6 +445,7 @@ impl RealtimeSession { fn encode_output(&self, image: &RgbImage, frame_index: u32) -> Vec> { let output_encoding = self.state.lock().unwrap().output_encoding; match output_encoding { + OutputEncoding::None => Vec::new(), OutputEncoding::Raw | OutputEncoding::Png => { vec![encode_output_frame(image, output_encoding, frame_index)] } @@ -572,8 +596,8 @@ fn encode_output_frame(image: &RgbImage, encoding: OutputEncoding, frame_index: } } } - OutputEncoding::H264 => { - eprintln!("realtime: encode_output_frame called with H264 (should route through encode_output) — using raw"); + OutputEncoding::H264 | OutputEncoding::None => { + eprintln!("realtime: encode_output_frame called with non-frame encoding (should route through encode_output) - using raw"); (FrameKind::Raw, image.data.clone()) } }; @@ -1298,6 +1322,9 @@ pub fn run_live( } }; + if let Some(aux_json) = out.aux_json.as_deref() { + session.push_bytes(realtime_wire::encode_aux_message(frame_index, aux_json)); + } { let mut slot = outbound.lock().unwrap(); if slot.replace((frame_index, out.image.clone())).is_some() { @@ -1640,6 +1667,33 @@ mod tests { assert_eq!(params.config.noise_mode.resolve(LoopMode::Feed), NoiseMode::Reroll); } + #[test] + fn output_encoding_none_is_feed_only() { + use crate::protocol::RealtimeRequestJson; + + let feed = RealtimeRequestJson { + model: "testpattern".to_string(), + loop_mode: Some("feed".to_string()), + output_encoding: Some("none".to_string()), + ..Default::default() + }; + let params = LiveParams::from_request(&feed).unwrap(); + assert_eq!(params.output_encoding, OutputEncoding::None); + + let feedback = RealtimeRequestJson { + model: "testpattern".to_string(), + loop_mode: Some("feedback".to_string()), + output_encoding: Some("none".to_string()), + ..Default::default() + }; + let error = LiveParams::from_request(&feedback) + .err() + .expect("feedback with no output must be refused"); + assert!(matches!(error, AssetAiError::Params(_))); + assert!(error.to_string().contains("feedback")); + assert!(error.to_string().contains("output_encoding \"none\"")); + } + #[test] fn strength_is_a_five_position_switch_at_four_steps() { use crate::backend::img2img_start_step; @@ -1939,7 +1993,12 @@ mod tests { // A frame that changes every step, so frame_diff is non-zero. let tint = (frame.frame_index * 40 % 256) as u8; let image = solid_image(frame.config.width, frame.config.height, [tint, 20, 30]); - Ok(crate::backend::LiveFrameOut { image, model_ms: 0.1, text_encode_ms: 0.0 }) + Ok(crate::backend::LiveFrameOut { + image, + aux_json: None, + model_ms: 0.1, + text_encode_ms: 0.0, + }) } } @@ -2186,7 +2245,7 @@ mod tests { prompt: Some("hi".to_string()), ..Default::default() }; - session.apply_control(&update); + session.apply_control(&update).unwrap(); let (config, loop_mode, output_encoding, max_fps) = session.snapshot(); assert_eq!(loop_mode, LoopMode::Feedback); assert_eq!(output_encoding, OutputEncoding::Png); @@ -2194,6 +2253,32 @@ mod tests { assert_eq!(config.prompt, "hi"); } + #[test] + fn none_control_sends_no_frame_and_refuses_feedback() { + let params = LiveParams { + model: "testpattern".to_string(), + config: LiveConfig::default(), + loop_mode: LoopMode::Feed, + input_encoding: OutputEncoding::Raw, + output_encoding: OutputEncoding::None, + max_fps: 0.0, + idle_timeout_s: 30, + }; + let session = RealtimeSession::new("job-none".to_string(), ¶ms); + assert!(session.encode_output(&RgbImage::blank(16, 16), 0).is_empty()); + + let update = ControlUpdateJson { + kind: "control".to_string(), + loop_mode: Some("feedback".to_string()), + ..Default::default() + }; + let error = session.apply_control(&update).unwrap_err(); + assert!(matches!(error, AssetAiError::Params(_))); + let (_, loop_mode, output_encoding, _) = session.snapshot(); + assert_eq!(loop_mode, LoopMode::Feed); + assert_eq!(output_encoding, OutputEncoding::None); + } + /// The server-loop handshake: open in feed, push the source once, flip /// to feedback after the first output. The worker used to park on the /// mailbox inside the feed branch and never re-read the mode — one frame diff --git a/libs/ai/hub/src/realtime_wire.rs b/libs/ai/hub/src/realtime_wire.rs index 85238bd64..1da9c5fbb 100644 --- a/libs/ai/hub/src/realtime_wire.rs +++ b/libs/ai/hub/src/realtime_wire.rs @@ -310,6 +310,16 @@ pub fn encode_stats_message(mut stats: StatsMessageJson) -> String { stats.serialize_json() } +/// Wraps an already-validated backend JSON value without parsing or +/// re-serializing it. Server pushes are websocket Binary payloads, so the +/// returned bytes intentionally have no FRFL frame header. +pub fn encode_aux_message(frame_index: u64, data_json: &str) -> Vec { + format!( + "{{\"type\":\"aux\",\"frame_index\":{frame_index},\"data\":{data_json}}}" + ) + .into_bytes() +} + #[derive(Clone, Debug, Default, SerJson, DeJson)] struct ErrorMessageJson { #[rename(type)] @@ -423,6 +433,17 @@ mod tests { assert!(!is_frame_message(json.as_bytes())); } + #[test] + fn aux_message_embeds_raw_json_without_a_frame_header() { + let data = r#"{"n_people":1,"opaque":[1, 2]}"#; + let bytes = encode_aux_message(17, data); + assert_eq!( + bytes, + br#"{"type":"aux","frame_index":17,"data":{"n_people":1,"opaque":[1, 2]}}"# + ); + assert!(!is_frame_message(&bytes)); + } + #[test] fn parse_client_message_control_partial_fields() { let msg = parse_client_message(r#"{"type":"control","prompt":"a cat","steps":8}"#).unwrap(); diff --git a/libs/ai/hub/src/registry.rs b/libs/ai/hub/src/registry.rs index 3a0eab083..18ae62cf1 100644 --- a/libs/ai/hub/src/registry.rs +++ b/libs/ai/hub/src/registry.rs @@ -139,6 +139,8 @@ pub enum Domain { Matte, /// Image -> metric depthmap (Depth-Anything-3). Depth, + /// Image/frame -> structured human body pose packet (SAM 3D Body). + Body, /// Image + text prompt -> instance mask PNG + RGBA cutout (SAM 3.1). Segment, /// Mesh GLB -> skinned/rigged GLB (SkinTokens). @@ -207,6 +209,7 @@ impl Domain { "world" => Some(Domain::World), "matte" => Some(Domain::Matte), "depth" => Some(Domain::Depth), + "body" => Some(Domain::Body), "segment" => Some(Domain::Segment), "rig" => Some(Domain::Rig), "motion" => Some(Domain::Motion), @@ -235,6 +238,7 @@ impl Domain { Domain::World => "world", Domain::Matte => "matte", Domain::Depth => "depth", + Domain::Body => "body", Domain::Segment => "segment", Domain::Rig => "rig", Domain::Motion => "motion", @@ -447,7 +451,7 @@ impl Registry { for model in wire.models { let domain = Domain::parse(&model.domain).ok_or_else(|| { AssetAiError::Registry(format!( - "model {}: unknown domain {:?} (expected image|mesh|video|audio|text|speech|world|matte|depth|segment|rig|motion)", + "model {}: unknown domain {:?} (expected image|mesh|video|audio|text|speech|world|matte|depth|body|segment|rig|motion)", model.id, model.domain )) })?; @@ -1488,6 +1492,15 @@ mod tests { // The licensing guard lives in the note: the x.1 refreshes are NC. assert!(depth.note.as_deref().unwrap().contains("Apache-2.0")); + // Body domain: externally provisioned persistent worker, no hub-side + // model artifact download. + let body = registry.find("sam3dbody-ref").unwrap(); + assert_eq!(body.domain, Domain::Body); + assert_eq!(body.backend, "body"); + assert!(body.available); + assert_eq!(body.vram_gb, Some(4.0)); + assert!(body.files.is_empty()); + // Segment domain: pinned Comfy-Org SAM 3.1 multiplex CUDA artifact. let segment = registry.find("sam3-1-multiplex").unwrap(); assert_eq!(segment.domain, Domain::Segment); diff --git a/libs/ai/hub/src/testpattern.rs b/libs/ai/hub/src/testpattern.rs index 1a4d7ccb9..c9fe06fda 100644 --- a/libs/ai/hub/src/testpattern.rs +++ b/libs/ai/hub/src/testpattern.rs @@ -109,6 +109,7 @@ impl ContentBackend for TestPatternBackend { cancel.check()?; Ok(LiveFrameOut { image: RgbImage { width, height, data: out_data }, + aux_json: None, model_ms: start.elapsed().as_secs_f64() * 1000.0, text_encode_ms: 0.0, }) diff --git a/libs/ai/hub/tests/body_worker.rs b/libs/ai/hub/tests/body_worker.rs new file mode 100644 index 000000000..b2a628059 --- /dev/null +++ b/libs/ai/hub/tests/body_worker.rs @@ -0,0 +1,219 @@ +use makepad_ai_hub::backend::{ + CancelToken, ContentBackend, GenerateParams, LiveConfig, LiveFrameIn, RgbImage, +}; +use makepad_ai_hub::body_backend::{ + BodyBackend, BodyWorker, BODY_TIMEOUT_ENV, BODY_WORKER_ENV, +}; +use makepad_ai_hub::protocol::GenerateRequestJson; +use makepad_ai_hub::testpattern::encode_png_rgb8; +use std::io::{Read, Write}; +use std::path::{Path, PathBuf}; +use std::time::{Duration, Instant}; + +const FAKE_FLAG: &str = "MAKEPAD_SAM3DBODY_FAKE_WORKER"; +const FAKE_MODE: &str = "MAKEPAD_SAM3DBODY_FAKE_MODE"; +const FAKE_MARKER: &str = "MAKEPAD_SAM3DBODY_FAKE_MARKER"; +const PACKET: &str = r#"{"n_people":1,"people":[],"opaque":{"keep":[1, 2]}}"#; + +fn main() { + if std::env::var(FAKE_FLAG).ok().as_deref() == Some("1") { + fake_worker_main(); + return; + } + + worker_round_trip_keeps_child_alive(); + worker_restarts_after_child_death(); + worker_stops_after_three_restarts(); + worker_timeout_is_bounded(); + backend_live_step_echoes_frame_and_pose_aux(); + backend_generate_returns_json_artifact(); + unset_worker_command_is_clear(); + println!("body_worker: 7 passed"); +} + +fn fake_worker_main() { + let mode = std::env::var(FAKE_MODE).unwrap_or_else(|_| "normal".to_string()); + if mode == "die" { + return; + } + if mode == "die_once" { + let marker = PathBuf::from(std::env::var(FAKE_MARKER).expect("fake marker")); + if !marker.exists() { + std::fs::write(marker, b"died").expect("write fake marker"); + return; + } + } + + let mut stdin = std::io::stdin().lock(); + let mut stdout = std::io::stdout().lock(); + writeln!(stdout, "{{\"ready\":true}}").expect("fake worker ready"); + stdout.flush().expect("fake worker ready flush"); + loop { + let mut length = [0u8; 4]; + match stdin.read_exact(&mut length) { + Ok(()) => {} + Err(error) if error.kind() == std::io::ErrorKind::UnexpectedEof => return, + Err(error) => panic!("fake worker length read: {error}"), + } + let length = u32::from_le_bytes(length) as usize; + let mut png = vec![0u8; length]; + stdin.read_exact(&mut png).expect("fake worker png read"); + assert!(png.starts_with(b"\x89PNG\r\n\x1a\n")); + if mode == "timeout" { + std::thread::sleep(Duration::from_secs(2)); + } + writeln!(stdout, "{PACKET}").expect("fake worker response"); + stdout.flush().expect("fake worker flush"); + } +} + +struct FakeEnv { + marker: Option, +} + +impl FakeEnv { + fn set(mode: &str, timeout_s: &str, marker: Option<&Path>) -> Self { + let executable = std::env::current_exe().expect("current test executable"); + let command = executable + .to_str() + .expect("test executable path is utf-8") + .to_string(); + assert!(!command.contains(char::is_whitespace)); + std::env::set_var(BODY_WORKER_ENV, command); + std::env::set_var(BODY_TIMEOUT_ENV, timeout_s); + std::env::set_var(FAKE_FLAG, "1"); + std::env::set_var(FAKE_MODE, mode); + if let Some(marker) = marker { + std::env::set_var(FAKE_MARKER, marker); + } else { + std::env::remove_var(FAKE_MARKER); + } + Self { + marker: marker.map(Path::to_path_buf), + } + } +} + +impl Drop for FakeEnv { + fn drop(&mut self) { + std::env::remove_var(BODY_WORKER_ENV); + std::env::remove_var(BODY_TIMEOUT_ENV); + std::env::remove_var(FAKE_FLAG); + std::env::remove_var(FAKE_MODE); + std::env::remove_var(FAKE_MARKER); + if let Some(marker) = self.marker.as_ref() { + let _ = std::fs::remove_file(marker); + } + } +} + +fn test_png() -> Vec { + encode_png_rgb8(&[10, 20, 30, 40, 50, 60], 2, 1).unwrap() +} + +fn worker_round_trip_keeps_child_alive() { + let _env = FakeEnv::set("normal", "1", None); + let mut worker = BodyWorker::new().unwrap(); + let cancel = CancelToken::new(); + assert_eq!(worker.process_png(&test_png(), &cancel).unwrap(), PACKET); + assert_eq!(worker.process_png(&test_png(), &cancel).unwrap(), PACKET); + assert_eq!(worker.restart_count(), 0); +} + +fn worker_restarts_after_child_death() { + let marker = std::env::current_dir() + .unwrap() + .join("target") + .join(format!("body-worker-die-once-{}", std::process::id())); + std::fs::create_dir_all(marker.parent().unwrap()).unwrap(); + let _ = std::fs::remove_file(&marker); + let _env = FakeEnv::set("die_once", "1", Some(&marker)); + let mut worker = BodyWorker::new().unwrap(); + let pose = worker + .process_png(&test_png(), &CancelToken::new()) + .unwrap(); + assert_eq!(pose, PACKET); + assert_eq!(worker.restart_count(), 1); +} + +fn worker_timeout_is_bounded() { + let _env = FakeEnv::set("timeout", "0.05", None); + let mut worker = BodyWorker::new().unwrap(); + let start = Instant::now(); + let error = worker + .process_png(&test_png(), &CancelToken::new()) + .unwrap_err(); + assert!(error.to_string().contains("timed out"), "{error}"); + assert!(start.elapsed() < Duration::from_secs(1)); + assert!(!worker.is_started()); +} + +fn worker_stops_after_three_restarts() { + let _env = FakeEnv::set("die", "1", None); + let mut worker = BodyWorker::new().unwrap(); + let error = worker + .process_png(&test_png(), &CancelToken::new()) + .unwrap_err(); + assert!(error.to_string().contains("after 3 restarts"), "{error}"); + assert_eq!(worker.restart_count(), 3); +} + +fn backend_live_step_echoes_frame_and_pose_aux() { + let _env = FakeEnv::set("normal", "1", None); + let worker = BodyWorker::new().unwrap(); + let mut backend = BodyBackend::with_worker("sam3dbody-ref", worker); + let image = RgbImage { + width: 2, + height: 1, + data: vec![10, 20, 30, 40, 50, 60], + }; + let config = LiveConfig::default(); + let out = backend + .live_step( + LiveFrameIn { + init: Some(&image), + anchor: None, + frame_index: 9, + config: &config, + }, + &CancelToken::new(), + ) + .unwrap(); + assert_eq!(out.image, image); + assert_eq!(out.aux_json.as_deref(), Some(PACKET)); + assert_eq!(out.text_encode_ms, 0.0); +} + +fn backend_generate_returns_json_artifact() { + let _env = FakeEnv::set("normal", "1", None); + let worker = BodyWorker::new().unwrap(); + let mut backend = BodyBackend::with_worker("sam3dbody-ref", worker); + let input_b64 = String::from_utf8(makepad_ai_hub::makepad_base64::base64_encode( + &test_png(), + &makepad_ai_hub::makepad_base64::BASE64_STANDARD, + )) + .unwrap(); + let params = GenerateParams::from_request(&GenerateRequestJson { + model: "sam3dbody-ref".to_string(), + input_b64: Some(input_b64), + ..Default::default() + }) + .unwrap(); + let mut progress = |_: &str, _: f64| {}; + let artifacts = backend + .generate(¶ms, &mut progress, &CancelToken::new()) + .unwrap(); + assert_eq!(artifacts.len(), 1); + assert_eq!(artifacts[0].content_type, "application/json"); + assert_eq!(artifacts[0].ext, "json"); + assert_eq!(artifacts[0].bytes, PACKET.as_bytes()); +} + +fn unset_worker_command_is_clear() { + std::env::remove_var(BODY_WORKER_ENV); + std::env::remove_var(BODY_TIMEOUT_ENV); + let error = BodyWorker::new() + .err() + .expect("an unset worker command must be refused"); + assert!(error.to_string().contains(BODY_WORKER_ENV), "{error}"); +} From 237da90a36f68faafc3478427ba38cd3ec1c00f1 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 19:54:29 +0200 Subject: [PATCH 003/417] render: the sprite lane hands the screen draw back the way it found it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One DrawSceneScreen serves both the in-world video screen and every sprite billboard, and the sprite loop left its last pose, size and atlas behind — so the next frame's "is there a screen" gate (zero screen_size draws nothing) read the leftover and drew the whole spritemap as one opaque quad: under the last-drawn unit in C&C, and hanging in the sky of any level that draws no sprites at all. Snapshot the host's pos/size/ texture before the lane and restore after. Co-Authored-By: Claude Fable 5 --- libs/render/src/renderer.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/libs/render/src/renderer.rs b/libs/render/src/renderer.rs index 76a03e4a1..7832687ab 100644 --- a/libs/render/src/renderer.rs +++ b/libs/render/src/renderer.rs @@ -8044,6 +8044,19 @@ impl Renderer { if let Some(sc) = draws.screen.as_deref_mut() { let geometry_id = self.ensure_flare_geometry(cx.cx); sc.draw_vars.geometry_id = Some(geometry_id); + // The sprite lane below BORROWS this draw — one shader serves both + // the video screen and every billboard — so it overwrites the pose + // and texture the host owns. Remember them here and hand them back + // when the lane is done: otherwise the last sprite of the frame + // leaves its pose behind, next frame the "is there a screen?" test + // (a zero `screen_size` draws nothing) reads THAT and passes, and + // the sprite's whole sheet is drawn as one opaque quad with full + // 0..1 UVs — an atlas standing in the world under the unit that + // happened to be drawn last, and still standing there after the + // level that owned it is gone. + let host_pos = sc.screen_pos; + let host_size = sc.screen_size; + let host_texture = sc.draw_vars.texture_slots[0].clone(); sc.depth_clip = 1.0; sc.cutout = 0.0; sc.pixelated = 0.0; @@ -8082,6 +8095,10 @@ impl Renderer { sc.draw_vars.area = cx.update_area_refs(sc.draw_vars.area, new_area); } } + // The borrow ends here: the host's screen is exactly as it left it. + sc.screen_pos = host_pos; + sc.screen_size = host_size; + sc.draw_vars.texture_slots[0] = host_texture; } // 7. View-local held meshes, after the complete world. The dedicated From 0d7185e0de6902ee2dc85a99795c05f216551f6d Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 20:18:31 +0200 Subject: [PATCH 004/417] asset chat: catalog SQL answers in-process, and the game brief stops teaching the y mistake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Post-P8 the game session still advertised assets.query/assets.schema but the in-process executor answered both Unavailable — the model's main alias-search tool was dead, and every "find me X" turn gave up on the store. Both now execute over the server's bounded /v1/assets/query route (schema via sqlite_master plus the usage notes). The game brief gains the new-game-vs-edit rule, interior design law, generate-after-search, and explicit y semantics so player_pos().y stops being pasted into ground-relative fields. Co-Authored-By: Claude Fable 5 --- libs/asset/chat/context/game.md | 251 ++++++++++++---------- libs/asset/chat/src/dispatch.rs | 101 ++++++++- libs/asset/chat/src/tools.rs | 8 +- libs/asset/store/src/host/assets_query.rs | 2 +- 4 files changed, 237 insertions(+), 125 deletions(-) diff --git a/libs/asset/chat/context/game.md b/libs/asset/chat/context/game.md index 27788a9c4..f09e23502 100644 --- a/libs/asset/chat/context/game.md +++ b/libs/asset/chat/context/game.md @@ -27,25 +27,60 @@ EDITING A LIVE WORLD below): 4. To ADD one thing later, world.spawn (see EDITING A LIVE WORLD); world.place / world.move / world.remove handle individual scenery placements without rewriting the source. +NEW GAME vs EDIT: this chat belongs to ONE game. "make me a new level / +a new world / another map to switch to" = world.new_level with a title +and a COMPLETE source — the game publishes it as a NEW game and switches +the player there; that new game has its own chat, so this conversation +ends on the tool's answer (report the new game's title and stop). +world.set_source edits the CURRENT game in place and is never a switch. Model bytes stream from the asset server automatically once the source references an alias — you never fetch anything yourself. +SUB-WORLD INTERIORS: one game asset carries `game.splash` (`sub: "main"`) +plus named `interiors/.splash` sources. A generated entrance is +`game.door(pos_or_entity, {door: "stable-id", generate: "the room brief"})`; +on a building, bind its model handle — `let shop = game.model(...)` then +`game.door(shop, {...})` — so the prompt zone hugs the building's own box; +the matching interior source declares +`game.door(pos, {door: "stable-id", label: "Outside", back: true})`. +INTERIOR DESIGN LAW: an interior is an OPEN STAGE, not a box you sit inside. +Its shell: true walls are invisible containment (drawn never, solid always) +and it has NO ceiling — never author visible wall or ceiling boxes in an +interior; make the space read through the floor, furnishings, lamps/glow and +the game.sky backdrop, so both first and third person feel open. +The file's existence IS the link. First open adds that interior file to the +parent game's next revision; it never creates another game or a source +marker. An explicit `to: ""` still crosses to that +other game's `main` world. World tools accept optional `sub`; source tools +default to this conversation's bound sub, while placement/live tools default +to the player's current sub. Read the per-turn WORLD MANIFEST and presence +line before editing, and check each result's `asset`, `sub`, and `file`. + +GENERATING MISSING ART: SEARCH FIRST with asset.search or assets.query. +Use content.generate ONLY when the library has no suitable result, choosing +character, prop, or sound and giving it a concrete production prompt (plus +dim_height in metres when scale matters). Generation takes minutes and this +turn does not wait for it. Tell the player it is generating and will appear +in the library when finished; never claim it is ready or reference a future +alias in the live world yet. The player can see and cancel every costly job +in the status area below chat. You may still build a primitive stand-in now. + DRIVEABLE CARS: `game.car({pos, model: "kenney/car-kit/", color})` makes a real driveable vehicle — the engine owns the driving physics and the player walks up and presses interact to get in. Never build a car from boxes; never make it a plain game.model (that is scenery). +A "small car" = `world.spawn({model: "...", scale: 0.5})` or `scale: "small"` +— it stays driveable; `world.place` makes static scenery. -CITIES, VILLAGES, RACETRACKS, ROADS, FORESTS AND DUNGEONS ARE ONE CALL — -never place tiles or a dozen trees one by one. All are deterministic from -seed (reroll = change the seed) and come out at the right world scale: -- game.city({seed: 5, size: 90, density: 0.8}) — streets, blocks and - COMPLETE buildings facing them with sane spacing. THE way to do "build - me a town/city". (game.town is the same verb's old name.) -- game.village({seed: 5, size: 60}) — one main cobbled street with lanes, - low density. Add the villagers, fountain and trees yourself. -- game.racetrack({seed: 7, size: 120, complexity: 8}) — a COMPLETE - circuit: track tiles, a staggered starting grid, checkpoints in lap - order, rival waypoints. THE race pattern: +CITIES, VILLAGES, RACETRACKS, ROADS, FORESTS AND DUNGEONS ARE ONE CALL; +never hand-place their tiles. They are deterministic from seed: +- `game.city({seed, size, density})`, `game.village({seed, size})`, and + `game.dungeon({kit, extent, seed})` build complete layouts. +- `game.scatter({models, pos, size, spacing, count, seed})` builds forests + or crowds while avoiding earlier roads/buildings. +- `game.road_network({kit, paths})` joins and scales custom road paths. +- `game.racetrack({seed, size, complexity})` returns slots, checkpoints, + start and waypoints. A race's essential shape is: let t = game.racetrack({seed: 7}) let car = game.car({model: "kenney/car-kit/race", color: #ff4444}) game.place(car, t.slots[0]) @@ -54,24 +89,8 @@ seed (reroll = change the seed) and come out at the right world scale: game.autodrive(r, {points: t.waypoints, pace: 0.85}) game.race({laps: 3}) game.player_character({pos: t.start, model: "kenney/mini-characters/character-male-b"}) - EVERY car gets its OWN slot from t.slots — two cars on one spawnpoint - explode at the green flag. THE PLAYER SPAWNS AT t.start (beside their - car) — a player at the terrain centre cannot reach the grid. - game.standings() feeds a HUD. -- game.scatter({models: ["kenney/nature-kit/tree_default", - "kenney/nature-kit/tree_oak"], pos: vec3(0,0,0), size: 40, spacing: 4, - count: 30, seed: 3}) — forests, rocks, crowds of props with natural - spacing that automatically stays OFF roads and buildings placed before - it (so call it after game.city). -- game.road_network({kit: "kenney/city-kit-roads", paths: [[vec3(-20,0,0), - vec3(20,0,0)], [vec3(0,0,-20), vec3(0,0,20)]]}) — custom road shapes in - metres; corners and junctions come out automatically where paths bend - and meet; paths snap to the road grid. -- game.dungeon({kit: "kenney/modular-dungeon-kit", extent: 24, seed: 5}) — - a connected interior; returns {entrance, exit} to spawn the player at. -Use these first, then add landmarks, cars, characters and game logic -around them. Hand-place single game.model calls only for accents (a -fountain, a statue), never for a road or a forest. +Every car gets a different `t.slots` entry; spawn the player at `t.start`. +Use these first, then hand-place only accents and game logic. ALWAYS BUILD SOMETHING. The primitives (terrain, water, box, mover, character, labels, colors) need NO store content — when a query finds no @@ -81,69 +100,27 @@ artwork never blocks a level. Into a RUNNING world, build the substitute as ONE world.add_addon chunk (primitive boxes and movers welcome) — never replace the user's level to conjure one thing. -Only kind 'mesh' (and rigged 'character') assets place with game.model. -Catalog 'world' maps load with game.map — a WHOLE playable level in one -call: game.map("doom/doom/worlds/doom1/e1m1") streams the map, builds -real walking collision (walls, stairs), opens its doors on approach and -spawns the player at its player start. Query kind='world' for aliases. -A map level needs NO terrain and NO sky of its own — the map carries -them. The whole level is four lines (ARM THE PLAYER, below, is why it is -four and never three): - game.map("doom/doom/worlds/doom1/e1m1") - let hero = game.player_character({view: "first"}) - game.gun(hero, {view_model: "", rate: 2, damage: 25}) - game.text("hint", "WASD to move, click to shoot", {anchor: "top_left"}) -game.map also takes {actors: "/"} to place the map's actor -sprites from a billboard pack of the SAME game family (its own pack is -the default). Cross-family mixes ("duke characters in doom") are not -mapped yet — unknown actor keys skip silently, so say honestly that the -map will load but those actors won't appear, and offer the map with its -own actors instead. -A MAP BRINGS ITS OWN CAST — loading it IS loading the monsters. The map's -data declares every thing in the level, and the engine gives the ones -declared as characters real bodies: they hunt the player through the -level's corridors, take gunfire, flinch and die, and bite back. You never -spawn them, place them, tag them or write their AI. Never substitute -game.box/game.mover stand-ins for a level's inhabitants, and never -hand-place them at coordinates you invented — that replaces a real cast -with a fake one. -ARM THE PLAYER — a COMPLETION RULE, not a flourish. A level that loads a -map with a cast, or that puts the player in `view: "first"`, is NOT DONE -until `game.gun` has been called on that player. Nothing about the -request has to mention shooting: an unarmed player in a level full of -things that bite is a game you cannot play, and the four-line recipe -above is the finished shape. Check your own script before you answer — if -it has `game.map` or `view: "first"` and no `game.gun` line, it is -unfinished, so add it and re-check. -`game.gun(hero, {rate, damage})` gives the player a working gun and the -mouse fires it. The first-person weapon may be a SPRITE — classic packs -publish the held weapon as billboard artwork. -A pack holds BOTH the gun lying on the floor -and the gun in your hands, and their names give you no way to tell them -apart, so never guess from the alias: the artwork carries a LABEL, and -only the held one is labelled `weapon` (the floor pickup is `item`, a -monster is `character`). One query gets it: +Only 'mesh' and rigged 'character' assets place with game.model. A 'world' +alias loads through game.map as a whole level with collision, doors, +player start and its declared cast. It needs no separate terrain/sky and +you never hand-spawn or replace its monsters. `actors:` may select only a +billboard pack from the same game family; cross-family actor keys do not map. + +ARM THE PLAYER: any map with a cast, or any `view: "first"` player, is not +complete without `game.gun`. Classic packs contain both floor pickups and +held sprites, so query the label `weapon` rather than guessing an alias: SELECT a.canon_alias FROM search_annotations a JOIN search_labels l ON l.asset_id = a.asset_id WHERE a.live=1 AND a.kind='billboard' AND l.label='weapon' AND a.canon_alias LIKE '/%' LIMIT 20 -Name that in `view_model`; without one the engine draws a stock model — -so run the query and pass a real held-weapon alias from the map's own -pack, never a floor-pickup alias and never a guess. -That makes a whole first-person shooter four lines: +Then a complete first-person map is four lines: game.map("") let hero = game.player_character({view: "first"}) game.gun(hero, {view_model: "", rate: 2, damage: 25}) game.text("hint", "WASD to move, click to shoot", {anchor: "top_left"}) -SAY ONLY WHAT THE GAME HAS. The hint text and your reply describe the -script you actually wrote: never promise shooting from a level with no -`game.gun`, monsters from a map you did not load, or a weapon you could -not find. Write the missing verb instead of the promise — and if -something truly is not there, say that plainly. -'billboard' assets are otherwise queryable-only — they are the map's and -the gun's artwork, not props: say so honestly if asked to place one. -First person vs third person is the player line's `view:` option — a -mode switch is a one-line edit of that option, nothing else changes. +Never promise a feature absent from the script. Billboard assets are map/ +weapon artwork, not placeable props. First/third person is the player's +`view:` option and changes with a one-line edit. SPLASH SYNTAX (it is NOT JavaScript — these exact forms only): - Loops: `for i in 0..16 { }` and `for item in list { }`. There is NO @@ -165,8 +142,9 @@ SPLASH RULES (each one breaks the game if ignored): - Budget: stay well under ~400 entities; prefer one terrain over box fields; a level is usually 30-120 lines. - Store models place with `game.model("", {pos, yaw, scale, - collide, tag})` — yaw is RADIANS. Never guess an alias; query first. + tint, hue, collide, tag})` — yaw is RADIANS. Never guess an alias; query first. `yaw` also orients cars, characters and movers. +- Any spawned/placed asset takes `tint: #rrggbb` and `hue: degrees` — ten differently-colored copies of one asset need no rebuilds (`world.spawn` spells tint as `color: "#rrggbb"`). - `game.find_model("query", {count}) -> [ids]` searches the installed library at runtime and returns DISTINCT model ids (useful for variety), but exact aliases from your catalog query are better. @@ -178,46 +156,85 @@ game.terrain({size: 160, cells: 65, smooth: true, seed: 3, amp: 8, color: #x3a7d height h; omit it for dry land. Hilly ground: put objects at y ≈ amp, or use amp: 0 where exact placement matters. game.water({min, max, color}) — a wave volume (only when you want water) -game.character({pos, color, player: true, view: "third"}) -> id -game.player_character({pos, model, speed, jump}) -> id — walker + camera -game.model("alias", {pos, yaw, scale, collide, tag}) +game.character({pos, model, tint, hue, scale, player: true, view: "third"}) -> id +game.player_character({pos, model, tint, hue, scale, speed, jump}) -> id — walker + camera +game.model("alias", {pos, yaw, scale, tint, hue, collide, tag}) game.box({pos, size, color, tag}) / game.mover({pos, size, color, tag}) -> id -game.car({pos, color, model, player}) -> id · game.plane({...}) · game.boat({...}) -game.wander(id, {home, range, speed}) · game.chase(id, {tag, range, speed}) -game.patrol(id, {points, speed}) · game.monster(id, {targets, damage, speed}) +game.part(owner, {pos, size, color, shape, rot_x, rot_y, rot_z}) -> part +game.part_swing(part, {axis: "x", degrees: 25, hz: 2}) — engine gait + (`game.part` attaches once in owner-local space; `move_part` is only for + an explicit pose change, and `game.attach`/`detach` are for entity riders) +game.car({pos, color, tint, hue, model, player}) -> id · game.plane({...}) · game.boat({...}) +game.chaser(id, {targets, attack: {kind, damage, rate, range}, pain: {chance, secs}}) + — THE creature class: sees, paths through corridors, attacks in reach + (ranged attacks fire a real gun), flinches, dies through on_death. A + body spawned with a model whose asset carries an actor definition (an + imported monster) fills health/attack/speed/sounds from that asset: + game.chaser(imp, {targets: "player"}) is a complete monster. +game.sentry(id, {arc, attack}) — stands and shoots what it sees (turret) +game.follower(id, {target, near, far}) — companion; never attacks +game.pacer(id, {speed, turn_at: ["wall","edge"]}) — walks a line, turns + at walls/drop-offs; with hurt rules it is the classic 2D enemy +game.patroller(id, {points | axis: "x" + span, pause, turn_at}) — routes +game.wanderer(id, {home, range, pois: [tags]}) — ambler; pois = villager +game.pickup(id, {give: {health, ammo, count, key, weapon}, respawn}) +game.hazard(id, {damage, period}) — a volume that hurts (lava, spikes) +game.trigger(id, {filter, once}) + game.on_enter/on_exit(|trigger, body|) +game.wander/chase/patrol — the plain route brains (no perception) +game.monster — classic alias of game.chaser; new levels say chaser +game.on_sight/on_attack/on_pain/on_state(|id, ...| ...) — creature + events; returning false cancels the default (attack, flinch, wake) — + that is how a custom behaviour overrides a class without rewriting it game.label(id, "text") · game.text("key", "shown text", {anchor}) game.score(id, points) · game.checkpoint({pos, size}) · game.race({laps}) -game.health(id, {max}) · game.damage(id, n) · game.gun(owner, {rate, damage, view_model}) -> gun -game.on_touch(|a, b| ...) · game.on_death(|id, from| ...) · game.on_tick(|| ...) +game.health(id, {max, pain_chance, invuln_secs, hurt_by: {...}, hurts_on_contact: {...}, explode: {radius, damage}}) + — vitals AND receive rules; game.damage(id, n, {from, kind}) · game.gun(owner, {rate, damage, view_model}) -> gun +game.on_touch(|a, b, side| ...) — side: "above"|"below"|"side" +game.on_death(|id, from| ...) · game.on_tick(|| ...) game.sfx("name") · game.burst(pos, {kind, count}) -A COMPLETE SMALL LEVEL LOOKS LIKE THIS: +BUILD A CREATURE FROM PARTS when no suitable complete model exists. Law: +**attach parts once; never +reposition parts per tick; use part_swing for gait.** Parts are owner-local, +non-colliding visuals and follow a turning/moving body for free. One body gets +one engine behaviour class; there is ZERO `on_tick`: + +```splash +let dog = game.mover({pos: vec3(0, 0.75, 0), size: vec3(1, 0.45, 0.5), color: #8b5a2b, tag: "dog"}) +game.part(dog, {pos: vec3(0, 0.32, -0.58), size: vec3(0.25, 0.25, 0.25), color: #8b5a2b}) +game.part(dog, {pos: vec3(0, 0.28, -0.77), size: vec3(0.16, 0.12, 0.22), color: #5a351d}) +game.part(dog, {pos: vec3(-0.09, 0.49, -0.58), size: vec3(0.11, 0.22, 0.1), shape: "wedge", color: #5a351d}) +game.part(dog, {pos: vec3(0.09, 0.49, -0.58), size: vec3(0.11, 0.22, 0.1), shape: "wedge", color: #5a351d}) +let lf = game.part(dog, {pos: vec3(-0.38, -0.38, -0.3), size: vec3(0.14, 0.55, 0.14), color: #5a351d}) +let rf = game.part(dog, {pos: vec3(0.38, -0.38, -0.3), size: vec3(0.14, 0.55, 0.14), color: #5a351d}) +let lb = game.part(dog, {pos: vec3(-0.38, -0.38, 0.3), size: vec3(0.14, 0.55, 0.14), color: #5a351d}) +let rb = game.part(dog, {pos: vec3(0.38, -0.38, 0.3), size: vec3(0.14, 0.55, 0.14), color: #5a351d}) +game.part(dog, {pos: vec3(0, 0.15, 0.62), size: vec3(0.12, 0.12, 0.5), rot_x: -0.45, color: #8b5a2b}) +game.part_swing(lf, {axis: "x", degrees: 25, hz: 2}) +game.part_swing(rf, {axis: "x", degrees: -25, hz: 2}) +game.part_swing(lb, {axis: "x", degrees: -25, hz: 2}) +game.part_swing(rb, {axis: "x", degrees: 25, hz: 2}) +game.follower(dog, {targets: "player", near: 2, far: 5, speed: 3}) ``` -let SPEED = 7.0 -game.sky({}) -game.sun({time_of_day: 10.0}) -game.terrain({size: 160, cells: 65, smooth: true, seed: 3, amp: 6}) + -let hero = game.player_character({pos: vec3(0, 6, 8)}) -game.label(hero, "You") +CREATURES ARE CLASSES, NEVER HAND-ROLLED AI. Pick a class verb and attach +events; never write chase/attack logic in on_tick, never call game.sfx for +a creature's own sounds (the engine voices its sight/pain/death/attack +slots), never re-implement touch damage. Two worked shapes: +``` +// The 2D-style enemy: walks its line, hurts on side contact, dies to a +// stomp from above. All combat is CONFIG on game.health. +let g = game.character({pos: vec3(4, 1, 0), model: "kenney/mini-characters/character-female-c", tag: "enemy"}) +game.health(g, {max: 1, hurt_by: {contact_above: 1, contact_side: 0, hitscan: 0}, + hurts_on_contact: {side: 1}, stomp_bounce: 7}) +game.pacer(g, {speed: 2, turn_at: ["wall", "edge"]}) -// Store models are miniatures — scale them up next to people: -game.model("kenney/space-kit/hangar_smalla", {pos: vec3(6, 0, -4), yaw: 1.57, scale: 3}) -game.model("kenney/space-kit/rocks_smallb", {pos: vec3(2, 0, -7), scale: 2}) - -let pig = game.mover({pos: vec3(6, 6, 4), size: vec3(0.9, 0.7, 1.4), color: #ffb3c1, tag: "animal"}) -game.wander(pig, {home: vec3(6, 0, 4), range: 12, speed: 2.5}) - -let score = 0 -game.text("score", "Caught: 0", {anchor: "top_left"}) -game.on_touch(|a, b| { - if game.tag(b) == "animal" { - score = score + 1 - game.text("score", "Caught: " + score) - game.sfx("pickup") - game.remove(b) - } -}) +// The imported imp: EVERYTHING below the class name comes off its asset — +// health 60, pain chance, projectile attack, its own sounds. +let imp = game.character({pos: vec3(9, 0, -3), model: "doom/doom/billboards/doom1/troo"}) +game.chaser(imp, {targets: "player"}) +game.on_death(|id, from| if game.tag(id) == "enemy" { game.score(from, 1) }) ``` VILLAGE RECIPE — build from PREBUILT COMPLETE MODELS ONLY: whole houses, diff --git a/libs/asset/chat/src/dispatch.rs b/libs/asset/chat/src/dispatch.rs index d554c2e24..ebd3438d3 100644 --- a/libs/asset/chat/src/dispatch.rs +++ b/libs/asset/chat/src/dispatch.rs @@ -82,6 +82,44 @@ impl AssetServerTools { } } + /// One bounded SELECT over the live catalog, via the server's + /// `/v1/assets/query` route (the server owns the row/step/deadline + /// budgets and the single-SELECT guard). Rendered exactly like the old + /// broker did — aligned text plus a row count — so the model reads it + /// the same way it always has. + fn assets_query(&self, sql: &str) -> ToolOutcome { + match self.api.assets_query(sql) { + Err(e) => err_outcome(e), + Ok(dto) => query_outcome(dto), + } + } + + /// The catalog schema, fetched from the server's own `sqlite_master` + /// through the same bounded query route (there is no dedicated schema + /// endpoint), plus the usage notes the model needs to write good SQL. + fn assets_schema(&self) -> ToolOutcome { + const SCHEMA_SQL: &str = "SELECT name, sql FROM sqlite_master WHERE name IN \ + ('assets', 'asset_aliases', 'asset_revisions', 'search_annotations', \ + 'search_labels') ORDER BY name"; + match self.api.assets_query(SCHEMA_SQL) { + Err(e) => err_outcome(e), + Ok(dto) => { + let mut text = + String::from("Catalog tables (SELECT-only; single statement):\n"); + for row in &dto.rows { + if let Some(sql) = row.get(1) { + text.push_str(sql); + text.push('\n'); + } + } + text.push_str(crate::catalog_sql::SCHEMA_NOTES); + ToolOutcome::Ok { + value: json::obj(vec![("text", json::s(text))]), + } + } + } + } + fn inspect(&self, target: &InspectTarget) -> ToolOutcome { match target { InspectTarget::Revision(rev) => self.revision_summary(rev), @@ -217,12 +255,20 @@ impl ToolExecutor for AssetServerTools { ContentToolCall::LlmConsult { .. } => ToolOutcome::Unavailable { reason: "llm.consult is executed by the chat broker".to_string(), }, + // Catalog SQL runs HERE, over the same authenticated client the + // search uses. The game session advertises assets.query/schema + // (see `tools::sandbox_definitions`) and, since the session + // engine moved in-process (aicore P8), this executor is the one + // that answers them — the old "the broker runs it" refusal left + // the game AI's main alias-search tool permanently dead + // (observed live 2026-09-01: every doom-enemy lookup answered + // "Unavailable" and the model gave up on the store). + ContentToolCall::AssetsQuery { sql } => self.assets_query(sql), + ContentToolCall::AssetsSchema => self.assets_schema(), // Game-client tools: the broker's dispatcher never advertises // them (see `ToolExecutor::tool_definitions`); a model that // calls one anyway gets the honest answer, not an execution. - ContentToolCall::AssetsQuery { .. } - | ContentToolCall::AssetsSchema - | ContentToolCall::ModelBuild { .. } + ContentToolCall::ModelBuild { .. } | ContentToolCall::ModelFetch { .. } | ContentToolCall::WorldPlace { .. } | ContentToolCall::WorldRemove { .. } @@ -236,8 +282,7 @@ impl ToolExecutor for AssetServerTools { | ContentToolCall::WorldTune { .. } | ContentToolCall::WorldAddAddon { .. } | ContentToolCall::WorldInSub { .. } => ToolOutcome::Unavailable { - reason: "catalog SQL, local model, and world tools run in a game chat session" - .to_string(), + reason: "local model and world tools run in a game chat session".to_string(), }, } } @@ -246,6 +291,25 @@ impl ToolExecutor for AssetServerTools { /// Typed error mapping: authorization failures are `Denied` (the ACL /// answer), everything else is an operational failure with a bounded /// description. Never a panic, never a silent Ok. +/// Render one bounded query result the way the broker always has: aligned +/// text with a row-count footer, plus the machine-readable row count the +/// chat UI's chip reads (`outcome_summary` shows "queried → N rows"). +fn query_outcome(dto: makepad_asset_client::dto::AssetsQueryDto) -> ToolOutcome { + let out = crate::catalog_sql::QueryOutput { + columns: dto.columns, + rows: dto.rows, + truncated: dto.truncated, + elapsed_ms: dto.elapsed_ms, + }; + ToolOutcome::Ok { + value: json::obj(vec![ + ("rows", Value::Int(out.rows.len() as i64)), + ("truncated", Value::Bool(out.truncated)), + ("text", json::s(out.to_text())), + ]), + } +} + fn err_outcome(e: ClientError) -> ToolOutcome { match e { ClientError::Unauthenticated => { @@ -324,4 +388,31 @@ mod tests { other => panic!("expected Refused, got {other:?}"), } } + + /// assets.query answers with rendered rows the model can read AND the + /// row count the UI chip reads — not the old "Unavailable" refusal + /// (which left the game session's advertised SQL tool permanently + /// dead; the live doom-enemy hunt died on it, 2026-09-01). + #[test] + fn assets_query_outcome_renders_rows_and_counts() { + let dto = makepad_asset_client::dto::AssetsQueryDto { + columns: vec!["canon_alias".into(), "kind".into()], + rows: vec![ + vec!["doom/doom/billboards/doom1/troo".into(), "billboard".into()], + vec!["doom/doom/billboards/doom1/sarg".into(), "billboard".into()], + ], + truncated: false, + elapsed_ms: 3, + }; + match query_outcome(dto) { + ToolOutcome::Ok { value } => { + assert_eq!(value.get("rows").and_then(Value::as_i64), Some(2)); + let text = value.get("text").and_then(Value::as_str).unwrap(); + assert!(text.contains("canon_alias"), "{text}"); + assert!(text.contains("doom/doom/billboards/doom1/troo"), "{text}"); + assert!(text.contains("(2 rows)"), "{text}"); + } + other => panic!("expected Ok, got {other:?}"), + } + } } diff --git a/libs/asset/chat/src/tools.rs b/libs/asset/chat/src/tools.rs index ab368cba5..e56dcc54e 100644 --- a/libs/asset/chat/src/tools.rs +++ b/libs/asset/chat/src/tools.rs @@ -799,8 +799,12 @@ pub fn sandbox_definitions() -> Vec { game.part_swing for gait, and give the body a follower/chaser/ \ pacer class. Never reposition parts from game.on_tick. PLACE \ spawned creatures NEAR THE PLAYER: `let p = game.player_pos()` \ - then pos: p + vec3(2, 0.55, 0) — an absolute guess like \ - vec3(0,0,2) lands 50 m away where nobody sees it.", + then pos: p + vec3(2, 0.55, 0) for game.mover/game.character \ + (their y is absolute) — an absolute guess like vec3(0,0,2) \ + lands 50 m away where nobody sees it. game.model's pos.y is \ + height ABOVE the ground: use vec3(p.x + 2, 0, p.z) there, \ + never p + vec3(...) — p.y is an absolute feet height and \ + buries the model.", args_doc: r#"{"name": "forest", "src": "for i in 0..12 {\n game.model(\"kenney/nature-kit/tree_oak\", {pos: vec3(i * 3, 0, 8), scale: 2})\n}"}"#, parameters: schema_object( vec![ diff --git a/libs/asset/store/src/host/assets_query.rs b/libs/asset/store/src/host/assets_query.rs index f17372b88..011271d85 100644 --- a/libs/asset/store/src/host/assets_query.rs +++ b/libs/asset/store/src/host/assets_query.rs @@ -349,7 +349,7 @@ impl CatalogReader { /// Advisory notes the model gets with the generated schema. They describe /// the well-known catalog tables; the generated part above is the truth. -const SCHEMA_NOTES: &str = "\nNotes:\n\ +pub const SCHEMA_NOTES: &str = "\nNotes:\n\ - search_annotations is the main listing: one row per asset with \ canon_alias (the readable id you place with), kind, title, description, \ prompt, live (1 = current). Always filter live=1.\n\ From b0380bac349d3f8a85a57e6fee07a038d5dbce38 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 20:19:56 +0200 Subject: [PATCH 005/417] =?UTF-8?q?image-tiles:=20the=20picture-wall=20eng?= =?UTF-8?q?ine=20as=20a=20library=20=E2=80=94=20tape=20atlases,=20a=20bake?= =?UTF-8?q?r=20CLI,=20and=20the=20TileGrid=20widget?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Source Library wall's pixel engine, extracted for anyone's pictures: libs/image_tiles carries the NV12 slot pyramid, the 32x32 shard atlas geometry and the one-HEVC-intra-frame-per-file tape codec (tape.rs), a small SQLite index (db.rs), a priority decode pool (store.rs), and the TileGrid widget — instanced tiles batched per atlas page, anchor-locked wheel zoom with log-space glide, continuous per-shard LOD with crossfades, full-resolution promotion under byte budgets with LRU eviction, and uniform-only re-presents inside the pad of the last build. image-tiles-bake downloads a manifest of URLs (fetch pool free to be wide, encode pool hard-capped — concurrent VT session churn has panicked the encoder's IOMMU) and bakes a library; examples/image_tiles views one. No JPEGs on disk; decode and encode are the hardware's. Co-Authored-By: Claude Fable 5 --- Cargo.toml | 4 + examples/image_tiles/Cargo.toml | 8 + examples/image_tiles/manifest.tsv | 15 + examples/image_tiles/src/main.rs | 86 +++ libs/image_tiles/Cargo.toml | 26 + libs/image_tiles/src/bake.rs | 340 +++++++++ libs/image_tiles/src/bin/bake.rs | 59 ++ libs/image_tiles/src/db.rs | 261 +++++++ libs/image_tiles/src/grid.rs | 1088 +++++++++++++++++++++++++++++ libs/image_tiles/src/lib.rs | 48 ++ libs/image_tiles/src/library.rs | 127 ++++ libs/image_tiles/src/store.rs | 193 +++++ libs/image_tiles/src/tape.rs | 356 ++++++++++ 13 files changed, 2611 insertions(+) create mode 100644 examples/image_tiles/Cargo.toml create mode 100644 examples/image_tiles/manifest.tsv create mode 100644 examples/image_tiles/src/main.rs create mode 100644 libs/image_tiles/Cargo.toml create mode 100644 libs/image_tiles/src/bake.rs create mode 100644 libs/image_tiles/src/bin/bake.rs create mode 100644 libs/image_tiles/src/db.rs create mode 100644 libs/image_tiles/src/grid.rs create mode 100644 libs/image_tiles/src/lib.rs create mode 100644 libs/image_tiles/src/library.rs create mode 100644 libs/image_tiles/src/store.rs create mode 100644 libs/image_tiles/src/tape.rs diff --git a/Cargo.toml b/Cargo.toml index 460538847..93abc404c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -123,6 +123,10 @@ workspace.members = [ "libs/frametween", # === archive.org search + download content input (VJ / asset-ui) === "libs/archive_org", + # === image tile wall: HEVC tape atlases + baker CLI + TileGrid widget + # (the engine extracted from the Source Library picture wall) === + "libs/image_tiles", + "examples/image_tiles", # === mp4 sample index for range-streaming playback === "libs/mp4_index", # === necessary tools === diff --git a/examples/image_tiles/Cargo.toml b/examples/image_tiles/Cargo.toml new file mode 100644 index 000000000..4bf6fda37 --- /dev/null +++ b/examples/image_tiles/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "makepad-example-image-tiles" +version = "0.1.0" +edition = "2021" + +[dependencies] +makepad-widgets = { path = "../../widgets", version = "2.0.0" } +makepad-image-tiles = { path = "../../libs/image_tiles" } diff --git a/examples/image_tiles/manifest.tsv b/examples/image_tiles/manifest.tsv new file mode 100644 index 000000000..00d873d64 --- /dev/null +++ b/examples/image_tiles/manifest.tsv @@ -0,0 +1,15 @@ +# One picture per line: urltitlelink. Bare URLs work too. +# These are public-domain paintings served by Wikimedia Commons, asked for +# at a modest width so a first bake is quick and gentle. +https://commons.wikimedia.org/wiki/Special:FilePath/Claude%20Monet%2C%20Impression%2C%20soleil%20levant.jpg?width=1600 Impression, Sunrise https://commons.wikimedia.org/wiki/File:Claude_Monet,_Impression,_soleil_levant.jpg +https://commons.wikimedia.org/wiki/Special:FilePath/Meisje%20met%20de%20parel.jpg?width=1600 Girl with a Pearl Earring https://commons.wikimedia.org/wiki/File:Meisje_met_de_parel.jpg +https://commons.wikimedia.org/wiki/Special:FilePath/The%20Great%20Wave%20off%20Kanagawa.jpg?width=1600 The Great Wave off Kanagawa https://commons.wikimedia.org/wiki/File:The_Great_Wave_off_Kanagawa.jpg +https://commons.wikimedia.org/wiki/Special:FilePath/Mona%20Lisa%2C%20by%20Leonardo%20da%20Vinci%2C%20from%20C2RMF%20retouched.jpg?width=1600 Mona Lisa https://commons.wikimedia.org/wiki/File:Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg +https://commons.wikimedia.org/wiki/Special:FilePath/The%20Night%20Watch%20-%20HD.jpg?width=1600 The Night Watch https://commons.wikimedia.org/wiki/File:The_Night_Watch_-_HD.jpg +https://commons.wikimedia.org/wiki/Special:FilePath/Gustav%20Klimt%20016.jpg?width=1600 The Kiss https://commons.wikimedia.org/wiki/File:The_Kiss_-_Gustav_Klimt_-_Google_Cultural_Institute.jpg +https://commons.wikimedia.org/wiki/Special:FilePath/Edvard%20Munch%2C%201893%2C%20The%20Scream%2C%20oil%2C%20tempera%20and%20pastel%20on%20cardboard%2C%2091%20x%2073%20cm%2C%20National%20Gallery%20of%20Norway.jpg?width=1600 The Scream https://commons.wikimedia.org/wiki/File:Edvard_Munch,_1893,_The_Scream.jpg +https://commons.wikimedia.org/wiki/Special:FilePath/Sandro%20Botticelli%20-%20La%20nascita%20di%20Venere%20-%20Google%20Art%20Project%20-%20edited.jpg?width=1600 The Birth of Venus https://commons.wikimedia.org/wiki/File:Sandro_Botticelli_-_La_nascita_di_Venere.jpg +https://commons.wikimedia.org/wiki/Special:FilePath/Caspar%20David%20Friedrich%20-%20Wanderer%20above%20the%20sea%20of%20fog.jpg?width=1600 Wanderer above the Sea of Fog https://commons.wikimedia.org/wiki/File:Caspar_David_Friedrich_-_Wanderer_above_the_sea_of_fog.jpg +https://commons.wikimedia.org/wiki/Special:FilePath/Van%20Gogh%20-%20Starry%20Night%20-%20Google%20Art%20Project.jpg?width=1600 The Starry Night (drawing) https://commons.wikimedia.org/wiki/File:Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg +https://commons.wikimedia.org/wiki/Special:FilePath/Nighthawks%20by%20Edward%20Hopper%201942.jpg?width=1600 Nighthawks https://commons.wikimedia.org/wiki/File:Nighthawks_by_Edward_Hopper_1942.jpg +https://commons.wikimedia.org/wiki/Special:FilePath/Georges%20Seurat%20-%20A%20Sunday%20on%20La%20Grande%20Jatte%20--%201884%20-%20Google%20Art%20Project.jpg?width=1600 A Sunday Afternoon on La Grande Jatte https://commons.wikimedia.org/wiki/File:A_Sunday_on_La_Grande_Jatte,_Georges_Seurat,_1884.jpg diff --git a/examples/image_tiles/src/main.rs b/examples/image_tiles/src/main.rs new file mode 100644 index 000000000..fc2f687e1 --- /dev/null +++ b/examples/image_tiles/src/main.rs @@ -0,0 +1,86 @@ +//! A pannable, zoomable wall of pictures over a baked tile library. +//! +//! Bake a library first (the manifest beside this example is a start): +//! ```text +//! cargo run -p makepad-image-tiles --release --bin image-tiles-bake -- \ +//! examples/image_tiles/manifest.tsv +//! ``` +//! then run this viewer from the same directory. `IMAGE_TILES_HOME` names a +//! different library; the default is the nearest `local/image-tiles`. +//! Wheel zooms around the cursor, drag pans, click logs the picture. + +pub use makepad_widgets; +use makepad_image_tiles::TileGridAction; +use makepad_widgets::*; + +app_main!(App); + +script_mod! { + use mod.prelude.widgets.* + use mod.widgets.* + + startup() do #(App::script_component(vm)){ + ui: Root{ + main_window := Window{ + window.inner_size: vec2(1200, 800) + body +: { + grid_wrap := View{ + width: Fill + height: Fill + grid := TileGrid{} + } + } + } + } + } +} + +#[derive(Script, ScriptHook)] +pub struct App { + #[live] + ui: WidgetRef, +} + +impl MatchEvent for App { + fn handle_startup(&mut self, cx: &mut Cx) { + // The grid owns its draw list: without this, any sibling redraw + // re-runs the grid's draw_walk and re-uploads the whole instance + // buffer every frame. + if let Some(mut wrap) = self.ui.view(cx, ids!(grid_wrap)).borrow_mut() { + wrap.set_optimize(cx, ViewOptimize::DrawList); + } + } + + fn handle_actions(&mut self, _cx: &mut Cx, actions: &Actions) { + for action in actions { + let Some(widget_action) = action.as_widget_action() else { + continue; + }; + match widget_action.cast() { + TileGridAction::Clicked { item, title, link, url } => { + log!("picture {item}: {title} — {}", if link.is_empty() { url } else { link }); + } + TileGridAction::Opened { count, error: None } => { + log!("library open: {count} picture(s)"); + } + TileGridAction::Opened { error: Some(e), .. } => { + log!("no library: {e} — bake one with image-tiles-bake first"); + } + _ => {} + } + } + } +} + +impl AppMain for App { + fn script_mod(vm: &mut ScriptVm) -> ScriptValue { + crate::makepad_widgets::script_mod(vm); + makepad_image_tiles::script_mod(vm); + self::script_mod(vm) + } + + fn handle_event(&mut self, cx: &mut Cx, event: &Event) { + self.match_event(cx, event); + self.ui.handle_event(cx, event, &mut Scope::empty()); + } +} diff --git a/libs/image_tiles/Cargo.toml b/libs/image_tiles/Cargo.toml new file mode 100644 index 000000000..a3fd22c57 --- /dev/null +++ b/libs/image_tiles/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "makepad-image-tiles" +version = "0.1.0" +edition = "2021" +description = "Pannable, zoomable wall of image tiles: a small baker CLI downloads pictures into hardware-HEVC tape atlases, and the TileGrid widget draws them as instanced NV12 textures with continuous LOD" +license = "MIT OR Apache-2.0" + +[lib] +name = "makepad_image_tiles" +path = "src/lib.rs" + +# The baker: reads a manifest of image URLs, downloads and decodes them in +# RAM, and bakes the tile library a TileGrid widget opens. No window. +[[bin]] +name = "image-tiles-bake" +path = "src/bin/bake.rs" + +[dependencies] +makepad-widgets = { path = "../../widgets" } +# The library index: items and shard bookkeeping in our own SQLite engine. +makepad-sqlite = { path = "../sqlite_query" } +# Hardware HEVC intra frames (VideoToolbox) for the on-disk tapes: no JPEGs +# or PNGs are ever kept, one hardware decode fills a whole atlas level. +makepad-video = { path = "../../platform/video" } +# The baker's downloader: the dependency-free blocking HTTP client. +makepad-network = { path = "../../platform/network" } diff --git a/libs/image_tiles/src/bake.rs b/libs/image_tiles/src/bake.rs new file mode 100644 index 000000000..4a371bd43 --- /dev/null +++ b/libs/image_tiles/src/bake.rs @@ -0,0 +1,340 @@ +//! The baker: a manifest of image URLs in, a baked tile library out. +//! +//! Deliberately small and linear so it is easy to customise — swap +//! [`parse_manifest`] for your own catalogue walker, or call [`bake`] from +//! your own tool with sources you built any other way. The pipeline is: +//! fetch threads pull bytes off the wire; encode workers decode in RAM, +//! cut the slot pyramid and write the HEVC full/pyramid frames; the packer +//! (this thread) blits slots into the open shard, records the index row and +//! seals full shards to tape. Re-running is cheap: URLs already baked are +//! skipped, and a crash mid-shard resets only that shard's items. + +use crate::db::{ShardRow, TileDb}; +use crate::library::{mark_no_pyramid, Library}; +use crate::tape::{ + box_downscale, build_pyramid, decode_image, fit_dims, image_to_rgba, page_size, write_frame, Planes, TilePyramid, + FULL_BPP, FULL_MAX_PX, LEVELS, PAGE_BPP, PYRAMID_LEVELS, SHARD_CAP, +}; +use makepad_network::blocking_http::{self, Limits, Request}; +use std::collections::VecDeque; +use std::sync::mpsc::{self, SyncSender}; +use std::sync::{Arc, Mutex}; +use std::time::{Duration, Instant}; + +/// The largest picture download accepted. +pub const PICTURE_MAX_BYTES: usize = 64 * 1024 * 1024; +const MAX_REDIRECTS: usize = 5; + +#[derive(Clone, Debug)] +pub struct Source { + pub url: String, + pub title: String, + pub link: String, +} + +#[derive(Clone, Copy, Debug)] +pub struct BakeOptions { + /// Network threads: sockets, not cores; raise freely. + pub fetch_threads: usize, + /// Decode + HEVC encode workers. Every worker holds a VideoToolbox + /// compression session per frame it writes; dozens of concurrent + /// session create/teardowns per second have kernel-panicked an M3 Max + /// (the AVE encoder's IOMMU falls over), so this stays bounded and + /// modest — the clamp in [`bake`] is a hard one, not a suggestion. + pub encode_threads: usize, + /// Put previously-failed items back in the queue first. + pub retry_failed: bool, +} + +impl Default for BakeOptions { + fn default() -> BakeOptions { + BakeOptions { fetch_threads: 6, encode_threads: 4, retry_failed: false } + } +} + +#[derive(Clone, Copy, Debug, Default)] +pub struct BakeSummary { + pub baked: usize, + pub failed: usize, + pub skipped: usize, + pub shards_sealed: usize, +} + +/// One manifest line per picture: a bare URL, or `urltitlelink`. +/// Blank lines and `#` comments are skipped. +pub fn parse_manifest(text: &str) -> Vec { + let mut out = Vec::new(); + for line in text.lines() { + let line = line.trim(); + if line.is_empty() || line.starts_with('#') { + continue; + } + let mut parts = line.split('\t'); + let url = parts.next().unwrap_or("").trim().to_string(); + if url.is_empty() { + continue; + } + let title = parts.next().map(str::trim).filter(|t| !t.is_empty()).map(String::from).unwrap_or_else(|| { + url.rsplit('/').find(|s| !s.is_empty()).unwrap_or("untitled").to_string() + }); + let link = parts.next().map(str::trim).unwrap_or("").to_string(); + out.push(Source { url, title, link }); + } + out +} + +/// GET with a bounded body and a short redirect chain; the platform client +/// does one hop at a time and never follows a redirect on its own. +pub fn fetch_bytes(url: &str, max_bytes: usize) -> Result, String> { + let mut current = url.to_string(); + for _ in 0..=MAX_REDIRECTS { + let limits = Limits { max_body_bytes: max_bytes, total_timeout: Duration::from_secs(120), ..Limits::default() }; + let request = Request::get(current.clone()).limits(limits); + let response = blocking_http::request_no_redirect(request).map_err(|e| format!("GET {current}: {e:?}"))?; + match response.status { + 200 => return Ok(response.body), + 301 | 302 | 303 | 307 | 308 => { + let location = response.header("location").ok_or_else(|| format!("GET {current}: redirect without location"))?; + current = if location.starts_with("http://") || location.starts_with("https://") { + location.to_string() + } else if let Some(rest) = location.strip_prefix('/') { + let origin_end = current.find("://").map(|i| i + 3).unwrap_or(0); + let origin = match current[origin_end..].find('/') { + Some(i) => ¤t[..origin_end + i], + None => ¤t, + }; + format!("{origin}/{rest}") + } else { + return Err(format!("GET {current}: unsupported relative redirect {location}")); + }; + } + status => return Err(format!("GET {current}: HTTP {status}")), + } + } + Err(format!("GET {url}: too many redirects")) +} + +struct Baked { + width: u32, + height: u32, + pyramid: TilePyramid, +} + +/// The CPU half of one picture: decode, the slot pyramid, the capped full +/// frame and its pre-cut zoom levels — everything except the shard, which +/// belongs to the packer. +fn process_picture(library: &Library, id: i64, bytes: &[u8]) -> Result { + let img = decode_image(bytes)?; + let (w, h) = (img.width as u32, img.height as u32); + let rgba = image_to_rgba(&img); + let pyramid = build_pyramid(&rgba, w, h); + let (fw, fh) = fit_dims(w, h, FULL_MAX_PX); + // The fitted buffer is kept: it is also the zoom pyramid's source. The + // levels are each made from the one above, so the whole pyramid costs + // about a third more than its top level instead of a multiple of it. + let fitted: Option> = if (fw, fh) == (w, h) { None } else { Some(box_downscale(&rgba, w, h, 4, fw, fh)) }; + let full = Planes::from_rgba(fitted.as_deref().unwrap_or(&rgba), fw, fh); + write_frame(&library.full_path(id), &full, FULL_BPP).map_err(|e| format!("full frame: {e}"))?; + let (mut lw, mut lh) = (fw, fh); + let mut level_rgba: Option> = None; + let mut any = false; + for px in PYRAMID_LEVELS { + let (nw, nh) = fit_dims(lw, lh, px); + if (nw, nh) == (lw, lh) { + continue; + } + let src = level_rgba.as_deref().or(fitted.as_deref()).unwrap_or(&rgba); + let next = box_downscale(src, lw, lh, 4, nw, nh); + let frame = Planes::from_rgba(&next, nw, nh); + write_frame(&library.pyramid_path(id, px), &frame, FULL_BPP).map_err(|e| format!("pyramid {px}: {e}"))?; + level_rgba = Some(next); + (lw, lh) = (nw, nh); + any = true; + } + if !any { + mark_no_pyramid(library, id); + } + Ok(Baked { width: w, height: h, pyramid }) +} + +struct OpenShard { + id: i64, + count: u32, + pages: Vec, +} + +fn open_shard(id: i64) -> OpenShard { + OpenShard { id, count: 0, pages: (0..LEVELS).map(|l| Planes::black(page_size(l), page_size(l))).collect() } +} + +/// Write a filled (or final partial) shard's five tape frames and mark it +/// sealed. Runs on the packer thread: the writes are serial, which also +/// keeps the encoder-session count honest. +fn seal(library: &Library, db: &mut TileDb, shard: OpenShard) -> Result<(), String> { + for (level, page) in shard.pages.iter().enumerate() { + write_frame(&library.tape_path(shard.id, level), page, PAGE_BPP).map_err(|e| format!("tape {} L{level}: {e}", shard.id))?; + } + db.upsert_shard(ShardRow { id: shard.id, count: shard.count as i64, sealed: true }) +} + +enum PackMsg { + Baked { id: i64, baked: Baked }, + Failed { id: i64, error: String }, +} + +/// Bake `sources` into the library at `root`. Safe to re-run: known URLs +/// keep their pixels, only pending (and, with `retry_failed`, failed) items +/// are fetched. `log` gets one line per notable event. +pub fn bake( + root: &std::path::Path, + sources: &[Source], + options: &BakeOptions, + log: &mut dyn FnMut(String), +) -> Result { + let library = Library::new(root); + library.ensure_dirs()?; + let mut db = TileDb::open(&library.db_path())?; + let reset = db.reset_unsealed_shards()?; + if reset > 0 { + log(format!("{reset} unsealed shard(s) from an interrupted run reset")); + } + for s in sources { + db.add_source(&s.url, &s.title, &s.link)?; + } + if options.retry_failed { + let retried = db.retry_failed()?; + if retried > 0 { + log(format!("{retried} failed item(s) back in the queue")); + } + } + let pending = db.pending()?; + let (already_pending, ready, failed_before) = db.counts()?; + let _ = already_pending; + let mut summary = BakeSummary { skipped: ready as usize, ..Default::default() }; + if pending.is_empty() { + log(format!("nothing to bake: {ready} ready, {failed_before} failed")); + return Ok(summary); + } + log(format!("baking {} picture(s) ({ready} already in the library)", pending.len())); + + let fetch_threads = options.fetch_threads.clamp(1, 32); + // The hard encoder cap — see BakeOptions::encode_threads. + let encode_threads = options.encode_threads.clamp(1, 8); + + let (job_tx, job_rx) = mpsc::channel::<(i64, String)>(); + for job in &pending { + let _ = job_tx.send(job.clone()); + } + drop(job_tx); + let job_rx = Arc::new(Mutex::new(job_rx)); + // Bounded: fetched bytes wait here for a core, and a fast line must not + // move the whole manifest into RAM. + let (fetched_tx, fetched_rx) = mpsc::sync_channel::<(i64, Vec)>(encode_threads); + let fetched_rx = Arc::new(Mutex::new(fetched_rx)); + let (done_tx, done_rx) = mpsc::channel::(); + + let total = pending.len(); + let result = std::thread::scope(|scope| -> Result<(), String> { + for _ in 0..fetch_threads { + let job_rx = job_rx.clone(); + let fetched_tx: SyncSender<(i64, Vec)> = fetched_tx.clone(); + let done_tx = done_tx.clone(); + scope.spawn(move || loop { + let job = { job_rx.lock().unwrap().recv() }; + let Ok((id, url)) = job else { break }; + match fetch_bytes(&url, PICTURE_MAX_BYTES) { + Ok(bytes) => { + if fetched_tx.send((id, bytes)).is_err() { + break; + } + } + Err(error) => { + if done_tx.send(PackMsg::Failed { id, error }).is_err() { + break; + } + } + } + }); + } + drop(fetched_tx); + for _ in 0..encode_threads { + let fetched_rx = fetched_rx.clone(); + let done_tx = done_tx.clone(); + let library = library.clone(); + scope.spawn(move || loop { + let job = { fetched_rx.lock().unwrap().recv() }; + let Ok((id, bytes)) = job else { break }; + let msg = match process_picture(&library, id, &bytes) { + Ok(baked) => PackMsg::Baked { id, baked }, + Err(error) => PackMsg::Failed { id, error }, + }; + if done_tx.send(msg).is_err() { + break; + } + }); + } + drop(done_tx); + + // The packer: this thread. One open shard, slots filled in arrival + // order, sealed when full. + let mut open: Option = None; + let mut next_shard = db.next_shard()?; + let mut taken = 0usize; + let mut last_report = Instant::now(); + let mut recent_errors: VecDeque = VecDeque::new(); + while let Ok(msg) = done_rx.recv() { + taken += 1; + match msg { + PackMsg::Baked { id, baked } => { + let shard = open.get_or_insert_with(|| { + let s = open_shard(next_shard); + next_shard += 1; + s + }); + let slot = shard.count; + for (level, planes) in baked.pyramid.levels.iter().enumerate() { + let (x, y) = crate::tape::slot_origin(slot, level); + shard.pages[level].blit(planes, x, y); + } + shard.count += 1; + db.upsert_shard(ShardRow { id: shard.id, count: shard.count as i64, sealed: false })?; + db.set_ready(id, baked.width, baked.height, shard.id, slot)?; + summary.baked += 1; + if shard.count >= SHARD_CAP { + let full = open.take().unwrap(); + seal(&library, &mut db, full)?; + summary.shards_sealed += 1; + } + } + PackMsg::Failed { id, error } => { + db.set_failed(id, &error)?; + summary.failed += 1; + recent_errors.push_back(error); + if recent_errors.len() > 3 { + recent_errors.pop_front(); + } + } + } + if last_report.elapsed().as_secs_f64() > 2.0 || taken == total { + last_report = Instant::now(); + let mut line = format!("baked {}/{total} ({} failed)", summary.baked, summary.failed); + for e in recent_errors.drain(..) { + line.push_str(&format!("\n {e}")); + } + log(line); + } + } + if let Some(shard) = open.take() { + seal(&library, &mut db, shard)?; + summary.shards_sealed += 1; + } + Ok(()) + }); + result?; + let (pending_after, ready_after, failed_after) = db.counts()?; + log(format!( + "done: {ready_after} ready, {failed_after} failed, {pending_after} pending, {} shard(s) sealed this run", + summary.shards_sealed + )); + Ok(summary) +} diff --git a/libs/image_tiles/src/bin/bake.rs b/libs/image_tiles/src/bin/bake.rs new file mode 100644 index 000000000..ae7f2578d --- /dev/null +++ b/libs/image_tiles/src/bin/bake.rs @@ -0,0 +1,59 @@ +//! The baker CLI: a manifest of image URLs in, a baked tile library out. +//! +//! ```text +//! image-tiles-bake --root [--fetch N] [--encode N] [--retry-failed] +//! ``` +//! +//! The manifest is one picture per line: a bare URL, or +//! `urltitlelink`. Blank lines and `#` comments are skipped. +//! Re-running is cheap: pictures already baked are skipped. This file is +//! deliberately a thin wrapper — the engine is `makepad_image_tiles::bake`, +//! made to be called from (and customised by) your own tools. + +use makepad_image_tiles::bake::{bake, parse_manifest, BakeOptions}; +use std::path::PathBuf; + +fn usage() -> ! { + eprintln!("usage: image-tiles-bake --root [--fetch N] [--encode N] [--retry-failed] "); + std::process::exit(2); +} + +fn main() { + let mut root: Option = None; + let mut manifest: Option = None; + let mut options = BakeOptions::default(); + let mut args = std::env::args().skip(1); + while let Some(arg) = args.next() { + match arg.as_str() { + "--root" => root = args.next().map(PathBuf::from), + "--fetch" => options.fetch_threads = args.next().and_then(|v| v.parse().ok()).unwrap_or_else(|| usage()), + "--encode" => options.encode_threads = args.next().and_then(|v| v.parse().ok()).unwrap_or_else(|| usage()), + "--retry-failed" => options.retry_failed = true, + "--help" | "-h" => usage(), + _ if arg.starts_with('-') => usage(), + _ => manifest = Some(PathBuf::from(arg)), + } + } + let Some(manifest) = manifest else { usage() }; + let root = root.unwrap_or_else(|| makepad_image_tiles::Library::resolve().root); + let text = match std::fs::read_to_string(&manifest) { + Ok(t) => t, + Err(e) => { + eprintln!("read {}: {e}", manifest.display()); + std::process::exit(1); + } + }; + let sources = parse_manifest(&text); + println!("library: {} — {} source(s) in the manifest", root.display(), sources.len()); + match bake(&root, &sources, &options, &mut |line| println!("{line}")) { + Ok(summary) => { + if summary.failed > 0 { + std::process::exit(3); + } + } + Err(e) => { + eprintln!("bake: {e}"); + std::process::exit(1); + } + } +} diff --git a/libs/image_tiles/src/db.rs b/libs/image_tiles/src/db.rs new file mode 100644 index 000000000..515f55ba2 --- /dev/null +++ b/libs/image_tiles/src/db.rs @@ -0,0 +1,261 @@ +//! The library index: one SQLite file, two tables. +//! +//! `items` is every picture the baker was ever asked for — its source URL, +//! a little display metadata, and once baked, the shard and slot its pixels +//! live at. `shards` records which tape files exist and are complete. The +//! whole thing is deliberately small so people can point their own tools +//! (or an AI) at it: add rows with any SQLite writer, run the baker, and the +//! grid draws whatever reached `status = 1`. + +use makepad_sqlite::{Connection, Database, Value}; +use std::path::Path; +use std::time::Duration; + +pub type ItemId = i64; + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum ItemStatus { + Pending, + Ready, + Failed, +} + +impl ItemStatus { + fn as_i64(self) -> i64 { + match self { + ItemStatus::Pending => 0, + ItemStatus::Ready => 1, + ItemStatus::Failed => 2, + } + } +} + +#[derive(Clone, Debug)] +pub struct ItemRow { + pub id: ItemId, + pub url: String, + pub title: String, + pub link: String, + pub width: i64, + pub height: i64, + pub aspect: f64, + pub shard: Option, + pub slot: Option, +} + +#[derive(Clone, Copy, Debug)] +pub struct ShardRow { + pub id: i64, + pub count: i64, + pub sealed: bool, +} + +const SCHEMA: &str = " +CREATE TABLE IF NOT EXISTS items( + id INTEGER PRIMARY KEY, + url TEXT NOT NULL UNIQUE, + title TEXT NOT NULL DEFAULT '', + link TEXT NOT NULL DEFAULT '', + width INTEGER NOT NULL DEFAULT 0, + height INTEGER NOT NULL DEFAULT 0, + aspect REAL NOT NULL DEFAULT 1.0, + shard INTEGER, + slot INTEGER, + status INTEGER NOT NULL DEFAULT 0, + error TEXT NOT NULL DEFAULT '' +); +CREATE TABLE IF NOT EXISTS shards( + id INTEGER PRIMARY KEY, + count INTEGER NOT NULL, + sealed INTEGER NOT NULL +); +"; + +/// The baker's writable handle on the index. +pub struct TileDb { + conn: Connection, +} + +impl TileDb { + pub fn open(path: &Path) -> Result { + let mut conn = Connection::open(path, Duration::from_secs(5)) + .map_err(|e| format!("open {}: {e:?}", path.display()))?; + conn.execute_batch(SCHEMA).map_err(|e| format!("schema: {e:?}"))?; + Ok(TileDb { conn }) + } + + /// Add a source URL to bake. Already-known URLs keep their row (and + /// their pixels); title/link are refreshed. + pub fn add_source(&mut self, url: &str, title: &str, link: &str) -> Result<(), String> { + self.conn + .execute( + "INSERT INTO items(url, title, link) VALUES(?, ?, ?) + ON CONFLICT(url) DO UPDATE SET title = ?, link = ?", + &[Value::text(url), Value::text(title), Value::text(link), Value::text(title), Value::text(link)], + ) + .map(|_| ()) + .map_err(|e| format!("add {url}: {e:?}")) + } + + /// Everything still waiting for pixels, oldest first. + pub fn pending(&mut self) -> Result, String> { + let result = self + .conn + .query("SELECT id, url FROM items WHERE status = 0 ORDER BY id", &[]) + .map_err(|e| format!("pending: {e:?}"))?; + Ok(result + .rows + .iter() + .filter_map(|r| Some((r[0].as_integer()?, r[1].as_text()?.to_string()))) + .collect()) + } + + /// Put permanently-failed items back in the queue for another try. + pub fn retry_failed(&mut self) -> Result { + self.conn + .execute("UPDATE items SET status = 0, error = '' WHERE status = 2", &[]) + .map_err(|e| format!("retry: {e:?}")) + } + + pub fn set_ready( + &mut self, + id: ItemId, + width: u32, + height: u32, + shard: i64, + slot: u32, + ) -> Result<(), String> { + let aspect = width.max(1) as f64 / height.max(1) as f64; + self.conn + .execute( + "UPDATE items SET status = 1, width = ?, height = ?, aspect = ?, shard = ?, slot = ?, error = '' WHERE id = ?", + &[ + Value::Integer(width as i64), + Value::Integer(height as i64), + Value::Real(aspect), + Value::Integer(shard), + Value::Integer(slot as i64), + Value::Integer(id), + ], + ) + .map(|_| ()) + .map_err(|e| format!("ready {id}: {e:?}")) + } + + pub fn set_failed(&mut self, id: ItemId, error: &str) -> Result<(), String> { + self.conn + .execute( + "UPDATE items SET status = 2, error = ? WHERE id = ?", + &[Value::text(error), Value::Integer(id)], + ) + .map(|_| ()) + .map_err(|e| format!("fail {id}: {e:?}")) + } + + pub fn upsert_shard(&mut self, shard: ShardRow) -> Result<(), String> { + self.conn + .execute( + "INSERT INTO shards(id, count, sealed) VALUES(?, ?, ?) + ON CONFLICT(id) DO UPDATE SET count = ?, sealed = ?", + &[ + Value::Integer(shard.id), + Value::Integer(shard.count), + Value::Integer(shard.sealed as i64), + Value::Integer(shard.count), + Value::Integer(shard.sealed as i64), + ], + ) + .map(|_| ()) + .map_err(|e| format!("shard {}: {e:?}", shard.id)) + } + + pub fn shards(&mut self) -> Result, String> { + let result = self + .conn + .query("SELECT id, count, sealed FROM shards ORDER BY id", &[]) + .map_err(|e| format!("shards: {e:?}"))?; + Ok(result + .rows + .iter() + .filter_map(|r| { + Some(ShardRow { id: r[0].as_integer()?, count: r[1].as_integer()?, sealed: r[2].as_integer()? != 0 }) + }) + .collect()) + } + + /// A shard whose tapes never got written (a crash while it was open) + /// holds no pixels: its items go back to pending so they are fetched + /// again, and the shard id is freed. + pub fn reset_unsealed_shards(&mut self) -> Result { + let open: Vec = self.shards()?.into_iter().filter(|s| !s.sealed).map(|s| s.id).collect(); + for id in &open { + self.conn + .execute( + "UPDATE items SET status = 0, shard = NULL, slot = NULL WHERE shard = ?", + &[Value::Integer(*id)], + ) + .map_err(|e| format!("reset shard {id}: {e:?}"))?; + self.conn + .execute("DELETE FROM shards WHERE id = ?", &[Value::Integer(*id)]) + .map_err(|e| format!("drop shard {id}: {e:?}"))?; + } + Ok(open.len()) + } + + pub fn next_shard(&mut self) -> Result { + let result = self.conn.query("SELECT MAX(id) FROM shards", &[]).map_err(|e| format!("next shard: {e:?}"))?; + Ok(result.scalar().and_then(|v| v.as_integer()).unwrap_or(-1) + 1) + } + + pub fn counts(&mut self) -> Result<(i64, i64, i64), String> { + let q = |conn: &mut Connection, status: i64| -> Result { + Ok(conn + .query("SELECT COUNT(*) FROM items WHERE status = ?", &[Value::Integer(status)]) + .map_err(|e| format!("count: {e:?}"))? + .scalar() + .and_then(|v| v.as_integer()) + .unwrap_or(0)) + }; + let pending = q(&mut self.conn, ItemStatus::Pending.as_i64())?; + let ready = q(&mut self.conn, ItemStatus::Ready.as_i64())?; + let failed = q(&mut self.conn, ItemStatus::Failed.as_i64())?; + Ok((pending, ready, failed)) + } +} + +/// What a viewer needs, read without taking the writer's lock: every baked +/// picture in id order, plus which shards are sealed. +pub fn read_items(path: &Path) -> Result<(Vec, Vec), String> { + let mut db = Database::open(path).map_err(|e| format!("open {}: {e:?}", path.display()))?; + let result = db + .query( + "SELECT id, url, title, link, width, height, aspect, shard, slot FROM items \ + WHERE status = 1 AND shard IS NOT NULL ORDER BY id", + &[], + ) + .map_err(|e| format!("items: {e:?}"))?; + let items = result + .rows + .iter() + .filter_map(|r| { + Some(ItemRow { + id: r[0].as_integer()?, + url: r[1].as_text().unwrap_or("").to_string(), + title: r[2].as_text().unwrap_or("").to_string(), + link: r[3].as_text().unwrap_or("").to_string(), + width: r[4].as_integer().unwrap_or(0), + height: r[5].as_integer().unwrap_or(0), + aspect: r[6].as_real().or_else(|| r[6].as_integer().map(|i| i as f64)).unwrap_or(1.0), + shard: r[7].as_integer(), + slot: r[8].as_integer(), + }) + }) + .collect(); + let result = db.query("SELECT id, count, sealed FROM shards ORDER BY id", &[]).map_err(|e| format!("shards: {e:?}"))?; + let shards = result + .rows + .iter() + .filter_map(|r| Some(ShardRow { id: r[0].as_integer()?, count: r[1].as_integer()?, sealed: r[2].as_integer()? != 0 })) + .collect(); + Ok((items, shards)) +} diff --git a/libs/image_tiles/src/grid.rs b/libs/image_tiles/src/grid.rs new file mode 100644 index 000000000..e3308c4fc --- /dev/null +++ b/libs/image_tiles/src/grid.rs @@ -0,0 +1,1088 @@ +//! The TileGrid widget: a camera over a plane of image tiles. +//! +//! Every picture is one instance of one draw shader, batched per +//! (shard, level) atlas page — thousands of pictures are a handful of draw +//! calls. Pan and zoom are uniforms: while the camera glides inside the pad +//! of the last build, retained draw calls are re-presented with fresh +//! uniforms and the instance buffer is never re-uploaded. Atlas pages carry +//! continuous per-shard LOD with crossfades; a tile grown past its slot is +//! promoted to its own full-resolution mip-chain texture under byte budgets +//! with LRU eviction. +//! +//! IMPORTANT for hosts: wrap the grid in a `View` and give that view +//! `ViewOptimize::DrawList` once at startup — +//! ```ignore +//! if let Some(mut wrap) = self.ui.view(cx, ids!(grid_wrap)).borrow_mut() { +//! wrap.set_optimize(cx, ViewOptimize::DrawList); +//! } +//! ``` +//! — so a sibling widget's redraw cannot re-run this widget's draw and +//! re-upload a six-figure instance buffer. The uniform-only glide path +//! depends on the grid owning its draw list. + +use crate::db::{self, ItemRow}; +use crate::library::{ItemId, Library}; +use crate::store::{self, StoreEvent, StoreHandle}; +use crate::tape::{fit_dims, page_size, Planes, FullFrame, GRID, LEVELS, PYRAMID_LEVELS, SLOT}; +use makepad_widgets::*; +use std::collections::{HashMap, HashSet}; +use std::sync::Arc; +use std::time::Instant; + +script_mod! { + use mod.prelude.widgets_internal.* + use mod.widgets.* + + set_type_default() do #(DrawTile::script_shader(vm)){ + ..mod.draw.DrawQuad + tex_y: texture_2d(float) + tex_uv: texture_2d(float) + cam_pos: uniform(vec2(0.0, 0.0)) + cam_scale: uniform(100.0) + view_center: uniform(vec2(0.0, 0.0)) + tile_pos: vec2(0.0, 0.0) + tile_size: vec2(1.0, 1.0) + // 1: tex_y is a BGRA mip chain (a full-resolution picture). + rgba: 0.0 + uv0: vec2(0.0, 0.0) + uv1: vec2(1.0, 1.0) + fade: 1.0 + alpha_v: varying(float) + + vertex: fn() { + // Geometry anti-aliasing, analytically: a quad is never allowed + // to rasterize below one point. Zoomed all the way out a tile is + // a fraction of a pixel, and thousands of hard-edged grains + // beating against the pixel grid is moiré banding. The on-screen + // size is clamped to a point per axis and the shrink is paid + // back as alpha: exact area coverage, at no framebuffer cost. + let want = self.tile_size * self.cam_scale + let eff = max(want, vec2(1.0, 1.0)) + let cover = (want.x * want.y) / max(eff.x * eff.y, 0.000001) + let size2 = eff / max(self.cam_scale, 0.000001) + let world_xy = self.tile_pos + (self.tile_size - size2) * 0.5 + self.geom.pos * size2 + let scr = self.view_center + (world_xy - self.cam_pos) * self.cam_scale + self.alpha_v = self.fade * cover + self.pos = self.geom.pos + self.world = self.draw_list.view_transform * vec4(scr.x, scr.y, self.draw_depth + self.draw_call.zbias, 1.) + self.vertex_pos = self.draw_pass.camera_projection * (self.draw_pass.camera_view * self.world) + } + + pixel: fn() { + let uv = self.uv0 + clamp(self.pos, vec2(0.0, 0.0), vec2(1.0, 1.0)) * (self.uv1 - self.uv0) + // BT.709 limited range, the same math the tape encoder used. + let yy = self.tex_y.sample(uv).x + let cc = self.tex_uv.sample(uv).xy + let c = (yy - 0.0627) * 1.1644 + let d = cc.x - 0.5 + let e = cc.y - 0.5 + let rgb = clamp( + vec3(c + 1.7927 * e, c - 0.2132 * d - 0.5329 * e, c + 2.1124 * d), + vec3(0.0, 0.0, 0.0), + vec3(1.0, 1.0, 1.0) + ) + let direct = self.tex_y.sample_as_bgra(uv) + let lit = rgb.mix(direct.xyz, self.rgba) + return vec4(lit * self.alpha_v, self.alpha_v) + } + } + + mod.widgets.TileGridBase = #(TileGrid::register_widget(vm)) + mod.widgets.TileGrid = set_type_default() do mod.widgets.TileGridBase{ + width: Fill + height: Fill + } +} + +#[derive(Script, ScriptHook)] +#[repr(C)] +pub struct DrawTile { + #[deref] + draw_super: DrawQuad, + #[live] + tile_pos: Vec2f, + #[live] + tile_size: Vec2f, + #[live] + rgba: f32, + #[live] + uv0: Vec2f, + #[live] + uv1: Vec2f, + #[live] + fade: f32, +} + +/// World-unit gap inside a cell: a tile fills at most this fraction. +const CELL_FILL: f32 = 0.92; +/// LOD / full-frame crossfade time. +const FADE_SECS: f64 = 0.35; +/// Resident atlas page budget (bytes of NV12). +const VRAM_BUDGET: usize = 512 * 1024 * 1024; +/// Resident full-resolution frames (bytes of BGRA + mips). +const FULL_BUDGET: usize = 512 * 1024 * 1024; +/// Above this on-screen tile size in device pixels the 128 px slot would be +/// magnified, so a frame from the picture's own pyramid is fetched. A tile +/// has to be worth several slots before it is worth a decode and megabytes +/// of texture. +const FULL_RES_PX: f64 = 320.0; +/// How long a decode that came back broken is left alone. +const RETRY_EMBARGO_SECS: f64 = 15.0; +/// Below this many tiles a rebuild is cheap enough that the uniform-only +/// glide path is not worth its bookkeeping. +const UNIFORM_ONLY_MIN_TILES: usize = 2_000; +/// A resize is one relayout, not a hundred: wait for the drag to rest. +const RESIZE_SETTLE_SECS: f64 = 0.35; + +fn vec2f(x: f32, y: f32) -> Vec2f { + Vec2f { x, y } +} + +/// The grid a set of pictures hangs on: cut once for a view aspect and an +/// item count, then held while neither moves materially. +#[derive(Clone, Copy, PartialEq, Debug, Default)] +pub struct GridPlan { + pub cols: usize, + pub rows: usize, + pub origin: Vec2f, + pub aspect: f32, +} + +/// The grid for `count` pictures in a view of this aspect, centred on the +/// world origin. +pub fn grid_plan(count: usize, aspect: f32) -> GridPlan { + let aspect = if aspect.is_finite() && aspect > 0.05 { aspect.clamp(0.35, 3.0) } else { 1.6 }; + let reserve = count.max(1); + let cols = ((reserve as f32 * aspect).sqrt().ceil() as usize).max(1); + let rows = reserve.div_ceil(cols).max(1); + GridPlan { cols, rows, origin: vec2f(-(cols as f32) * 0.5, -(rows as f32) * 0.5), aspect } +} + +/// Where rank `rank` hangs on this grid, its aspect-fit size centred in the +/// unit cell. +pub fn grid_slot(plan: &GridPlan, rank: usize, size: Vec2f) -> Vec2f { + let cols = plan.cols.max(1); + let col = (rank % cols) as f32; + let row = (rank / cols) as f32; + vec2f(plan.origin.x + col + (1.0 - size.x) * 0.5, plan.origin.y + row + (1.0 - size.y) * 0.5) +} + +/// A picture's world size inside its unit cell, keeping its own proportions. +pub fn cell_size(aspect: f32) -> Vec2f { + let a = if aspect.is_finite() && aspect > 0.0 { aspect.clamp(0.05, 20.0) } else { 1.0 }; + if a >= 1.0 { + vec2f(CELL_FILL, CELL_FILL / a) + } else { + vec2f(CELL_FILL * a, CELL_FILL) + } +} + +struct GridItem { + id: ItemId, + shard: i64, + slot: u32, + /// Fraction of the atlas slot the picture covers. + uv1: Vec2f, + title: Arc, + link: Arc, + url: Arc, + pos: Vec2f, + size: Vec2f, + aspect: f32, +} + +struct PageTex { + y: Texture, + uv: Texture, + arrived: f64, + last_used: u64, + bytes: usize, +} + +struct FullTex { + tex: Texture, + arrived: f64, + last_used: u64, + bytes: usize, + /// The long side this was decoded at, and whether anything finer exists. + px: u32, + finest: bool, +} + +#[derive(Default)] +struct ShardView { + /// The last level drawn fully opaque, so re-entering a shard does not + /// restart a fade. + shown: Option, +} + +struct Pass { + y: Texture, + uv: Texture, + fade: f32, + tiles: Vec<(usize, Vec2f, Vec2f)>, +} + +type PageKey = (i64, usize); + +/// True while `key` rests after a failed decode; a rest that is over is +/// cleared as it is passed. +fn embargoed(failed: &mut HashMap, key: K, now: f64) -> bool { + match failed.get(&key) { + Some(&until) if now < until => true, + Some(_) => { + failed.remove(&key); + false + } + None => false, + } +} + +#[derive(Clone, Debug, Default)] +pub enum TileGridAction { + #[default] + None, + /// A picture was clicked: its item id and metadata from the library. + Clicked { item: ItemId, title: String, link: String, url: String }, + /// The library opened (or failed to). Count is the pictures on the grid. + Opened { count: usize, error: Option }, +} + +#[derive(Script, ScriptHook, Widget)] +pub struct TileGrid { + #[uid] + uid: WidgetUid, + #[source] + source: ScriptObjectRef, + #[walk] + walk: Walk, + #[layout] + layout: Layout, + #[redraw] + #[live] + draw_tile: DrawTile, + /// Library root to open at startup; empty resolves the default + /// (`IMAGE_TILES_HOME`, else the nearest `local/image-tiles`). + #[live] + library: String, + + #[rust] + area: Area, + #[rust] + store: Option, + #[rust] + opened: bool, + #[rust] + items: Vec, + #[rust] + plan: Option, + #[rust] + start: Option, + #[rust] + next_frame: NextFrame, + #[rust] + last_time: f64, + #[rust] + frame: u64, + #[rust] + view_rect: Rect, + + // ── camera ── + #[rust] + cam_pos: Vec2d, + #[rust(1.0)] + cam_scale: f64, + #[rust] + cam_pos_t: Vec2d, + #[rust(1.0)] + cam_scale_t: f64, + #[rust] + cam_ready: bool, + #[rust(0.05)] + min_scale: f64, + #[rust] + zoom_anchor: Option<(Vec2d, Vec2d)>, + #[rust] + drag: Option<(Vec2d, Vec2d, bool)>, + #[rust] + user_moved: bool, + #[rust] + resize_settle_at: Option, + + // ── uniform-only glide bookkeeping ── + #[rust] + pushed_cam: Option<(Vec2d, f64)>, + #[rust] + pushed_all: bool, + #[rust] + cull_frac: f32, + #[rust] + beat_now: bool, + #[rust] + last_beat: f64, + + // ── resident textures ── + #[rust] + pages: HashMap, + #[rust] + shard_views: HashMap, + #[rust] + full: HashMap, + #[rust] + requested: HashSet, + #[rust] + full_requested: HashSet, + #[rust] + page_failed: HashMap, + #[rust] + full_failed: HashMap, +} + +impl TileGrid { + fn time(&mut self) -> f64 { + let start = *self.start.get_or_insert_with(Instant::now); + start.elapsed().as_secs_f64() + } + + /// Open a baked library: read the index, spawn the decode pool, lay the + /// grid out and ask for every shard's coarsest page so the whole set + /// shows the moment the first decodes land. + pub fn open(&mut self, cx: &mut Cx, library: Library) { + if let Some(store) = self.store.take() { + store.shutdown(); + } + self.items.clear(); + self.pages.clear(); + self.full.clear(); + self.shard_views.clear(); + self.requested.clear(); + self.full_requested.clear(); + self.page_failed.clear(); + self.full_failed.clear(); + self.plan = None; + self.opened = true; + let uid = self.widget_uid(); + let (rows, shards) = match db::read_items(&library.db_path()) { + Ok(v) => v, + Err(e) => { + log!("image-tiles: {e}"); + cx.widget_action(uid, TileGridAction::Opened { count: 0, error: Some(e) }); + return; + } + }; + self.items = rows.iter().filter_map(item_of).collect(); + let store = store::spawn(library); + for shard in shards.iter().filter(|s| s.sealed) { + store.need_page(shard.id, LEVELS - 1, 1); + self.requested.insert((shard.id, LEVELS - 1)); + } + self.store = Some(store); + self.relayout(); + self.fit_camera(); + self.cam_pos = self.cam_pos_t; + self.cam_scale = self.cam_scale_t; + cx.widget_action(uid, TileGridAction::Opened { count: self.items.len(), error: None }); + self.next_frame = cx.new_next_frame(); + self.area.redraw(cx); + } + + fn ensure_open(&mut self, cx: &mut Cx) { + if self.opened { + return; + } + let library = + if self.library.is_empty() { Library::resolve() } else { Library::new(self.library.clone()) }; + self.open(cx, library); + } + + fn view_aspect(&self) -> f32 { + if self.view_rect.size.y > 1.0 { + (self.view_rect.size.x / self.view_rect.size.y) as f32 + } else { + 1.6 + } + } + + fn relayout(&mut self) { + let plan = grid_plan(self.items.len(), self.view_aspect()); + for (rank, item) in self.items.iter_mut().enumerate() { + item.size = cell_size(item.aspect); + item.pos = grid_slot(&plan, rank, item.size); + } + self.plan = Some(plan); + } + + // ── camera ───────────────────────────────────────────────────────── + + fn view_center(&self) -> Vec2d { + self.view_rect.pos + self.view_rect.size * 0.5 + } + + fn world_to_screen(&self, p: Vec2f) -> Vec2d { + let c = self.view_center(); + Vec2d { x: (p.x as f64 - self.cam_pos.x) * self.cam_scale + c.x, y: (p.y as f64 - self.cam_pos.y) * self.cam_scale + c.y } + } + + fn screen_to_world(&self, s: Vec2d) -> Vec2d { + let c = self.view_center(); + Vec2d { x: (s.x - c.x) / self.cam_scale + self.cam_pos.x, y: (s.y - c.y) / self.cam_scale + self.cam_pos.y } + } + + fn cam_usable(&self) -> bool { + self.cam_ready + && self.cam_scale.is_finite() + && self.cam_scale > 0.0 + && self.cam_pos.x.is_finite() + && self.cam_pos.y.is_finite() + } + + /// Frame the whole grid in the viewport. + fn fit_camera(&mut self) { + let Some(plan) = self.plan else { + self.cam_scale = 1.0; + self.cam_scale_t = 1.0; + self.cam_pos = Vec2d::default(); + self.cam_pos_t = Vec2d::default(); + self.cam_ready = true; + return; + }; + if self.view_rect.size.x < 1.0 { + return; + } + let cols = plan.cols.max(1) as f64; + let rows = plan.rows.max(1) as f64; + let scale = (self.view_rect.size.x * 0.94 / (cols + 0.6)).min(self.view_rect.size.y * 0.94 / (rows + 0.8)); + let scale = scale.clamp(0.01, 6000.0); + // The fit is as far back as an auto-move goes; the wheel may pull a + // little further to see the set with room around it. + self.min_scale = scale * 0.2; + self.zoom_anchor = None; + self.cam_scale_t = scale; + self.cam_pos_t = Vec2d::default(); + self.cam_ready = true; + } + + /// Wheel zoom: the world point under the cursor stays under the cursor + /// on every frame of the smoothing, not just at the end. + fn zoom_at(&mut self, cursor: Vec2d, factor: f64) { + if !self.cam_usable() { + return; + } + let world = match self.zoom_anchor { + Some((screen, world)) if (screen - cursor).length() < 1.0 => world, + _ => self.screen_to_world(cursor), + }; + self.zoom_anchor = Some((cursor, world)); + self.cam_scale_t = (self.cam_scale_t * factor).clamp(self.min_scale, 6000.0); + let c = self.view_center(); + self.cam_pos_t = Vec2d { x: world.x - (cursor.x - c.x) / self.cam_scale_t, y: world.y - (cursor.y - c.y) / self.cam_scale_t }; + } + + /// Ease the live camera toward its target: scale in log space, and while + /// a zoom anchor stands, the anchored world point is held under its + /// screen point on every frame. Returns whether it is still moving. + fn step_camera(&mut self, dt: f64) -> bool { + if !self.cam_scale.is_finite() || self.cam_scale <= 0.0 || !self.cam_pos.x.is_finite() || !self.cam_pos.y.is_finite() { + self.cam_scale = if self.cam_scale_t.is_finite() && self.cam_scale_t > 0.0 { self.cam_scale_t } else { 1.0 }; + self.cam_pos = if self.cam_pos_t.x.is_finite() && self.cam_pos_t.y.is_finite() { self.cam_pos_t } else { Vec2d::default() }; + self.cam_scale_t = self.cam_scale; + self.cam_pos_t = self.cam_pos; + self.zoom_anchor = None; + return false; + } + let k = 1.0 - (-dt * 12.0).exp(); + let dp0 = self.cam_pos_t - self.cam_pos; + let ds = self.cam_scale_t.ln() - self.cam_scale.ln(); + let was_apart = dp0.x.abs() * self.cam_scale > 0.05 || dp0.y.abs() * self.cam_scale > 0.05 || ds.abs() > 0.0005; + self.cam_scale = (self.cam_scale.ln() + ds * k).exp(); + if let Some((screen, world)) = self.zoom_anchor { + let c = self.view_center(); + self.cam_pos = Vec2d { x: world.x - (screen.x - c.x) / self.cam_scale, y: world.y - (screen.y - c.y) / self.cam_scale }; + } else if self.drag.is_some() { + // Under a held drag the grid is BOLTED to the finger: easing here + // makes the pan trail by a rubber-band beat. + self.cam_pos = self.cam_pos_t; + } else { + let dp = self.cam_pos_t - self.cam_pos; + self.cam_pos = self.cam_pos + dp * k; + } + let dp = self.cam_pos_t - self.cam_pos; + let ds = self.cam_scale_t.ln() - self.cam_scale.ln(); + let moving = dp.x.abs() * self.cam_scale > 0.05 || dp.y.abs() * self.cam_scale > 0.05 || ds.abs() > 0.0005; + if !moving { + self.cam_pos = self.cam_pos_t; + self.cam_scale = self.cam_scale_t; + self.zoom_anchor = None; + if was_apart { + // The camera just settled: one beat re-asks LOD at rest. + self.beat_now = true; + } + } + moving + } + + fn item_at(&self, world: Vec2d) -> Option { + let plan = self.plan?; + let col = (world.x as f32 - plan.origin.x).floor(); + let row = (world.y as f32 - plan.origin.y).floor(); + if col < 0.0 || row < 0.0 || col as usize >= plan.cols { + return None; + } + let rank = row as usize * plan.cols + col as usize; + let item = self.items.get(rank)?; + let (x, y) = (world.x as f32, world.y as f32); + let slop = 0.04; + (x >= item.pos.x - slop + && x <= item.pos.x + item.size.x + slop + && y >= item.pos.y - slop + && y <= item.pos.y + item.size.y + slop) + .then_some(rank) + } + + // ── store events ─────────────────────────────────────────────────── + + fn drain_store(&mut self, cx: &mut Cx) { + let Some(store) = self.store.take() else { return }; + let mut redraw = false; + while let Ok(event) = store.events.try_recv() { + redraw = true; + match event { + StoreEvent::Page { shard, level, planes } => self.on_page(cx, shard, level, planes), + StoreEvent::Full { item, px, finest, frame } => self.on_full(cx, item, px, finest, frame), + StoreEvent::PageFailed { shard, level } => { + let until = self.time() + RETRY_EMBARGO_SECS; + self.requested.remove(&(shard, level)); + self.page_failed.insert((shard, level), until); + } + StoreEvent::FullFailed { item } => { + let until = self.time() + RETRY_EMBARGO_SECS; + self.full_requested.remove(&item); + self.full_failed.insert(item, until); + } + } + } + self.store = Some(store); + if redraw { + self.next_frame = cx.new_next_frame(); + self.area.redraw(cx); + } + } + + fn make_page(cx: &mut Cx, planes: Planes, now: f64) -> PageTex { + let (w, h) = (planes.width as usize, planes.height as usize); + let bytes = planes.y.len() + planes.uv.len(); + let y = Texture::new_with_format( + cx, + TextureFormat::VecRu8 { width: w, height: h, data: Some(planes.y), unpack_row_length: None, updated: TextureUpdated::Full }, + ); + let uv = Texture::new_with_format( + cx, + TextureFormat::VecRGu8 { + width: w / 2, + height: h / 2, + data: Some(planes.uv), + unpack_row_length: None, + updated: TextureUpdated::Full, + }, + ); + PageTex { y, uv, arrived: now, last_used: 0, bytes } + } + + fn on_page(&mut self, cx: &mut Cx, shard: i64, level: usize, planes: Planes) { + let now = self.time(); + self.requested.remove(&(shard, level)); + if planes.width != page_size(level) { + log!("image-tiles: page {shard} L{level}: unexpected size {}", planes.width); + return; + } + let page = Self::make_page(cx, planes, now); + self.pages.insert((shard, level), page); + } + + fn on_full(&mut self, cx: &mut Cx, item: ItemId, px: u32, finest: bool, frame: FullFrame) { + let now = self.time(); + self.full_requested.remove(&item); + // A frame never replaces a finer one already resident: decodes come + // back in whatever order the pool finishes them. + if let Some(have) = self.full.get(&item) { + if have.px > px { + return; + } + } + // Only a picture's FIRST frame fades in; a finer one swaps in where + // the fade already stands, or the tile bounces sharp-soft-sharp. + let arrived = self.full.get(&item).map_or(now, |have| have.arrived); + let bytes = frame.bgra.len() * 4; + let tex = Texture::new_with_format( + cx, + TextureFormat::VecMipBGRAu8_32 { + width: frame.width as usize, + height: frame.height as usize, + data: Some(frame.bgra), + max_level: Some(frame.max_level), + wrap: TextureWrap::ClampToEdge, + updated: TextureUpdated::Full, + }, + ); + self.full.insert(item, FullTex { tex, arrived, last_used: self.frame, bytes, px, finest }); + } + + fn evict(&mut self) { + let mut used: usize = self.pages.values().map(|p| p.bytes).sum(); + if used > VRAM_BUDGET { + let frame = self.frame; + // Fine levels only: the coarse tail is cheap and always kept, so + // a shard never goes fully dark. Nothing drawn this frame or + // last is touched. + let mut victims: Vec<(PageKey, u64, usize)> = self + .pages + .iter() + .filter(|((_, level), p)| *level <= 2 && p.last_used + 2 < frame) + .map(|(k, p)| (*k, p.last_used, p.bytes)) + .collect(); + victims.sort_by_key(|(_, last, _)| *last); + for (key, _, bytes) in victims { + if used <= VRAM_BUDGET { + break; + } + self.pages.remove(&key); + if let Some(view) = self.shard_views.get_mut(&key.0) { + if view.shown == Some(key.1) { + view.shown = None; + } + } + used -= bytes; + } + } + let mut full_used: usize = self.full.values().map(|f| f.bytes).sum(); + if full_used > FULL_BUDGET { + let frame = self.frame; + let mut order: Vec<(ItemId, u64, usize)> = + self.full.iter().filter(|(_, f)| f.last_used + 2 < frame).map(|(k, f)| (*k, f.last_used, f.bytes)).collect(); + order.sort_by_key(|(_, last, _)| *last); + for (key, _, bytes) in order { + if full_used <= FULL_BUDGET { + break; + } + self.full.remove(&key); + full_used -= bytes; + } + } + } + + fn push_instance(&mut self, cx: &mut Cx2d, i: usize, uv0: Vec2f, uv1: Vec2f, fade: f32, rgba: bool) { + let item = &self.items[i]; + let p = self.world_to_screen(item.pos); + let s = Vec2d { x: item.size.x as f64 * self.cam_scale, y: item.size.y as f64 * self.cam_scale }; + let dt = &mut self.draw_tile; + dt.tile_pos = item.pos; + dt.tile_size = item.size; + dt.rgba = if rgba { 1.0 } else { 0.0 }; + dt.uv0 = uv0; + dt.uv1 = uv1; + dt.fade = fade; + dt.draw_abs(cx, Rect { pos: p, size: s }); + } +} + +fn item_of(row: &ItemRow) -> Option { + let shard = row.shard?; + let slot = row.slot? as u32; + let fit = fit_dims(row.width.max(1) as u32, row.height.max(1) as u32, SLOT); + Some(GridItem { + id: row.id, + shard, + slot, + uv1: vec2f(fit.0 as f32 / SLOT as f32, fit.1 as f32 / SLOT as f32), + title: row.title.as_str().into(), + link: row.link.as_str().into(), + url: row.url.as_str().into(), + pos: Vec2f::default(), + size: vec2f(CELL_FILL, CELL_FILL), + aspect: row.aspect as f32, + }) +} + +impl Widget for TileGrid { + fn handle_event(&mut self, cx: &mut Cx, event: &Event, _scope: &mut Scope) { + if let Event::Startup = event { + self.ensure_open(cx); + } + if let Event::Signal = event { + self.drain_store(cx); + } + if let Event::Shutdown = event { + if let Some(store) = self.store.take() { + store.shutdown(); + } + } + if let Some(nf) = self.next_frame.is_event(event) { + let now_time = nf.time; + let dt = (now_time - self.last_time).clamp(0.0, 0.1); + self.last_time = now_time; + let moving = self.step_camera(dt) || self.drag.is_some(); + let now = self.time(); + if let Some(at) = self.resize_settle_at { + if now >= at { + self.resize_settle_at = None; + self.relayout(); + if !self.user_moved { + self.fit_camera(); + } + self.area.redraw(cx); + self.next_frame = cx.new_next_frame(); + } + } + let animating = self.pages.values().any(|p| now - p.arrived < FADE_SECS) + || self.full.values().any(|f| now - f.arrived < FADE_SECS); + if moving || animating || self.resize_settle_at.is_some() { + self.next_frame = cx.new_next_frame(); + } + // A settle beat exists to ask for the settled camera's tiles; + // between beats, glide frames ride the uniforms. + let beat_gap = if moving { 1.5 } else { 0.25 }; + let beat_due = self.beat_now && now - self.last_beat > beat_gap; + if beat_due { + self.last_beat = now; + } + let within_pad = self.pushed_cam.map_or(false, |(pos, scale)| { + let ratio = self.cam_scale / scale.max(1e-9); + let view_world = self.view_rect.size.x / self.cam_scale.max(1e-9); + let d = self.cam_pos - pos; + // Zoom is a uniform too: instances are world-space, so scale + // changes cost nothing until the CULL SET is wrong. With + // everything pushed any zoom-in is safe; zooming out reveals + // unpushed tiles and rebuilds past the pad. + let ratio_ok = if self.pushed_all { ratio > 0.25 && ratio < 4.0 } else { ratio > 0.9 && ratio < 4.0 }; + ratio_ok && (self.pushed_all || (d.x.abs() < view_world * 0.09 && d.y.abs() < view_world * 0.09)) + }); + if !beat_due && (moving || animating) && self.items.len() > UNIFORM_ONLY_MIN_TILES && within_pad { + // Re-present the retained draw calls under fresh camera + // uniforms: no draw_walk, no instance re-upload. + let center = self.view_center(); + let area = self.area; + let dv = &mut self.draw_tile.draw_vars; + dv.set_uniform_on_draw_list(cx, area, id!(cam_pos), &[self.cam_pos.x as f32, self.cam_pos.y as f32]); + dv.set_uniform_on_draw_list(cx, area, id!(cam_scale), &[self.cam_scale as f32]); + dv.set_uniform_on_draw_list(cx, area, id!(view_center), &[center.x as f32, center.y as f32]); + } else if moving || animating || beat_due { + self.area.redraw(cx); + } + } + match event.hits(cx, self.area) { + Hit::FingerScroll(fs) => { + self.user_moved = true; + if fs.scroll.x.abs() > fs.scroll.y.abs() * 1.2 && self.cam_usable() { + self.zoom_anchor = None; + self.cam_pos_t.x += fs.scroll.x / self.cam_scale_t; + } else { + let factor = (-fs.scroll.y * 0.0025).exp(); + self.zoom_at(fs.abs, factor); + } + self.next_frame = cx.new_next_frame(); + } + Hit::FingerDown(fd) => { + self.drag = Some((fd.abs, self.cam_pos_t, false)); + cx.set_cursor(MouseCursor::Grabbing); + } + Hit::FingerMove(fm) => { + if let Some((start, cam, moved)) = self.drag { + let delta = fm.abs - start; + let moved = moved || delta.length() > 3.0; + self.drag = Some((start, cam, moved)); + if moved && self.cam_usable() { + self.user_moved = true; + self.zoom_anchor = None; + self.cam_pos_t = Vec2d { x: cam.x - delta.x / self.cam_scale_t, y: cam.y - delta.y / self.cam_scale_t }; + self.next_frame = cx.new_next_frame(); + } + } + } + Hit::FingerUp(fu) => { + cx.set_cursor(MouseCursor::Default); + if let Some((_, _, moved)) = self.drag.take() { + if !moved { + let world = self.screen_to_world(fu.abs); + if let Some(rank) = self.item_at(world) { + let item = &self.items[rank]; + let uid = self.widget_uid(); + cx.widget_action( + uid, + TileGridAction::Clicked { + item: item.id, + title: item.title.to_string(), + link: item.link.to_string(), + url: item.url.to_string(), + }, + ); + } + } + self.next_frame = cx.new_next_frame(); + } + } + _ => {} + } + } + + fn draw_walk(&mut self, cx: &mut Cx2d, _scope: &mut Scope, walk: Walk) -> DrawStep { + cx.begin_turtle(walk, self.layout); + let rect = cx.turtle().rect(); + let first = self.view_rect.size.x < 1.0 && rect.size.x >= 1.0; + let resized = !first + && rect.size.x >= 1.0 + && (rect.size.x - self.view_rect.size.x).abs() + (rect.size.y - self.view_rect.size.y).abs() > 0.5; + self.view_rect = rect; + if resized { + self.resize_settle_at = Some(self.time() + RESIZE_SETTLE_SECS); + self.next_frame = cx.new_next_frame(); + } + if first { + self.ensure_open(cx.cx); + self.relayout(); + if !self.user_moved { + self.fit_camera(); + self.cam_pos = self.cam_pos_t; + self.cam_scale = self.cam_scale_t; + } + } + self.frame += 1; + if !self.cam_usable() || self.items.is_empty() { + cx.end_turtle_with_area(&mut self.area); + return DrawStep::done(); + } + let now = self.time(); + let frame = self.frame; + let center = self.view_center(); + self.pushed_cam = Some((self.cam_pos, self.cam_scale)); + self.draw_tile.set_uniform(cx, id!(cam_pos), &[self.cam_pos.x as f32, self.cam_pos.y as f32]); + self.draw_tile.set_uniform(cx, id!(cam_scale), &[self.cam_scale as f32]); + self.draw_tile.set_uniform(cx, id!(view_center), &[center.x as f32, center.y as f32]); + + // Visible world rectangle, padded a cell plus a twelfth of the view + // on every side: glide frames re-present this build under a camera + // that has moved a little, and the pad keeps the leading edge + // populated until the next rebuild. + let w0 = self.screen_to_world(rect.pos); + let w1 = self.screen_to_world(rect.pos + rect.size); + let (pad_x, pad_y) = ((w1.x - w0.x) as f32 * 0.12, (w1.y - w0.y) as f32 * 0.12); + let (vx0, vy0, vx1, vy1) = + (w0.x as f32 - 1.0 - pad_x, w0.y as f32 - 1.0 - pad_y, w1.x as f32 + 1.0 + pad_x, w1.y as f32 + 1.0 + pad_y); + + let mut by_shard: HashMap> = HashMap::new(); + let mut want_pages: HashMap = HashMap::new(); + let mut culled = 0usize; + let cull_off = self.cull_frac < 0.10; + for (i, item) in self.items.iter().enumerate() { + let (p, s) = (item.pos, item.size); + if p.x + s.x < vx0 || p.x > vx1 || p.y + s.y < vy0 || p.y > vy1 { + // The count is the truth either way — it decides whether the + // NEXT build culls — but the skip itself is what hysteresis + // turns off. + culled += 1; + if !cull_off { + continue; + } + } + by_shard.entry(item.shard).or_default().push(i); + } + // A build that culled nothing holds the whole grid: no amount of + // panning invalidates it, so glide frames stay uniform-only until + // the zoom changes. Below 10% culled, culling buys nothing and costs + // pan-proofness — stop culling. + self.pushed_all = culled == 0; + self.cull_frac = culled as f32 / self.items.len().max(1) as f32; + + // Level wanted for the on-screen slot size in DEVICE pixels: the + // finer neighbour, so a source pixel is never stretched over more + // than one screen pixel. + let px = self.cam_scale * cx.current_dpi_factor().max(1.0); + let lod = (SLOT as f64 / px.max(1.0)).log2(); + let desired = lod.floor().clamp(0.0, (LEVELS - 1) as f64) as usize; + + let mut passes: Vec = Vec::new(); + let mut shards: Vec = by_shard.keys().copied().collect(); + shards.sort_unstable(); + let inv = 1.0 / GRID as f32; + for key in shards { + let indices = by_shard.remove(&key).unwrap(); + let resident: Vec = (0..LEVELS).filter(|l| self.pages.contains_key(&(key, *l))).collect(); + if !self.pages.contains_key(&(key, desired)) { + // What this page would paint: every visible tile of the + // shard, at the cell size this zoom draws them. + let cell = (px * CELL_FILL as f64) * (px * CELL_FILL as f64); + want_pages.insert((key, desired), (indices.len() as f64 * cell).max(1.0) as u64); + } + if resident.is_empty() { + continue; + } + let fine = *resident + .iter() + .min_by_key(|l| (**l as i64 - desired as i64).abs() * 2 - if **l >= desired { 1 } else { 0 }) + .unwrap(); + let fade = ((now - self.pages[&(key, fine)].arrived) / FADE_SECS).clamp(0.0, 1.0) as f32; + let shown = self.shard_views.get(&key).and_then(|v| v.shown); + let tiles: Vec<(usize, Vec2f, Vec2f)> = indices + .iter() + .map(|&i| { + let item = &self.items[i]; + let (sx, sy) = ((item.slot % GRID) as f32 * inv, (item.slot / GRID) as f32 * inv); + (i, vec2f(sx, sy), vec2f(sx + item.uv1.x * inv, sy + item.uv1.y * inv)) + }) + .collect(); + if fade < 1.0 { + // Whatever was drawn before stays underneath until the new + // page is in: transitions are crossfades, never a blink. + let under = shown + .filter(|p| *p != fine && self.pages.contains_key(&(key, *p))) + .or_else(|| resident.iter().copied().filter(|l| *l != fine).max()); + if let Some(prev) = under { + let page = &self.pages[&(key, prev)]; + passes.push(Pass { y: page.y.clone(), uv: page.uv.clone(), fade: 1.0, tiles: tiles.clone() }); + self.pages.get_mut(&(key, prev)).unwrap().last_used = frame; + } + } else { + self.shard_views.entry(key).or_default().shown = Some(fine); + } + let page = self.pages.get_mut(&(key, fine)).unwrap(); + page.last_used = frame; + passes.push(Pass { y: page.y.clone(), uv: page.uv.clone(), fade, tiles }); + } + for (&key, &priority) in &want_pages { + if embargoed(&mut self.page_failed, key, now) { + continue; + } + if let Some(store) = &self.store { + if self.requested.insert(key) { + store.need_page(key.0, key.1, priority); + } + } + } + + // Coarse (opaque) passes first, then the fading fine ones on top. + passes.sort_by(|a, b| b.fade.partial_cmp(&a.fade).unwrap_or(std::cmp::Ordering::Equal)); + let mut full_needs: Vec<(ItemId, f64, u32)> = Vec::new(); + // Every visible picture that wants a frame at all, asked or not: + // this is what "still wanted" means to the store on the wants beat. + let mut full_visible: Vec<(ItemId, u64)> = Vec::new(); + let mut full_draw: Vec<(usize, Texture, f32)> = Vec::new(); + for pass in &passes { + self.draw_tile.draw_vars.set_texture(0, &pass.y); + self.draw_tile.draw_vars.set_texture(1, &pass.uv); + // One batch per pass: the pass holds its textures constant, + // which is exactly the condition for batching — thousands of + // tiles become a memcpy into one instance buffer and one call. + self.draw_tile.begin_many_instances(cx); + for &(i, uv0, uv1) in &pass.tiles { + let item_id = self.items[i].id; + let (s, p) = (self.items[i].size, self.items[i].pos); + let area = ((s.x * s.y) as f64 * self.cam_scale * self.cam_scale).max(1.0); + let tile_px = ((s.x.max(s.y)) as f64 * px).ceil().max(1.0) as u32; + let on_screen = p.x + s.x >= vx0 && p.x <= vx1 && p.y + s.y >= vy0 && p.y <= vy1; + if on_screen && tile_px as f64 >= FULL_RES_PX { + full_visible.push((item_id, area as u64)); + match self.full.get_mut(&item_id) { + Some(tex) => { + tex.last_used = frame; + // Outgrown what is held: ask finer, draw this one + // until it lands. + if !tex.finest && tile_px > tex.px && !self.full_requested.contains(&item_id) { + full_needs.push((item_id, area, tile_px)); + } + let ffade = ((now - tex.arrived) / FADE_SECS).clamp(0.0, 1.0) as f32; + if ffade >= 1.0 && pass.fade >= 1.0 { + full_draw.push((i, tex.tex.clone(), 1.0)); + continue; + } + full_draw.push((i, tex.tex.clone(), ffade)); + } + None => { + if !self.full_requested.contains(&item_id) { + full_needs.push((item_id, area, tile_px)); + } + } + } + } + self.push_instance(cx, i, uv0, uv1, pass.fade, false); + } + self.draw_tile.end_many_instances(cx); + } + full_draw.sort_by_key(|(i, ..)| *i); + full_draw.dedup_by_key(|(i, ..)| *i); + for (i, tex, ffade) in full_draw { + self.draw_tile.draw_vars.set_texture(0, &tex); + self.draw_tile.draw_vars.set_texture(1, &tex); + self.push_instance(cx, i, vec2f(0.0, 0.0), vec2f(1.0, 1.0), ffade, true); + } + + // Biggest on screen first, and only what the budget can hold: past + // it, every ask evicts something just fetched and the pool spends + // itself re-fetching. The few biggest are asked WHATEVER the budget + // says — the picture being stared at must never be the one refused; + // making room for it is eviction's job, not the ask's. + full_needs.sort_by(|a, b| b.1.total_cmp(&a.1)); + let visible_keys: HashSet = full_visible.iter().map(|(k, _)| *k).collect(); + let resident_visible: usize = self.full.iter().filter(|(k, _)| visible_keys.contains(*k)).map(|(_, f)| f.bytes).sum(); + let mut planned = resident_visible; + let level_bytes = |want: u32| { + let level = PYRAMID_LEVELS.iter().rev().find(|p| **p >= want).copied().unwrap_or(want); + (level as usize).pow(2) * 4 * 4 / 3 + }; + const ALWAYS_ASK: usize = 4; + let affordable: Vec<(ItemId, f64, u32)> = full_needs + .into_iter() + .enumerate() + .take_while(|(n, (_, _, want))| { + planned += level_bytes(*want); + *n < ALWAYS_ASK || planned <= FULL_BUDGET + }) + .map(|(_, v)| v) + .collect(); + for (key, area, want) in affordable.into_iter().take(8) { + if embargoed(&mut self.full_failed, key, now) { + continue; + } + if let Some(store) = &self.store { + if self.full_requested.insert(key) { + store.need_full(key, want, area as u64); + } + } + } + + // Every wants beat, tell the store exactly what decode work is still + // worth doing: queued work not named here has left the view and is + // dropped, and the claims on it are struck so it is askable again + // the moment it comes back. + if self.frame % 15 == 0 || self.beat_now { + self.beat_now = false; + if let Some(store) = &self.store { + let fulls: HashMap = full_visible.iter().copied().collect(); + store.wants(&want_pages, &fulls); + self.requested.retain(|k| want_pages.contains_key(k)); + self.full_requested.retain(|k| fulls.contains_key(k)); + } + } + + self.evict(); + cx.end_turtle_with_area(&mut self.area); + DrawStep::done() + } +} + +impl TileGridRef { + /// Open (or re-open) a library at `root`. + pub fn open(&self, cx: &mut Cx, root: &std::path::Path) { + if let Some(mut inner) = self.borrow_mut() { + inner.open(cx, Library::new(root)); + } + } + + /// The clicked item, if any of `actions` is ours. + pub fn clicked(&self, actions: &Actions) -> Option<(ItemId, String, String, String)> { + if let Some(item) = actions.find_widget_action(self.widget_uid()) { + if let TileGridAction::Clicked { item, title, link, url } = item.cast() { + return Some((item, title, link, url)); + } + } + None + } +} diff --git a/libs/image_tiles/src/lib.rs b/libs/image_tiles/src/lib.rs new file mode 100644 index 000000000..8f41e1a95 --- /dev/null +++ b/libs/image_tiles/src/lib.rs @@ -0,0 +1,48 @@ +//! makepad-image-tiles: a pannable, zoomable wall of downloaded pictures. +//! +//! Three pieces, one on-disk format: +//! +//! - [`tape`] — the engine: NV12 planes, the 128→8 px slot pyramid, shard +//! atlas geometry, and one hardware-HEVC intra frame per file. This is +//! the same engine the Source Library picture wall runs on; the tapes are +//! byte-compatible. +//! - The **baker** ([`bake`], and the `image-tiles-bake` binary) — reads a +//! manifest of image URLs, downloads and decodes them in RAM, and bakes a +//! library directory: atlas tapes, per-picture full frames and zoom +//! pyramids, and a small SQLite index ([`db`]). No JPEGs or PNGs are kept +//! on disk. Point it (or an AI, or your own script) at any list of URLs. +//! - The **viewer** ([`grid::TileGrid`]) — a widget that opens a baked +//! library and draws every picture on one pannable, zoomable grid: +//! instanced tiles batched per atlas page, camera glides on uniforms, +//! continuous LOD with crossfades, and full-resolution promotion under +//! byte budgets. +//! +//! Quickest start: +//! ```text +//! cargo run -p makepad-image-tiles --release --bin image-tiles-bake -- \ +//! --root local/image-tiles examples/image_tiles/manifest.tsv +//! cargo run -p makepad-example-image-tiles --release +//! ``` +//! +//! Note: baking requires the platform's single-intra-frame hardware encoder +//! (VideoToolbox — macOS today); viewing requires hardware decode. + +pub use makepad_widgets; + +pub mod bake; +pub mod db; +pub mod grid; +pub mod library; +pub mod store; +pub mod tape; + +pub use grid::{TileGrid, TileGridAction}; +pub use library::Library; + +use makepad_widgets::ScriptVm; + +/// Register the TileGrid widget. A host calls this once, after +/// `makepad_widgets::script_mod`, before its own UI module. +pub fn script_mod(vm: &mut ScriptVm) { + crate::grid::script_mod(vm); +} diff --git a/libs/image_tiles/src/library.rs b/libs/image_tiles/src/library.rs new file mode 100644 index 000000000..88a65a4a4 --- /dev/null +++ b/libs/image_tiles/src/library.rs @@ -0,0 +1,127 @@ +//! Where a baked tile library lives on disk. +//! +//! One directory is one library: +//! - `library.sqlite` — the index: items and shard bookkeeping ([`crate::db`]). +//! - `tapes//L.mov` — one HEVC intra frame per file: the atlas +//! page of a shard at one level. Level 0 is a 4096 px frame, level 4 a +//! 256 px one; one hardware decode fills a whole atlas level. +//! - `full/.mov` — the picture at the highest resolution it was +//! fetched at (capped to [`crate::tape::FULL_MAX_PX`]), one intra frame. +//! - `pyr/-.mov` — the picture's pre-cut zoom levels, named by +//! long side, so a zoom is one small hardware decode of the level that +//! fits, never the archival frame plus a rescale. +//! - `tmp/` — scratch for the baker. + +use crate::tape::{read_frame, Planes, PYRAMID_LEVELS}; +use std::path::{Path, PathBuf}; + +pub type ItemId = i64; + +#[derive(Clone, Debug)] +pub struct Library { + pub root: PathBuf, +} + +impl Library { + pub fn new(root: impl Into) -> Library { + Library { root: root.into() } + } + + /// Resolve a library root the way apps launched from a source tree + /// expect: `IMAGE_TILES_HOME` wins, else the nearest `local/` walking up + /// from the working directory gets a `local/image-tiles`, else + /// `./local/image-tiles`. + pub fn resolve() -> Library { + if let Ok(p) = std::env::var("IMAGE_TILES_HOME") { + if !p.trim().is_empty() { + return Library { root: PathBuf::from(p.trim()) }; + } + } + let mut dir = std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")); + for _ in 0..5 { + let candidate = dir.join("local"); + if candidate.is_dir() { + return Library { root: candidate.join("image-tiles") }; + } + if !dir.pop() { + break; + } + } + Library { root: PathBuf::from("local/image-tiles") } + } + + pub fn ensure_dirs(&self) -> Result<(), String> { + for sub in ["tapes", "full", "pyr", "tmp"] { + std::fs::create_dir_all(self.root.join(sub)).map_err(|e| format!("create {sub}: {e}"))?; + } + Ok(()) + } + + pub fn db_path(&self) -> PathBuf { + self.root.join("library.sqlite") + } + + pub fn tape_path(&self, shard: i64, level: usize) -> PathBuf { + self.root.join("tapes").join(format!("{shard:05}")).join(format!("L{level}.mov")) + } + + pub fn full_path(&self, item: ItemId) -> PathBuf { + self.root.join("full").join(format!("{item}.mov")) + } + + /// One level of a picture's on-disk pyramid, named by its long side. + pub fn pyramid_path(&self, item: ItemId, px: u32) -> PathBuf { + self.root.join("pyr").join(format!("{item}-{px}.mov")) + } + + pub fn exists(&self) -> bool { + self.db_path().is_file() + } +} + +/// Mark a picture as needing no pyramid levels at all (already smaller than +/// every level), so a later pass skips it: an empty file at level "0". +pub fn mark_no_pyramid(library: &Library, id: ItemId) { + let path = library.pyramid_path(id, 0); + if let Some(dir) = path.parent() { + let _ = std::fs::create_dir_all(dir); + } + let _ = std::fs::write(path, []); +} + +/// The frame a viewer should draw for a picture wanted at `want_px` across: +/// the smallest pyramid level that still covers the ask, falling back to the +/// archival frame only when nothing smaller will do. The second value says +/// whether this is as fine as it gets — a viewer that cannot tell will never +/// ask for sharper. +pub fn display_frame(library: &Library, item: ItemId, want_px: u32) -> Result<(Planes, bool), String> { + let mut pick: Option = None; + for px in PYRAMID_LEVELS { + if px >= want_px && library.pyramid_path(item, px).exists() { + pick = Some(px); + } + } + match pick { + Some(px) => { + let finer = PYRAMID_LEVELS.iter().any(|p| *p > px && library.pyramid_path(item, *p).exists()) + || library.full_path(item).exists(); + read_frame(&library.pyramid_path(item, px)).map(|p| (p, !finer)) + } + None => read_frame(&library.full_path(item)).map(|p| (p, true)), + } +} + +/// Best-effort file check used by tools; the viewer trusts the database. +pub fn tape_exists(library: &Library, shard: i64) -> bool { + (0..crate::tape::LEVELS).all(|l| library.tape_path(shard, l).is_file()) +} + +pub fn tmp_path(library: &Library, item: ItemId, ext: &str) -> PathBuf { + library.root.join("tmp").join(format!("{item}-{}.{ext}", std::process::id())) +} + +impl Library { + pub fn as_path(&self) -> &Path { + &self.root + } +} diff --git a/libs/image_tiles/src/store.rs b/libs/image_tiles/src/store.rs new file mode 100644 index 000000000..5e32565cf --- /dev/null +++ b/libs/image_tiles/src/store.rs @@ -0,0 +1,193 @@ +//! The viewer's decode pool: a baked library is read-only, so serving the +//! grid is nothing but hardware decodes, ranked by how much screen each one +//! would paint. +//! +//! There is no coordinator thread. The widget pushes wants straight onto a +//! shared priority queue; a handful of workers pop the biggest first, decode +//! on VideoToolbox, and send the result back over a [`ToUISender`] (which +//! raises the UI signal, so the widget drains on `Event::Signal`). A pan +//! that leaves work behind calls [`StoreHandle::wants`] with the whole +//! current truth: queued decodes not named are dropped, the rest take their +//! fresh weights. + +use crate::library::{display_frame, ItemId, Library}; +use crate::tape::{full_frame, read_frame, FullFrame, Planes}; +use makepad_widgets::makepad_platform::thread::{ToUIReceiver, ToUISender}; +use std::collections::HashMap; +use std::sync::{Arc, Condvar, Mutex}; +use std::time::Duration; + +pub enum StoreEvent { + /// A sealed shard's page at one level, hardware decoded from tape. + Page { shard: i64, level: usize, planes: Planes }, + /// A picture at full resolution, mipmapped. + Full { item: ItemId, px: u32, finest: bool, frame: FullFrame }, + /// A page decode that did not come back; without this the widget's + /// "already asked" mark would stand for ever. + PageFailed { shard: i64, level: usize }, + /// A full-frame decode that did not come back; same contract. + FullFailed { item: ItemId }, +} + +enum Work { + DecodePage { shard: i64, level: usize }, + DecodeFull { item: ItemId, px: u32 }, +} + +struct QueueState { + /// (priority, work): the pool serves the biggest first, newest on a tie. + immediate: Vec<(u64, Work)>, + closed: bool, +} + +struct WorkQueue { + state: Mutex, + cv: Condvar, +} + +impl WorkQueue { + fn new() -> WorkQueue { + WorkQueue { state: Mutex::new(QueueState { immediate: Vec::new(), closed: false }), cv: Condvar::new() } + } + + fn push(&self, work: Work, priority: u64) { + self.state.lock().unwrap().immediate.push((priority, work)); + self.cv.notify_one(); + } + + fn pop(&self) -> Option { + let mut s = self.state.lock().unwrap(); + loop { + if s.closed { + return None; + } + // A linear scan: the queue holds at most a screenful of asks + // between two wants messages, and a decode costs six orders of + // magnitude more than walking it. + let mut best: Option<(usize, u64)> = None; + for (i, (pri, _)) in s.immediate.iter().enumerate() { + if best.map_or(true, |(_, bp)| *pri >= bp) { + best = Some((i, *pri)); + } + } + if let Some((i, _)) = best { + return Some(s.immediate.swap_remove(i).1); + } + s = self.cv.wait_timeout(s, Duration::from_millis(100)).unwrap().0; + } + } + + /// Make the queue match what is on screen right now: queued decodes not + /// in the want maps are dropped, the rest take their fresh weights. + /// Returns what was dropped so the caller can strike its own claims. + fn retarget( + &self, + pages: &HashMap<(i64, usize), u64>, + fulls: &HashMap, + ) -> (Vec<(i64, usize)>, Vec) { + let mut s = self.state.lock().unwrap(); + let mut dropped_pages = Vec::new(); + let mut dropped_fulls = Vec::new(); + s.immediate.retain_mut(|(pri, w)| match w { + Work::DecodePage { shard, level } => match pages.get(&(*shard, *level)) { + Some(p) => { + *pri = *p; + true + } + None => { + dropped_pages.push((*shard, *level)); + false + } + }, + Work::DecodeFull { item, .. } => match fulls.get(item) { + Some(p) => { + *pri = *p; + true + } + None => { + dropped_fulls.push(*item); + false + } + }, + }); + (dropped_pages, dropped_fulls) + } + + fn close(&self) { + let mut s = self.state.lock().unwrap(); + s.closed = true; + s.immediate.clear(); + drop(s); + self.cv.notify_all(); + } +} + +pub struct StoreHandle { + queue: Arc, + pub events: ToUIReceiver, + pub library: Library, +} + +impl StoreHandle { + pub fn need_page(&self, shard: i64, level: usize, priority: u64) { + self.queue.push(Work::DecodePage { shard, level }, priority); + } + + pub fn need_full(&self, item: ItemId, px: u32, priority: u64) { + self.queue.push(Work::DecodeFull { item, px }, priority); + } + + /// The whole current want: everything queued and not named here is + /// dropped. Returns (pages, fulls) that were dropped, so the caller can + /// strike its "already asked" marks for exactly those. + pub fn wants( + &self, + pages: &HashMap<(i64, usize), u64>, + fulls: &HashMap, + ) -> (Vec<(i64, usize)>, Vec) { + self.queue.retarget(pages, fulls) + } + + /// A read-only store has nothing to flush: closing the queue is the + /// whole shutdown, and the workers exit on their next pop. + pub fn shutdown(&self) { + self.queue.close(); + } +} + +/// Bring up the decode pool over a baked library. +pub fn spawn(library: Library) -> StoreHandle { + let queue = Arc::new(WorkQueue::new()); + let events = ToUIReceiver::default(); + let workers = std::thread::available_parallelism().map_or(4, |n| (n.get() / 2).clamp(2, 8)); + for i in 0..workers { + let queue = queue.clone(); + let events: ToUISender = events.sender(); + let library = library.clone(); + let _ = std::thread::Builder::new() + .name(format!("tiles-decode-{i}")) + .spawn(move || worker(library, queue, events)); + } + StoreHandle { queue, events, library } +} + +fn worker(library: Library, queue: Arc, events: ToUISender) { + while let Some(work) = queue.pop() { + let event = match work { + Work::DecodePage { shard, level } => match read_frame(&library.tape_path(shard, level)) { + Ok(planes) => StoreEvent::Page { shard, level, planes }, + Err(_) => StoreEvent::PageFailed { shard, level }, + }, + Work::DecodeFull { item, px } => match display_frame(&library, item, px) { + Ok((planes, finest)) => { + let got = planes.width.max(planes.height); + StoreEvent::Full { item, px: got, finest, frame: full_frame(&planes) } + } + Err(_) => StoreEvent::FullFailed { item }, + }, + }; + if events.send(event).is_err() { + break; + } + } +} diff --git a/libs/image_tiles/src/tape.rs b/libs/image_tiles/src/tape.rs new file mode 100644 index 000000000..bd7c877d1 --- /dev/null +++ b/libs/image_tiles/src/tape.rs @@ -0,0 +1,356 @@ +//! The tile-tape engine: pixels in, hardware-HEVC tapes out, and back. +//! +//! Nothing here knows about downloads, databases or widgets — these are the +//! primitives both the baker and any viewer build on, and the same ones the +//! Source Library app runs its wall with: +//! +//! - NV12 [`Planes`] with BT.709 limited-range conversion, so a round trip +//! through HEVC is colour-neutral. +//! - The slot pyramid: one picture fitted into a 128 px atlas slot and +//! halved down to 8 px ([`build_pyramid`]), and the shard atlas geometry +//! that packs 1024 slots into a 32x32 grid per level. +//! - One HEVC intra frame per file ([`write_frame`] / [`read_frame`]): +//! hardware encoded, hardware decoded, written atomically. An atlas level +//! is one such frame; a full-resolution picture is another. +//! - The BGRA mip chain a full-resolution frame becomes on its way to a +//! `VecMipBGRAu8_32` texture ([`full_frame`]). +//! +//! No JPEGs or PNGs ever touch the disk: sources are decoded in memory and +//! kept only as hardware-decodable HEVC. + +use makepad_video::{encode_intra_frame_mp4, nv12, VideoFileCodec, VideoFileEncoderOptions}; +use makepad_video::VideoFileDecoder; +use makepad_widgets::ImageBuffer; +use std::path::Path; + +/// Atlas slot side in pixels at level 0. +pub const SLOT: u32 = 128; +/// Slots per shard side: a shard is a GRID x GRID block of slots. +pub const GRID: u32 = 32; +/// Items per shard. +pub const SHARD_CAP: u32 = GRID * GRID; +/// Pyramid levels per shard: 128, 64, 32, 16, 8 px per slot. +pub const LEVELS: usize = 5; + +/// HEVC intra quality for atlas pages / full pictures, bits per pixel per +/// frame. Shared so every writer fills byte-compatible tapes. +pub const PAGE_BPP: f64 = 1.2; +pub const FULL_BPP: f64 = 1.6; + +/// The long sides a picture's on-disk zoom pyramid is cut to, largest first. +/// Below the smallest of these the atlas tapes already carry the picture. +pub const PYRAMID_LEVELS: [u32; 4] = [4096, 2048, 1024, 512]; + +/// The largest full-resolution frame kept on disk. +pub const FULL_MAX_PX: u32 = 8192; + +pub fn page_size(level: usize) -> u32 { + (GRID * SLOT) >> level +} + +pub fn slot_size(level: usize) -> u32 { + SLOT >> level +} + +pub fn slot_origin(slot: u32, level: usize) -> (u32, u32) { + let s = slot_size(level); + ((slot % GRID) * s, (slot / GRID) * s) +} + +/// NV12 planes: `y` is width*height, `uv` is interleaved CbCr at half +/// resolution (width * height/2 bytes). Dimensions are even. +#[derive(Clone, Debug, PartialEq)] +pub struct Planes { + pub width: u32, + pub height: u32, + pub y: Vec, + pub uv: Vec, +} + +impl Planes { + pub fn black(width: u32, height: u32) -> Planes { + let (w, h) = (width as usize, height as usize); + Planes { width, height, y: vec![0; w * h], uv: vec![128; w * h / 2] } + } + + pub fn from_nv12(width: u32, height: u32, data: &[u8]) -> Result { + let (w, h) = (width as usize, height as usize); + if data.len() < w * h * 3 / 2 { + return Err(format!("nv12 frame too short: {} < {}", data.len(), w * h * 3 / 2)); + } + Ok(Planes { width, height, y: data[..w * h].to_vec(), uv: data[w * h..w * h * 3 / 2].to_vec() }) + } + + pub fn to_nv12(&self) -> Vec { + let mut out = Vec::with_capacity(self.y.len() + self.uv.len()); + out.extend_from_slice(&self.y); + out.extend_from_slice(&self.uv); + out + } + + /// BT.709 limited range, the same math the tape decoder and the tile + /// shader use, so a round trip through HEVC is colour-neutral. + pub fn from_rgba(rgba: &[u8], width: u32, height: u32) -> Planes { + debug_assert!(width % 2 == 0 && height % 2 == 0); + let mut nv12 = Vec::new(); + nv12::rgbx_to_nv12(rgba, width, height, 4, &mut nv12); + Planes::from_nv12(width, height, &nv12).expect("nv12 size") + } + + pub fn to_rgba(&self) -> Vec { + let mut bgra = Vec::new(); + nv12::nv12_to_bgra_u32(&self.to_nv12(), self.width, self.height, &mut bgra); + let mut out = Vec::with_capacity(bgra.len() * 4); + for p in bgra { + out.extend_from_slice(&[(p >> 16) as u8, (p >> 8) as u8, p as u8, 255]); + } + out + } + + /// Copy `src` into this plane set at even luma coordinates. + pub fn blit(&mut self, src: &Planes, x: u32, y: u32) { + debug_assert!(x % 2 == 0 && y % 2 == 0); + let (w, sw, sh) = (self.width as usize, src.width as usize, src.height as usize); + if x as usize + sw > w || y as usize + sh > self.height as usize { + return; + } + for row in 0..sh { + let dst = (y as usize + row) * w + x as usize; + self.y[dst..dst + sw].copy_from_slice(&src.y[row * sw..row * sw + sw]); + } + for row in 0..sh / 2 { + let dst = (y as usize / 2 + row) * w + x as usize; + self.uv[dst..dst + sw].copy_from_slice(&src.uv[row * sw..row * sw + sw]); + } + } + + /// Area-average downscale straight on the planes. + pub fn downscale(&self, dw: u32, dh: u32) -> Planes { + let dw = dw.max(2) & !1; + let dh = dh.max(2) & !1; + Planes { + width: dw, + height: dh, + y: box_downscale(&self.y, self.width, self.height, 1, dw, dh), + uv: box_downscale(&self.uv, self.width / 2, self.height / 2, 2, dw / 2, dh / 2), + } + } +} + +/// Exact box filter: each destination pixel averages its source rectangle. +pub fn box_downscale(src: &[u8], sw: u32, sh: u32, channels: usize, dw: u32, dh: u32) -> Vec { + let (sw, sh, dw, dh) = (sw as usize, sh as usize, dw as usize, dh as usize); + let mut out = vec![0u8; dw * dh * channels]; + if sw == 0 || sh == 0 || dw == 0 || dh == 0 { + return out; + } + for dy in 0..dh { + let y0 = dy * sh / dh; + let y1 = ((dy + 1) * sh / dh).max(y0 + 1).min(sh); + for dx in 0..dw { + let x0 = dx * sw / dw; + let x1 = ((dx + 1) * sw / dw).max(x0 + 1).min(sw); + let n = ((y1 - y0) * (x1 - x0)) as u32; + for c in 0..channels { + let mut sum = 0u32; + for y in y0..y1 { + let row = y * sw; + for x in x0..x1 { + sum += src[(row + x) * channels + c] as u32; + } + } + out[(dy * dw + dx) * channels + c] = ((sum + n / 2) / n) as u8; + } + } + } + out +} + +/// Fit `w x h` inside `max x max` keeping aspect; even dimensions, >= 2. +pub fn fit_dims(w: u32, h: u32, max: u32) -> (u32, u32) { + let (w, h) = (w.max(1) as f64, h.max(1) as f64); + let scale = (max as f64 / w).min(max as f64 / h).min(1.0); + let fw = ((w * scale).round() as u32).clamp(2, max) & !1; + let fh = ((h * scale).round() as u32).clamp(2, max) & !1; + (fw.max(2), fh.max(2)) +} + +/// One item's atlas slot at every level: the fitted picture sits at the +/// top-left of a black slot; `fit` is its level-0 size in pixels. +#[derive(Clone, Debug, PartialEq)] +pub struct TilePyramid { + pub fit: (u32, u32), + pub levels: Vec, +} + +/// Decode PNG/JPEG (or whatever else the magic bytes say) to an ImageBuffer. +pub fn decode_image(bytes: &[u8]) -> Result { + let is_png = bytes.starts_with(&[0x89, b'P', b'N', b'G']); + let is_jpg = bytes.starts_with(&[0xff, 0xd8]); + let result = if is_png { + ImageBuffer::from_png(bytes) + } else if is_jpg { + ImageBuffer::from_jpg(bytes) + } else { + ImageBuffer::from_jpg(bytes).or_else(|_| ImageBuffer::from_png(bytes)) + }; + result.map_err(|e| format!("{e:?}")) +} + +pub fn image_to_rgba(img: &ImageBuffer) -> Vec { + let mut out = Vec::with_capacity(img.data.len() * 4); + for p in &img.data { + out.extend_from_slice(&[(p >> 16) as u8, (p >> 8) as u8, *p as u8, 255]); + } + out +} + +/// Downscale a picture into its slot pyramid: level 0 is the picture fitted +/// into 128 px, every further level halves it. +pub fn build_pyramid(rgba: &[u8], width: u32, height: u32) -> TilePyramid { + let fit = fit_dims(width, height, SLOT); + let fitted = box_downscale(rgba, width, height, 4, fit.0, fit.1); + let mut level0 = Planes::black(SLOT, SLOT); + level0.blit(&Planes::from_rgba(&fitted, fit.0, fit.1), 0, 0); + let mut levels = vec![level0]; + for level in 1..LEVELS { + let prev = &levels[level - 1]; + levels.push(prev.downscale(slot_size(level), slot_size(level))); + } + TilePyramid { fit, levels } +} + +/// The H265 options a given size and quality ask for; public because apps +/// with their own encode paths (clips, streams) size bitrates the same way. +pub fn encoder_options(width: u32, height: u32, fps: u32, bpp: f64, keyframe_only: bool) -> VideoFileEncoderOptions { + let bitrate = (width as f64 * height as f64 * bpp * fps as f64).clamp(200_000.0, 800_000_000.0) as u32; + VideoFileEncoderOptions { + codec: VideoFileCodec::H265, + width, + height, + fps_num: fps, + fps_den: 1, + video_bitrate_bps: bitrate, + audio: None, + keyframe_only, + } +} + +/// One HEVC intra frame in its own container, written atomically. +pub fn write_frame(path: &Path, planes: &Planes, bpp: f64) -> Result<(), String> { + if let Some(dir) = path.parent() { + std::fs::create_dir_all(dir).map_err(|e| format!("mkdir: {e}"))?; + } + let options = encoder_options(planes.width, planes.height, 30, bpp, true); + // One still needs none of AVAssetWriter's machinery: the session encodes + // it and we write the container ourselves. + let mp4 = encode_intra_frame_mp4( + &planes.to_nv12(), + planes.width, + planes.height, + 30, + options.video_bitrate_bps, + options.codec, + ) + .map_err(|e| format!("encode: {e}"))?; + let tmp = path.with_extension("part"); + std::fs::write(&tmp, &mp4).map_err(|e| format!("write tmp: {e}"))?; + std::fs::rename(&tmp, path).map_err(|e| format!("rename: {e}")) +} + +/// The first frame of a container, hardware decoded. +pub fn read_frame(path: &Path) -> Result { + let text = path.to_string_lossy().to_string(); + let mut dec = VideoFileDecoder::open(&text).map_err(|e| format!("open {text}: {e:?}"))?; + let frame = dec + .next_frame() + .map_err(|e| format!("decode {text}: {e:?}"))? + .ok_or_else(|| format!("no frame in {text}"))?; + Planes::from_nv12(frame.width, frame.height, &frame.nv12) +} + +/// A full-resolution picture as a BGRA mip chain, ready for a +/// `VecMipBGRAu8_32` texture: level 0 first, each level halving, so the GPU +/// samples it trilinearly and it stays sharp at any zoom. +pub struct FullFrame { + pub width: u32, + pub height: u32, + pub bgra: Vec, + pub max_level: usize, +} + +/// Decoded NV12 -> BGRA with a full mip chain (2x2 box per level). +pub fn full_frame(planes: &Planes) -> FullFrame { + let (w, h) = (planes.width as usize, planes.height as usize); + let mut level0 = Vec::new(); + nv12::nv12_to_bgra_u32(&planes.to_nv12(), planes.width, planes.height, &mut level0); + let mut chain = level0; + let (mut lw, mut lh) = (w, h); + let mut max_level = 0usize; + let mut src_start = 0usize; + while lw > 1 || lh > 1 { + let (nw, nh) = ((lw / 2).max(1), (lh / 2).max(1)); + let src = &chain[src_start..src_start + lw * lh]; + let mut next = Vec::with_capacity(nw * nh); + for y in 0..nh { + let y0 = (y * 2).min(lh - 1); + let y1 = (y * 2 + 1).min(lh - 1); + for x in 0..nw { + let x0 = (x * 2).min(lw - 1); + let x1 = (x * 2 + 1).min(lw - 1); + let px = [src[y0 * lw + x0], src[y0 * lw + x1], src[y1 * lw + x0], src[y1 * lw + x1]]; + let mut acc = [0u32; 4]; + for p in px { + acc[0] += (p >> 24) & 0xff; + acc[1] += (p >> 16) & 0xff; + acc[2] += (p >> 8) & 0xff; + acc[3] += p & 0xff; + } + next.push(((acc[0] / 4) << 24) | ((acc[1] / 4) << 16) | ((acc[2] / 4) << 8) | (acc[3] / 4)); + } + } + src_start += lw * lh; + chain.extend_from_slice(&next); + lw = nw; + lh = nh; + max_level += 1; + } + FullFrame { width: planes.width, height: planes.height, bgra: chain, max_level } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn geometry() { + assert_eq!(page_size(0), 4096); + assert_eq!(page_size(4), 256); + assert_eq!(slot_size(4), 8); + assert_eq!(slot_origin(0, 0), (0, 0)); + assert_eq!(slot_origin(33, 0), (128, 128)); + assert_eq!(slot_origin(33, 2), (32, 32)); + assert_eq!(slot_origin(1023, 4), (31 * 8, 31 * 8)); + } + + #[test] + fn fits() { + assert_eq!(fit_dims(1000, 500, 128), (128, 64)); + assert_eq!(fit_dims(500, 1000, 128), (64, 128)); + assert_eq!(fit_dims(60, 30, 128), (60, 30)); + assert_eq!(fit_dims(129, 129, 128), (128, 128)); + assert_eq!(fit_dims(1, 1, 128), (2, 2)); + } + + #[test] + fn pyramid_shape() { + let rgba = vec![200u8; 640 * 480 * 4]; + let p = build_pyramid(&rgba, 640, 480); + assert_eq!(p.fit, (128, 96)); + assert_eq!(p.levels.len(), LEVELS); + for (l, planes) in p.levels.iter().enumerate() { + assert_eq!(planes.width, slot_size(l)); + assert_eq!(planes.height, slot_size(l)); + } + } +} From c18b7f4169cc1f951ed3d3403aaad8ae19c243e4 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 20:20:04 +0200 Subject: [PATCH 006/417] game brief: railways are one call too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The verbs existed with the right doc strings, but the model reads the brief, not the verb table — and the brief's ONE CALL list never said railway, so it hand-placed track pieces, horrendously. Now it says it, with the two-line essential shape. Co-Authored-By: Claude Fable 5 --- libs/asset/chat/context/game.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libs/asset/chat/context/game.md b/libs/asset/chat/context/game.md index f09e23502..49b51ecab 100644 --- a/libs/asset/chat/context/game.md +++ b/libs/asset/chat/context/game.md @@ -72,7 +72,7 @@ from boxes; never make it a plain game.model (that is scenery). A "small car" = `world.spawn({model: "...", scale: 0.5})` or `scale: "small"` — it stays driveable; `world.place` makes static scenery. -CITIES, VILLAGES, RACETRACKS, ROADS, FORESTS AND DUNGEONS ARE ONE CALL; +CITIES, VILLAGES, RACETRACKS, RAILWAYS, ROADS, FORESTS AND DUNGEONS ARE ONE CALL; never hand-place their tiles. They are deterministic from seed: - `game.city({seed, size, density})`, `game.village({seed, size})`, and `game.dungeon({kit, extent, seed})` build complete layouts. @@ -87,6 +87,14 @@ never hand-place their tiles. They are deterministic from seed: let r = game.car({model: "kenney/car-kit/race", color: #4488ff}) game.place(r, t.slots[1]) game.autodrive(r, {points: t.waypoints, pace: 0.85}) +- `game.traintrack({seed, size})` lays a complete closed RAILWAY from the + train kit — never hand-place track pieces (the joins will not line up; + the generator's are seamless). `game.train({cars})` puts a driveable + locomotive with trailing carriages on it: board it like any vehicle, + drive with forward/back only, it cannot leave the rails. A railway's + essential shape is: + game.traintrack({seed: 3, size: 90}) + game.train({cars: 4}) game.race({laps: 3}) game.player_character({pos: t.start, model: "kenney/mini-characters/character-male-b"}) Every car gets a different `t.slots` entry; spawn the player at `t.start`. From ea50c779706740a2417a08db0bf372c2eb473185 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 20:36:55 +0200 Subject: [PATCH 007/417] chat_ui: the feed's session gets its profile brief back Same orphaning as the sandbox: context::assemble had no caller post-P8, so gen/vj sessions ran brief-less. The executor's capability doc leads with the assembled profile layer. Co-Authored-By: Claude Fable 5 --- libs/chat_ui/src/feed.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libs/chat_ui/src/feed.rs b/libs/chat_ui/src/feed.rs index 5ffca09a9..661e68e91 100644 --- a/libs/chat_ui/src/feed.rs +++ b/libs/chat_ui/src/feed.rs @@ -248,7 +248,14 @@ struct AppExec { impl ToolExecutor for AppExec { fn capability_doc(&mut self) -> String { - self.inner.capability_doc() + // The profile brief (context::assemble) was orphaned when the + // session moved in-process (aicore P8) — the broker used to + // prepend it, so no in-app executor did. It rides in front of the + // live capability text, profile-matched. + let mut doc = makepad_asset_chat::context::assemble(self.profile, ""); + doc.push('\n'); + doc.push_str(&self.inner.capability_doc()); + doc } fn tool_definitions(&mut self) -> Vec { From 895b9a71c30f07a80a3663c87cbf183cb88cd25e Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 20:51:32 +0200 Subject: [PATCH 008/417] particles: an emitter can ride a body's own frame MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EmitterAnchor::EntityLocal carries an offset that yaws with the entity — a locomotive's chimney keeps its smoke over the funnel through every corner. The step lookup resolves (position, yaw) instead of position. Co-Authored-By: Claude Fable 5 --- libs/render/src/particles.rs | 29 +++++++++++++++++++++-------- libs/sim/src/particles.rs | 4 ++++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/libs/render/src/particles.rs b/libs/render/src/particles.rs index de783702a..23eb061fd 100644 --- a/libs/render/src/particles.rs +++ b/libs/render/src/particles.rs @@ -169,16 +169,27 @@ impl ParticleSystem { }); } - /// Step every emitter and particle. `entity_pos` resolves entity-anchored - /// emitters — the host passes a lookup into the world it is drawing, so - /// particles follow objects without the sim carrying particle state. - pub fn step(&mut self, dt: f32, entity_pos: &dyn Fn(u64) -> Option) { + /// Step every emitter and particle. `entity_pose` resolves entity-anchored + /// emitters to (position, yaw) — the host passes a lookup into the world + /// it is drawing, so particles follow objects without the sim carrying + /// particle state, and a local-offset anchor turns with its body. + pub fn step(&mut self, dt: f32, entity_pose: &dyn Fn(u64) -> Option<(Vec3f, f32)>) { // Emit. let mut pending: Vec<(Vec3f, ParticleSpec, usize)> = Vec::new(); for e in self.emitters.iter_mut() { let Some(at) = (match e.anchor { EmitterAnchor::Point(p) => Some(p), - EmitterAnchor::Entity(id) => entity_pos(id), + EmitterAnchor::Entity(id) => entity_pose(id).map(|(p, _)| p), + EmitterAnchor::EntityLocal(id, off) => entity_pose(id).map(|(p, yaw)| { + // The sim's heading convention: yaw 0 faces -Z, ccw + // positive. Rotate the local offset into world. + let (sy, cy) = (yaw.sin(), yaw.cos()); + vec3f( + p.x + off.x * cy - off.z * sy, + p.y + off.y, + p.z + off.x * sy + off.z * cy, + ) + }), }) else { continue; }; @@ -192,7 +203,9 @@ impl ParticleSystem { // Entity-anchored emitters whose entity is gone stop emitting; drop // them so a long game does not accumulate dead emitters. self.emitters.retain(|e| match e.anchor { - EmitterAnchor::Entity(id) => entity_pos(id).is_some(), + EmitterAnchor::Entity(id) | EmitterAnchor::EntityLocal(id, _) => { + entity_pose(id).is_some() + } EmitterAnchor::Point(_) => true, }); for (at, spec, n) in pending { @@ -235,7 +248,7 @@ impl ParticleSystem { mod tests { use super::*; - fn no_entities(_: u64) -> Option { + fn no_entities(_: u64) -> Option<(Vec3f, f32)> { None } @@ -318,7 +331,7 @@ mod tests { anchor: EmitterAnchor::Entity(42), spec: s, }]); - let at_x10 = |id: u64| (id == 42).then_some(vec3f(10.0, 0.0, 0.0)); + let at_x10 = |id: u64| (id == 42).then_some((vec3f(10.0, 0.0, 0.0), 0.0)); ps.step(1.0 / 60.0, &at_x10); assert_eq!(ps.live_count(), 1); assert!((ps.instances()[0].pos.x - 10.0).abs() < 0.5); diff --git a/libs/sim/src/particles.rs b/libs/sim/src/particles.rs index 29dd8d24f..4ea21dc0d 100644 --- a/libs/sim/src/particles.rs +++ b/libs/sim/src/particles.rs @@ -48,6 +48,10 @@ impl ParticleKind { #[derive(Clone, Copy, Debug, PartialEq)] pub enum EmitterAnchor { Entity(u64), + /// An entity plus an offset in ITS OWN frame — the offset yaws with the + /// body, so a locomotive's chimney smoke stays over the chimney through + /// every corner. + EntityLocal(u64, Vec3f), Point(Vec3f), } From 914471fa31d7c7290d571ee49cfb0e61d0aeb093 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 22:06:29 +0200 Subject: [PATCH 009/417] ai-hub: a feed session whose last socket left ends on its idle timeout; skin: parent, skinned centroid and a nodes-only rig for retargets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A realtime feed session parked in its wait-for-a-frame loop forever when the client died without sending stop (a sandbox quit left job-2 live on .123 for five minutes holding the GPU slot). The wait loop now returns to the top of the session loop once no socket is left, where the idle timeout counts a socketless session down. Test covers it. SkinnedModel gains node_parent/node_count, joint_skinned_centroid (the direction a leaf limb actually runs, from the flesh it skins) and from_nodes (a mesh-less rig for hierarchy-maths tests) — what the sandbox's webcam mocap retarget needs. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01B626urtY1Xo4hQdLzvSK6F --- libs/ai/hub/src/realtime.rs | 51 ++++++++++++++++++++++++++++++++ libs/render/src/skin.rs | 58 +++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/libs/ai/hub/src/realtime.rs b/libs/ai/hub/src/realtime.rs index 35799851b..e073f3979 100644 --- a/libs/ai/hub/src/realtime.rs +++ b/libs/ai/hub/src/realtime.rs @@ -1210,6 +1210,15 @@ pub fn run_live( if let Some(frame) = session.take_mailbox_frame() { break frame; } + if session.socket_count() == 0 { + // Nobody listening and nobody feeding: a client that + // died without `stop` would otherwise park this + // branch forever and hold the GPU slot. Go back + // through the top, where the idle timeout counts a + // socketless session down and ends it. + session.wait_for_mailbox(Duration::from_millis(250)); + continue 'session; + } if session.loop_mode() != LoopMode::Feed { // A control update flipped the session to feedback // while this branch sat waiting for input. Re-enter @@ -2054,6 +2063,48 @@ mod tests { } } + /// A feed-mode client that vanishes without `stop` (a crash, a kill) + /// must not hold the box's live slot forever: once its socket is gone + /// the idle timeout ends the session even though no frame ever arrives + /// again. + #[test] + fn run_live_feed_mode_ends_when_the_last_socket_leaves_past_the_idle_timeout() { + let mut params = recording_params(LoopMode::Feed); + params.idle_timeout_s = 1; + let session = std::sync::Arc::new(RealtimeSession::new("job-t".to_string(), ¶ms)); + let (socket_tx, socket_rx) = mpsc::channel(); + session.add_socket(1, socket_tx); + let seen = std::sync::Arc::new(Mutex::new(Vec::new())); + let source = gradient_image(32, 32); + let worker = { + let session = session.clone(); + let seen = seen.clone(); + let source = source.clone(); + std::thread::spawn(move || { + let mut backend = RecordingBackend { seen, source }; + let cancel = CancelToken::new(); + run_live(&session, &mut backend, &cancel, |_, _, _, _| {}) + }) + }; + session.push_input_frame(source); + let deadline = Instant::now() + Duration::from_secs(10); + while seen.lock().unwrap().is_empty() { + assert!(Instant::now() < deadline, "the first frame never ran"); + std::thread::sleep(Duration::from_millis(5)); + } + // The client is gone: socket closed, no stop, no more frames. + session.remove_socket(1); + drop(socket_rx); + let started = Instant::now(); + let deadline = started + Duration::from_secs(8); + while !worker.is_finished() { + assert!(Instant::now() < deadline, "a socketless feed session must end on the idle timeout"); + std::thread::sleep(Duration::from_millis(20)); + } + worker.join().unwrap().unwrap(); + assert!(started.elapsed() >= Duration::from_millis(900), "ended before the idle timeout"); + } + #[test] fn run_live_feed_mode_passes_init_without_anchor_and_rerolls_the_seed() { let source = gradient_image(32, 32); diff --git a/libs/render/src/skin.rs b/libs/render/src/skin.rs index db14eaf3d..42e77813f 100644 --- a/libs/render/src/skin.rs +++ b/libs/render/src/skin.rs @@ -1373,6 +1373,64 @@ impl SkinnedModel { self.nodes.get(node).map(|node| node.name.as_str()) } + /// Parent of `node` in the authored hierarchy; `None` for a root or an + /// out-of-range index. Retargets walk this parents-first. + pub fn node_parent(&self, node: usize) -> Option { + self.nodes.get(node).and_then(|node| node.parent) + } + + /// Number of nodes, joints or not — the length of every `PoseBuffer`. + pub fn node_count(&self) -> usize { + self.nodes.len() + } + + /// Weight-averaged rest position, in mesh space, of the vertices the + /// joint at `node` skins — where the flesh hangs off the bone. A leaf + /// limb has no child to point at; this is the way it actually runs. + /// `None` when `node` is not a joint or skins nothing. + pub fn joint_skinned_centroid(&self, node: usize) -> Option { + let joint = self.joint_nodes.iter().position(|&n| n == node)?; + let mut sum = Vec3f::default(); + let mut total = 0.0f32; + for v in &self.vertices { + for k in 0..4 { + if v.joints[k] as usize == joint && v.weights[k] > 0.0 { + let w = v.weights[k]; + sum = sum + v.pos.scale(w); + total += w; + } + } + } + if total <= 0.0 { + return None; + } + Some(sum.scale(1.0 / total)) + } + + /// A rig of nodes and nothing else — no mesh, no clips — for tests and + /// tools that exercise hierarchy maths (retargets) without a GLB. Every + /// node counts as a joint; `mesh_node` is the node whose inverse + /// premultiplies `node_mesh_transform`, as for a parsed model. + pub fn from_nodes(nodes: Vec<(String, Option, NodeTrs)>, mesh_node: usize) -> SkinnedModel { + let joint_nodes = (0..nodes.len()).collect(); + SkinnedModel { + rest_hash_cache: std::sync::OnceLock::new(), + nodes: nodes + .into_iter() + .map(|(name, parent, rest)| Node { name, parent, rest }) + .collect(), + joint_nodes, + inverse_bind: Vec::new(), + mesh_node, + vertices: Vec::new(), + indices: Vec::new(), + clips: Vec::new(), + skipped_unskinned: 0, + joint_bounds: Vec::new(), + ragdoll: None, + } + } + /// Mask containing `root` and every node parented below it. /// /// Cache this alongside a resolved animation clip when applying a From f7093bf82f10c0b59c88a6ae6a0f3da2cb4b9b22 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 22:13:13 +0200 Subject: [PATCH 010/417] map_nav: the search db's positioned read builds on Windows searchdb imported std::os::unix::fs::FileExt for read_exact_at, which does not exist on Windows (reported from a Windows checkout of work). A small ReadExactAt trait now wraps unix pread and Windows seek_read, both cursor-free, so the shared reader keeps serving lookups from several threads without a lock. Checked on x86_64-pc-windows-msvc. Co-Authored-By: Claude Fable 5.1 --- libs/map_nav/src/searchdb.rs | 44 +++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/libs/map_nav/src/searchdb.rs b/libs/map_nav/src/searchdb.rs index a7d1afca7..dc3024cb7 100644 --- a/libs/map_nav/src/searchdb.rs +++ b/libs/map_nav/src/searchdb.rs @@ -25,7 +25,49 @@ use crate::search::{normalize_tokens, score_search_hit, Category, SearchResult}; use std::collections::{BinaryHeap, HashMap, HashSet}; use std::fs::{self, File}; use std::io::{BufReader, BufWriter, Read, Write}; -use std::os::unix::fs::FileExt; +/// Positioned read, portable: unix `pread` and Windows `seek_read` both +/// leave the file's own cursor alone, which is what lets a shared reader +/// serve lookups from several threads without a lock. +trait ReadExactAt { + fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> std::io::Result<()>; +} + +impl ReadExactAt for File { + #[cfg(unix)] + fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> std::io::Result<()> { + std::os::unix::fs::FileExt::read_exact_at(self, buf, offset) + } + + #[cfg(windows)] + fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> std::io::Result<()> { + use std::os::windows::fs::FileExt; + while !buf.is_empty() { + match self.seek_read(buf, offset) { + Ok(0) => { + return Err(std::io::Error::new( + std::io::ErrorKind::UnexpectedEof, + "failed to fill whole buffer", + )) + } + Ok(n) => { + buf = &mut buf[n..]; + offset += n as u64; + } + Err(e) if e.kind() == std::io::ErrorKind::Interrupted => {} + Err(e) => return Err(e), + } + } + Ok(()) + } + + #[cfg(not(any(unix, windows)))] + fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> std::io::Result<()> { + use std::io::{Read, Seek, SeekFrom}; + let mut file = self; + file.seek(SeekFrom::Start(offset))?; + file.read_exact(buf) + } +} use std::path::{Path, PathBuf}; const SEARCHDB_MAGIC: u32 = 0x4d53_4442; // "BDSM"^W "MSDB" From 3fcccf3b477b408da4cc229e8fba4e3f751053b5 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 22:15:38 +0200 Subject: [PATCH 011/417] sim: the whole world is implicitly editable, and one seam says where the ground is MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The voxel layer's volume gate is gone — any edit materializes chunks anywhere on the map (volumes remain as styling), with the lazy-chunk economics proven by test: zero storage until the first op. The composed surface seam (GameWorld::surface_height_at: heightfield where untouched, voxel surface where a chunk owns it) is what ground queries, senses and the drape corridor read, so a mountain raised mid-game and a dug crater are the same truth the vehicles drive on. landform.rs adds the macro shapes (mountain/hill/ridge/valley/crater/plateau, fbm detail, slope rock + snow recolor) and the tunnel op rides the capsule-filtered materialization. Co-Authored-By: Claude Fable 5 --- libs/sim/src/landform.rs | 621 +++++++++++++++++++++++++++++++++++++++ libs/sim/src/lib.rs | 2 + libs/sim/src/queries.rs | 8 +- libs/sim/src/sense.rs | 7 +- libs/sim/src/voxel.rs | 473 ++++++++++++++++++++++++++--- libs/sim/src/world.rs | 45 ++- 6 files changed, 1096 insertions(+), 60 deletions(-) create mode 100644 libs/sim/src/landform.rs diff --git a/libs/sim/src/landform.rs b/libs/sim/src/landform.rs new file mode 100644 index 000000000..466932fb0 --- /dev/null +++ b/libs/sim/src/landform.rs @@ -0,0 +1,621 @@ +//! Macro landforms — the AI's big geometry verbs (`game.landform`). +//! +//! One unified destructible world means "raise a mountain" is one op, not a +//! thousand brush strokes. A landform is heightfield-scale terrain surgery: +//! a target-surface shape (mountain / hill / ridge / valley / crater / +//! plateau) with multi-octave noise detail so a mountain reads as one, not a +//! cone. Composition rule, same as the foundation press: the HEIGHTFIELD +//! takes the shape wherever no voxel chunk owns the surface; materialized +//! chunks compose the same shape as voxel min/max +//! ([`VoxelField::compose_surface_targets`]), so raising ground over a +//! dug-open pit fills it to the new surface rather than leaving a punched +//! hole with a mountain painted around it. +//! +//! Ops are idempotent (raise = max, lower = min, plateau = clamp) and ride +//! the voxel op stream ([`VoxelOp::Landform`]). They are recorded on the +//! field ([`VoxelField::land_ops`]) so that: +//! - a script re-eval, which rebuilds the authored heightfield, REPLAYS the +//! list on top ([`replay_land_ops`]) — the AI's mountains survive reload; +//! - the structure snapshot carries the list to late joiners. +//! Replay is heightfield-only (`voxelize = false`): the chunks persist their +//! own history, and re-composing would refill a tunnel dug through the +//! mountain after it was raised. +//! +//! Determinism: integer-hash lattice noise (same construction as +//! makepad-game-gen's terrain noise), fixed expression order, sqrt only +//! (IEEE-exact) — same op → same heights on every device. + +use makepad_math::*; + +use crate::terrain::Terrain; +use crate::voxel::{VoxelField, VoxelOp}; +use crate::world::GameWorld; + +/// Landform ops kept for replay/wire; beyond this they still apply but no +/// longer survive a reload (logged by the host path). +pub const MAX_LAND_OPS: usize = 128; + +/// What shape `game.landform` cuts or raises. +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum LandKind { + Mountain, + Hill, + Ridge, + Valley, + Crater, + Plateau, +} + +impl LandKind { + pub fn parse(name: &str) -> LandKind { + match name { + "mountain" | "peak" => LandKind::Mountain, + "ridge" => LandKind::Ridge, + "valley" | "basin" | "dip" => LandKind::Valley, + "crater" => LandKind::Crater, + "plateau" | "mesa" | "flat" => LandKind::Plateau, + _ => LandKind::Hill, + } + } + pub fn to_u8(self) -> u8 { + match self { + LandKind::Mountain => 0, + LandKind::Hill => 1, + LandKind::Ridge => 2, + LandKind::Valley => 3, + LandKind::Crater => 4, + LandKind::Plateau => 5, + } + } + pub fn from_u8(v: u8) -> LandKind { + match v { + 0 => LandKind::Mountain, + 2 => LandKind::Ridge, + 3 => LandKind::Valley, + 4 => LandKind::Crater, + 5 => LandKind::Plateau, + _ => LandKind::Hill, + } + } +} + +// ── noise (same integer-hash construction as gen's terrain noise) ──────── + +/// One lattice value in 0..1 — integer avalanche, device-identical. +#[inline] +fn lattice(seed: u64, x: i64, z: i64) -> f32 { + let mut h = seed + .wrapping_mul(0x9E37_79B9_7F4A_7C15) + .wrapping_add((x as u64).wrapping_mul(0x2545_F491_4F6C_DD1D)) + .wrapping_add((z as u64).wrapping_mul(0x27D4_EB2F_1656_67C5)); + h ^= h >> 33; + h = h.wrapping_mul(0xFF51_AFD7_ED55_8CCD); + h ^= h >> 33; + (h >> 11) as f32 / (1u64 << 53) as f32 +} + +#[inline] +fn smoothstep01(t: f32) -> f32 { + t * t * (3.0 - 2.0 * t) +} + +/// `floor` without the truncation-toward-zero mirror bug. +#[inline] +fn floor_i64(x: f32) -> i64 { + let t = x as i64; + if x < 0.0 && (x - t as f32) != 0.0 { + t - 1 + } else { + t + } +} + +/// Bilinear value noise in 0..1. +fn value_noise(seed: u64, x: f32, z: f32) -> f32 { + let x0 = floor_i64(x); + let z0 = floor_i64(z); + let sx = smoothstep01(x - x0 as f32); + let sz = smoothstep01(z - z0 as f32); + let h00 = lattice(seed, x0, z0); + let h10 = lattice(seed, x0 + 1, z0); + let h01 = lattice(seed, x0, z0 + 1); + let h11 = lattice(seed, x0 + 1, z0 + 1); + h00 + (h10 - h00) * sx + (h01 - h00) * sz + (h00 - h10 - h01 + h11) * sx * sz +} + +/// 4-octave fbm, normalized to ~0..1. `ridged` 0 = rolling, 1 = sharp +/// crests (the fold that makes a mountain read as rock, not pudding). +fn fbm(seed: u64, x: f32, z: f32, ridged: f32) -> f32 { + let mut amplitude = 1.0f32; + let mut total = 0.0f32; + let mut fx = x; + let mut fz = z; + for octave in 0..4u64 { + let n = value_noise(seed ^ octave.wrapping_mul(0x9E37_79B9), fx, fz); + let ridge = 1.0 - (n * 2.0 - 1.0).abs(); + total += (n + (ridge - n) * ridged) * amplitude; + amplitude *= 0.5; + fx *= 2.0; + fz *= 2.0; + } + total / 1.875 +} + +// ── the shape ──────────────────────────────────────────────────────────── + +/// The target-surface heights this landform asks for at world (x, z): +/// `(raise_to, lower_to)`. Raise means `h = max(h, t)`, lower means +/// `h = min(h, t)`, both Some clamps — all idempotent, which is the whole +/// replay/re-delivery story. `(None, None)` outside the shape's support. +pub fn shape_targets( + kind: LandKind, + pos: Vec3f, + r: f32, + height: f32, + seed: u32, + x: f32, + z: f32, +) -> (Option, Option) { + let seed = seed as u64; + let dx = x - pos.x; + let dz = z - pos.z; + let d = crate::math::sqrt(dx * dx + dz * dz); + match kind { + LandKind::Mountain => { + // Wobbled footprint + ridged detail: the peak wanders, spurs + // grow, and the silhouette stops being a traffic cone. + let wob = 0.8 + 0.4 * fbm(seed ^ 0xA5A5, dx * 2.0 / r + 13.7, dz * 2.0 / r - 7.3, 0.0); + let dn = d / (r * wob); + if dn >= 1.0 { + return (None, None); + } + let fall = smoothstep01(1.0 - dn); + let fall = fall * crate::math::sqrt(fall); // ^1.5: steep flanks + let n = fbm(seed, dx * 4.0 / r, dz * 4.0 / r, 1.0); + (Some(pos.y + height * fall * (0.55 + 0.45 * n)), None) + } + LandKind::Hill => { + let wob = 0.85 + 0.3 * fbm(seed ^ 0xA5A5, dx * 1.6 / r + 3.1, dz * 1.6 / r + 9.4, 0.0); + let dn = d / (r * wob); + if dn >= 1.0 { + return (None, None); + } + let fall = smoothstep01(1.0 - dn); + let n = fbm(seed, dx * 3.0 / r, dz * 3.0 / r, 0.0); + (Some(pos.y + height * fall * (0.8 + 0.2 * n)), None) + } + LandKind::Ridge => { + // A crest along a seed-picked axis, tapering toward its ends. + let (mut ax, mut az) = (lattice(seed, 11, 7) * 2.0 - 1.0, lattice(seed, 3, 29) * 2.0 - 1.0); + let alen = crate::math::sqrt(ax * ax + az * az); + if alen < 1.0e-3 { + (ax, az) = (1.0, 0.0); + } else { + ax /= alen; + az /= alen; + } + let half = r * 1.4; + let along = dx * ax + dz * az; + let clamped = along.clamp(-half, half); + let (nx, nz) = (dx - clamped * ax, dz - clamped * az); + let dseg = crate::math::sqrt(nx * nx + nz * nz); + let wob = 0.8 + 0.4 * fbm(seed ^ 0x51DE, along * 2.0 / r, 0.0, 0.0); + let dn = dseg / (r * 0.45 * wob); + if dn >= 1.0 { + return (None, None); + } + let taper = smoothstep01((1.0 - along.abs() / half).clamp(0.0, 1.0)); + let fall = smoothstep01(1.0 - dn) * taper; + let n = fbm(seed, dx * 3.0 / r, dz * 3.0 / r, 1.0); + (Some(pos.y + height * fall * (0.6 + 0.4 * n)), None) + } + LandKind::Valley => { + let wob = 0.85 + 0.3 * fbm(seed ^ 0xA5A5, dx * 1.6 / r - 5.2, dz * 1.6 / r + 2.8, 0.0); + let dn = d / (r * wob); + if dn >= 1.0 { + return (None, None); + } + let fall = smoothstep01(1.0 - dn); + let n = fbm(seed, dx * 3.0 / r, dz * 3.0 / r, 0.0); + (None, Some(pos.y - height * fall * (0.8 + 0.2 * n))) + } + LandKind::Crater => { + let rb = 0.68 * r; + if d < rb { + let t = d / rb; + (None, Some(pos.y - height * (1.0 - t * t))) + } else { + let t = (d - 0.85 * r) / (0.28 * r); + if t.abs() < 1.0 { + let bump = (1.0 - t * t) * (1.0 - t * t); + let n = fbm(seed, dx * 5.0 / r, dz * 5.0 / r, 0.0); + (Some(pos.y + 0.32 * height * bump * (0.8 + 0.2 * n)), None) + } else { + (None, None) + } + } + } + LandKind::Plateau => { + let dn = d / r; + if dn >= 1.0 { + return (None, None); + } + let t = pos.y + height; + // Flat core; the ring clamps surrounding ground into a widening + // band around the top — a feathered edge, still idempotent. + let allow = ((dn - 0.7).max(0.0) / 0.3) * (height.abs() + 10.0); + (Some(t - allow), Some(t + allow)) + } + } +} + +/// Full x/z reach of a landform's support (all kinds fit inside this). +pub fn shape_reach(r: f32) -> f32 { + r * 2.1 +} + +// ── application ────────────────────────────────────────────────────────── + +/// Heightfield part: write the shape into the terrain (idempotent max/min/ +/// clamp) and recolor the vertices it moved by slope — rock on the new +/// cliffs, snow on a mountain's crown. Returns whether anything moved. +fn apply_heightfield( + t: &mut Terrain, + pos: Vec3f, + kind: LandKind, + r: f32, + height: f32, + seed: u32, +) -> bool { + let cells = t.cells; + if cells < 2 || t.heights.len() < cells * cells { + return false; + } + let cs = t.cell_size.max(1.0e-6); + let reach = shape_reach(r); + let gx0 = (((pos.x - reach - t.origin) / cs).floor().max(0.0)) as usize; + let gz0 = (((pos.z - reach - t.origin) / cs).floor().max(0.0)) as usize; + let gx1 = ((((pos.x + reach - t.origin) / cs).ceil()).max(0.0) as usize).min(cells - 1); + let gz1 = ((((pos.z + reach - t.origin) / cs).ceil()).max(0.0) as usize).min(cells - 1); + if gx0 > gx1 || gz0 > gz1 { + return false; + } + let w = gx1 - gx0 + 1; + let mut moved = vec![false; w * (gz1 - gz0 + 1)]; + let mut changed = false; + for gz in gz0..=gz1 { + for gx in gx0..=gx1 { + let x = t.origin + gx as f32 * cs; + let z = t.origin + gz as f32 * cs; + let (raise, lower) = shape_targets(kind, pos, r, height, seed, x, z); + let h = &mut t.heights[gz * cells + gx]; + let before = *h; + if let Some(up) = raise { + if *h < up { + *h = up; + } + } + if let Some(down) = lower { + if *h > down { + *h = down; + } + } + if *h != before { + changed = true; + moved[(gz - gz0) * w + (gx - gx0)] = true; + } + } + } + // Recolor pass: pure function of the FINAL heights (and the seed), so a + // replay or re-delivery repaints identically instead of drifting. + if changed && t.colors.len() >= cells * cells { + for gz in gz0..=gz1 { + for gx in gx0..=gx1 { + if !moved[(gz - gz0) * w + (gx - gx0)] { + continue; + } + let h = |ix: usize, iz: usize| t.heights[iz * cells + ix]; + let xm = gx.saturating_sub(1); + let xp = (gx + 1).min(cells - 1); + let zm = gz.saturating_sub(1); + let zp = (gz + 1).min(cells - 1); + let dhdx = (h(xp, gz) - h(xm, gz)) / ((xp - xm).max(1) as f32 * cs); + let dhdz = (h(gx, zp) - h(gx, zm)) / ((zp - zm).max(1) as f32 * cs); + let slope = crate::math::sqrt(dhdx * dhdx + dhdz * dhdz); + let j = lattice(seed as u64 ^ 0x77C0, gx as i64, gz as i64) * 0.14 - 0.07; + let here = t.heights[gz * cells + gx]; + let snowy = kind == LandKind::Mountain && height > 0.0 + && here > pos.y + 0.72 * height; + let rockness = ((slope - 0.65) / 0.5).clamp(0.0, 1.0); + if snowy { + t.colors[gz * cells + gx] = + vec4f(0.86 + j * 0.5, 0.87 + j * 0.5, 0.92 + j * 0.5, 1.0); + } else if rockness > 0.35 { + t.colors[gz * cells + gx] = + vec4f(0.47 + j, 0.44 + j, 0.42 + j, 1.0); + } + } + } + } + changed +} + +/// Apply one [`VoxelOp::Landform`] to the world: heightfield always, +/// voxel composition into materialized chunks only when `voxelize` (first +/// application — a replay must not refill tunnels dug after the landform). +pub fn apply_landform_op(world: &mut GameWorld, op: VoxelOp, voxelize: bool) { + let VoxelOp::Landform { pos, kind, r, height, seed } = op else { + return; + }; + let kind = LandKind::from_u8(kind); + let Some(terrain) = world.terrain.as_mut() else { + world.log("game.landform: needs a game.terrain heightfield first".to_string()); + return; + }; + if apply_heightfield(terrain, pos, kind, r, height, seed) { + terrain.revision += 1; + world.mark_render_dirty(); + } + if voxelize { + let GameWorld { voxel, terrain, log_pending, .. } = world; + if let Some(field) = voxel.as_deref_mut() { + if field.chunk_count() > 0 { + let reach = shape_reach(r); + let band = height.abs() * 1.05 + field.cell * 2.0; + field.compose_surface_targets( + pos.x - reach, + pos.x + reach, + pos.z - reach, + pos.z + reach, + pos.y - band, + pos.y + band, + terrain.as_ref(), + log_pending, + &mut |x, z| shape_targets(kind, pos, r, height, seed, x, z), + ); + } + } + } +} + +/// Two landform ops are THE SAME LANDFORM when everything but the sampled +/// base height matches. The verb samples its base from the live composed +/// surface — which the landform itself raises — so a re-eval re-running the +/// same script line arrives with a HIGHER pos.y. Matching on it would +/// re-record the op and stack the mountain on its own peak, +height per +/// eval (the floating-curtain ratchet). Identity is (x, z, kind, r, +/// height, seed); the recorded op keeps its first-sample base forever. +fn same_landform(a: &VoxelOp, b: &VoxelOp) -> bool { + match (a, b) { + ( + VoxelOp::Landform { pos: pa, kind: ka, r: ra, height: ha, seed: sa }, + VoxelOp::Landform { pos: pb, kind: kb, r: rb, height: hb, seed: sb }, + ) => { + pa.x.to_bits() == pb.x.to_bits() + && pa.z.to_bits() == pb.z.to_bits() + && ka == kb + && ra.to_bits() == rb.to_bits() + && ha.to_bits() == hb.to_bits() + && sa == sb + } + _ => false, + } +} + +/// The authority path (verb layer / host): record for replay + replication, +/// then apply. A re-delivered identical op (a script re-eval re-running its +/// own landform line) applies heightfield-only — the chunks already carry +/// its voxel effect plus everything dug since. +pub fn host_apply_landform(world: &mut GameWorld, op: VoxelOp) { + let mut overflow = false; + let field = world + .voxel + .get_or_insert_with(|| Box::new(VoxelField::new(0.5))); + let recorded = field.land_ops.iter().find(|k| same_landform(k, &op)).copied(); + let known = recorded.is_some(); + if !known { + if field.land_ops.len() < MAX_LAND_OPS { + field.land_ops.push(op); + // The list rides the structure snapshot: bump so it rebroadcasts. + field.structure_rev += 1; + } else { + overflow = true; + } + if field.pending_ops.len() < 65536 { + field.pending_ops.push(op); + } + if field.persist_ops.len() < 8192 { + field.persist_ops.push(op); + } else { + field.persist_overflow = true; + field.persist_ops.clear(); + } + } + if overflow { + world.log(format!( + "game.landform: more than {MAX_LAND_OPS} landforms — this one applies \ + but will not survive a reload" + )); + } + // A known landform re-applies as its RECORDED twin (first-sample base): + // the incoming copy's base was sampled from ground the landform itself + // already raised, and applying that would still ratchet the heights. + apply_landform_op(world, recorded.unwrap_or(op), !known); +} + +/// The replica path (wire op): apply with voxel composition (this device's +/// chunks mirror the host's op application) and remember for ITS reloads — +/// never re-replicate. +pub fn wire_apply_landform(world: &mut GameWorld, op: VoxelOp) { + let field = world + .voxel + .get_or_insert_with(|| Box::new(VoxelField::new(0.5))); + let recorded = field.land_ops.iter().find(|k| same_landform(k, &op)).copied(); + let known = recorded.is_some(); + if !known && field.land_ops.len() < MAX_LAND_OPS { + field.land_ops.push(op); + } + apply_landform_op(world, recorded.unwrap_or(op), !known); +} + +/// Re-apply the recorded landform list onto a freshly rebuilt heightfield +/// (heightfield-only — see module doc). Runs once per pending flag, waiting +/// until a terrain exists; called every tick from `update_world_voxel`. +pub fn replay_land_ops(world: &mut GameWorld) { + let Some(field) = world.voxel.as_deref() else { + return; + }; + if !field.land_replay_pending { + return; + } + if field.land_ops.is_empty() { + if let Some(f) = world.voxel.as_deref_mut() { + f.land_replay_pending = false; + } + return; + } + if world.terrain.is_none() { + return; // eval not there yet — retry next tick + } + let ops: Vec = field.land_ops.clone(); + if let Some(f) = world.voxel.as_deref_mut() { + f.land_replay_pending = false; + } + for op in ops { + apply_landform_op(world, op, false); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn flat_world() -> GameWorld { + let cells = 65; + let mut w = GameWorld::new(); + w.terrain = Some(Terrain { + cells, + cell_size: 2.0, + origin: -64.0, + heights: vec![0.0; cells * cells], + colors: vec![vec4f(0.4, 0.6, 0.4, 1.0); cells * cells], + revision: 1, + }); + w + } + + fn mountain_op() -> VoxelOp { + VoxelOp::Landform { + pos: vec3f(0.0, 0.0, 0.0), + kind: LandKind::Mountain.to_u8(), + r: 30.0, + height: 18.0, + seed: 7, + } + } + + #[test] + fn mountain_raises_idempotently_and_survives_replay() { + let mut w = flat_world(); + host_apply_landform(&mut w, mountain_op()); + let peak = w.terrain.as_ref().unwrap().height_at(0.0, 0.0).unwrap(); + assert!(peak > 8.0, "mountain peak only {peak}"); + let snapshot = w.terrain.as_ref().unwrap().heights.clone(); + // Re-running the same script line must not double-raise. + host_apply_landform(&mut w, mountain_op()); + assert_eq!(w.terrain.as_ref().unwrap().heights, snapshot); + // Reload: heightfield rebuilt flat, replay restores the mountain. + let n = w.terrain.as_ref().unwrap().heights.len(); + w.terrain.as_mut().unwrap().heights = vec![0.0; n]; + w.voxel.as_deref_mut().unwrap().land_replay_pending = true; + replay_land_ops(&mut w); + assert_eq!(w.terrain.as_ref().unwrap().heights, snapshot); + } + + #[test] + fn a_reeval_resampling_its_own_mountain_does_not_ratchet() { + // The verb samples its base from the live surface; on a re-eval the + // same script line therefore arrives with pos.y on the mountain's + // own peak. It must be recognized as THE SAME landform and re-apply + // with its recorded base — not stack +height per eval. + let mut w = flat_world(); + host_apply_landform(&mut w, mountain_op()); + let snapshot = w.terrain.as_ref().unwrap().heights.clone(); + let peak = w.surface_height_at(0.0, 0.0).unwrap(); + assert!(peak > 8.0); + let VoxelOp::Landform { kind, r, height, seed, .. } = mountain_op() else { + unreachable!() + }; + host_apply_landform( + &mut w, + VoxelOp::Landform { pos: vec3f(0.0, peak, 0.0), kind, r, height, seed }, + ); + assert_eq!( + w.terrain.as_ref().unwrap().heights, + snapshot, + "re-sampled base ratcheted the mountain" + ); + assert_eq!(w.voxel.as_deref().unwrap().land_ops.len(), 1, "op re-recorded"); + } + + #[test] + fn landform_is_deterministic() { + let mut a = flat_world(); + let mut b = flat_world(); + host_apply_landform(&mut a, mountain_op()); + host_apply_landform(&mut b, mountain_op()); + let ha = &a.terrain.as_ref().unwrap().heights; + let hb = &b.terrain.as_ref().unwrap().heights; + assert!(ha.iter().zip(hb.iter()).all(|(x, y)| x.to_bits() == y.to_bits())); + } + + #[test] + fn crater_digs_a_bowl_with_a_rim() { + let mut w = flat_world(); + host_apply_landform( + &mut w, + VoxelOp::Landform { + pos: vec3f(0.0, 0.0, 0.0), + kind: LandKind::Crater.to_u8(), + r: 20.0, + height: 6.0, + seed: 3, + }, + ); + let t = w.terrain.as_ref().unwrap(); + let center = t.height_at(0.0, 0.0).unwrap(); + let rim = t.height_at(17.0, 0.0).unwrap(); + let outside = t.height_at(50.0, 0.0).unwrap(); + assert!(center < -4.0, "bowl centre {center}"); + assert!(rim > 0.5, "rim {rim}"); + assert!(outside.abs() < 1.0e-6, "outside moved: {outside}"); + } + + #[test] + fn landform_composes_into_materialized_chunks() { + // Dig a pit first (chunks own the surface there), then raise a + // mountain over it: the voxel surface must rise with the ground. + let mut w = flat_world(); + w.apply_voxel_op(VoxelOp::Dig { + pos: vec3f(0.0, 0.0, 0.0), + r: 4.0, + mode: crate::voxel::DigMode::Carve, + material: 1, + }); + let field = w.voxel.as_deref().unwrap(); + let pit = field.surface_at(0.0, 0.0, 0.0).expect("pit does not own surface"); + assert!(pit < -1.0, "pit floor {pit}"); + host_apply_landform(&mut w, mountain_op()); + let field = w.voxel.as_deref().unwrap(); + let composed = field + .surface_at(0.0, 0.0, 0.0) + .expect("voxel no longer owns the raised surface"); + assert!( + composed > 6.0, + "voxel surface did not rise with the mountain: {composed}" + ); + // And the seam agrees. + let seam = w.surface_height_at(0.0, 0.0).unwrap(); + assert!((seam - composed).abs() < 1.0e-4, "seam {seam} != voxel {composed}"); + } +} diff --git a/libs/sim/src/lib.rs b/libs/sim/src/lib.rs index 088e8d6a0..3b46bd4bd 100644 --- a/libs/sim/src/lib.rs +++ b/libs/sim/src/lib.rs @@ -20,6 +20,7 @@ pub mod dynamics; pub mod entity; pub mod heading; pub mod hud; +pub mod landform; pub mod level_solid; pub mod nav; pub mod particles; @@ -46,6 +47,7 @@ pub use hud::{ layout as hud_layout, Crosshair, CrosshairStyle, HudAlign, HudDoc, HudElement, HudKind, HudLine, HudPlaced, HudPulse, HudStack, HudValue, }; +pub use landform::LandKind; pub use nav::{FlowField, NavAgent, NavMap}; pub use particles::*; pub use player::*; diff --git a/libs/sim/src/queries.rs b/libs/sim/src/queries.rs index 8d26b0608..0f1328f9e 100644 --- a/libs/sim/src/queries.rs +++ b/libs/sim/src/queries.rs @@ -205,7 +205,13 @@ pub fn camera_path_limit( let p = origin + dir * t; if let Some(terrain) = &world.terrain { if let Some(h) = terrain.height_at(p.x, p.z) { - if p.y < h + 0.2 { + // Inside carved-open voxel air (a tunnel under this ground) + // the heightfield is not a wall — the camera may boom there. + let carved = world + .voxel + .as_deref() + .map_or(false, |v| v.is_carved_air(p)); + if p.y < h + 0.2 && !carved { return (t - clearance).max(minimum).min(distance); } } diff --git a/libs/sim/src/sense.rs b/libs/sim/src/sense.rs index 5b05fedc6..252df7fc3 100644 --- a/libs/sim/src/sense.rs +++ b/libs/sim/src/sense.rs @@ -102,10 +102,9 @@ pub fn ground_ahead( } let probe = vec3f(pos.x + dir.x / len * ahead, pos.y, pos.z + dir.z / len * ahead); let feet = pos.y - half.y; - let mut ground = world - .terrain - .as_ref() - .and_then(|t| t.height_at(probe.x, probe.z)); + // Composed world surface: an NPC at a dug pit's edge sees the pit floor, + // not the pre-dig heightfield it would happily walk out onto. + let mut ground = world.surface_height_at(probe.x, probe.z); for e in &world.entities { if !blocks_movement(e) { continue; diff --git a/libs/sim/src/voxel.rs b/libs/sim/src/voxel.rs index 82a92cf96..ca5d89e85 100644 --- a/libs/sim/src/voxel.rs +++ b/libs/sim/src/voxel.rs @@ -117,8 +117,11 @@ impl VoxelMode { } } -/// An editable region + its look. Ops apply only to sites inside a volume; -/// everything outside stays pure heightfield forever. +/// A declared style region: chunks whose centre falls inside pick this +/// volume's mesher ([`VoxelField::chunk_mode`]). Historically ops applied +/// ONLY inside declared volumes; the world is now implicitly editable +/// everywhere (one unified destructible ground), so volumes are about LOOK +/// (smooth vs blocky), not permission. #[derive(Clone, Copy, Debug, PartialEq)] pub struct VoxelVolume { pub min: Vec3f, @@ -184,6 +187,22 @@ pub enum VoxelOp { }, /// `material` 0 = remove the block. SetBlock { x: i32, y: i32, z: i32, material: u8 }, + /// Carve a straight capsule from `from` to `to` (a tunnel through a + /// hill). Materializes only chunks the capsule actually passes through, + /// never the whole segment AABB. + Tunnel { from: Vec3f, to: Vec3f, r: f32 }, + /// Foundation-press composition: open air above the plane `y` inside the + /// x/z rectangle `min..max`, up to `max.y`. Emitted when a structure pad + /// lies under materialized chunks — the voxel twin of the heightfield + /// press. Never materializes new chunks (untouched ground already obeys + /// the pressed heightfield implicitly). + Press { min: Vec3f, max: Vec3f, y: f32 }, + /// Macro landform (mountain / valley / crater / ...): the heightfield + /// part is applied by [`crate::landform`]; the voxel part composes into + /// already-materialized chunks. `pos.y` is the captured base height, + /// `kind` is [`crate::landform::LandKind::to_u8`]. Never dispatched + /// through [`VoxelField::apply_op`] — the world-level appliers own it. + Landform { pos: Vec3f, kind: u8, r: f32, height: f32, seed: u32 }, } /// One remeshed chunk, in the renderer's 16-float PbrVertex layout @@ -238,6 +257,12 @@ pub struct VoxelField { /// a different cell keep the field's (logged by the verb). pub cell: f32, pub palette: Vec, + /// Material the top ~2.5 cells of base ground materialize as (the rest + /// is [`BASE_MATERIAL`] dirt). Defaults to dirt — byte-identical to the + /// original behavior; the implicit whole-world field sets it to the + /// grass slot so an untouched materialized surface reads as the map, + /// and digging exposes dirt beneath. + pub surface_material: u8, pub volumes: Vec, /// Bumped when volumes / palette / cell change — the session layer /// rebroadcasts the structure snapshot when it moves. @@ -255,6 +280,23 @@ pub struct VoxelField { /// Chunks materialized since the session last drained — late-join / /// first-sight chunk snapshots ride these. pub fresh_chunks: Vec, + /// Macro landform ops applied to this world, in order (heightfield-scale + /// terrain surgery — see [`crate::landform`]). Kept across script + /// re-evals so the mountains an AI raised REPLAY onto the freshly + /// rebuilt heightfield; ride the structure snapshot on the wire so late + /// joiners and reloading clients replay the same list. + pub land_ops: Vec, + /// Set when `land_ops` must re-apply (after a re-eval rebuilt the + /// terrain, or a structure snapshot delivered the list). Drained by + /// [`crate::landform::replay_land_ops`] once a terrain exists. + pub land_replay_pending: bool, + /// Ops since the last persistence flush — drained by the host app's + /// DEBOUNCED terrain saver (parallel to `pending_ops`, which the session + /// drains every tick for the wire). Only the authority records here. + pub persist_ops: Vec, + /// The persist queue hit its cap and was cleared — the saver must cut a + /// full snapshot instead of appending a tail. + pub persist_overflow: bool, /// Terrain revision the heightfield hole-punch was last applied against. pub punch_rev: Option, /// Monotonic mesh revision source. @@ -268,6 +310,7 @@ impl VoxelField { Self { cell: if cell.is_finite() { cell.clamp(0.1, 4.0) } else { 0.5 }, palette: default_palette(), + surface_material: BASE_MATERIAL, volumes: Vec::new(), structure_rev: 1, chunks: BTreeMap::new(), @@ -275,6 +318,10 @@ impl VoxelField { dirty: Vec::new(), pending_ops: Vec::new(), fresh_chunks: Vec::new(), + land_ops: Vec::new(), + land_replay_pending: false, + persist_ops: Vec::new(), + persist_overflow: false, punch_rev: None, mesh_rev: 0, cap_logged: false, @@ -511,6 +558,32 @@ impl VoxelField { best } + /// THE surface-seam query (world-surface composition): the voxel layer's + /// surface height at (x, z) IF it owns the surface there, else `None` + /// (the heightfield's business). Ownership is the punch rule: the base + /// surface crossing at `base_h` — its air site AND the solid site below — + /// must both be materialized. A deep tunnel chunk under an untouched + /// ridge owns nothing; a pit carved at the surface, or a mound filled on + /// top of it, owns the column and answers with the topmost air→solid + /// crossing in materialized data. `None` also when the column was carved + /// clean through everything materialized (the caller falls back to the + /// heightfield, which is what the base layer below would say). + pub fn surface_at(&self, x: f32, z: f32, base_h: f32) -> Option { + if self.chunks.is_empty() { + return None; + } + let air = self.world_site(vec3f(x, base_h, z)); + let solid = [air[0], air[1] - 1, air[2]]; + if !self.chunks.contains_key(&ChunkKey::of_site(air)) + || !self.chunks.contains_key(&ChunkKey::of_site(solid)) + { + return None; + } + // Scan from above every materialized chunk: floor_probe clamps its + // start into the column's own top. + self.floor_probe(x, z, 1.0e9) + } + // ── ops ───────────────────────────────────────────────────────────── /// Site AABB an op can touch (inclusive), for chunk materialization and @@ -532,11 +605,70 @@ impl VoxelField { ) } VoxelOp::SetBlock { x, y, z, .. } => ([x, y, z], [x + 1, y + 1, z + 1]), + VoxelOp::Tunnel { from, to, r } => { + let r = r.abs(); + let lo = vec3f( + from.x.min(to.x) - r, + from.y.min(to.y) - r, + from.z.min(to.z) - r, + ); + let hi = vec3f( + from.x.max(to.x) + r, + from.y.max(to.y) + r, + from.z.max(to.z) + r, + ); + ( + self.world_site(lo), + [ + (hi.x / self.cell).ceil() as i32, + (hi.y / self.cell).ceil() as i32, + (hi.z / self.cell).ceil() as i32, + ], + ) + } + VoxelOp::Press { min, max, y } => ( + self.world_site(vec3f(min.x, y - self.cell, min.z)), + [ + (max.x / self.cell).ceil() as i32, + (max.y / self.cell).ceil() as i32, + (max.z / self.cell).ceil() as i32, + ], + ), + // Landform never reaches the generic path (the world-level + // appliers in `crate::landform` own it); bounds are its region. + VoxelOp::Landform { pos, r, height, .. } => { + let reach = r.abs() * 2.1; + let h = height.abs() * 1.2 + 2.0 * self.cell; + ( + self.world_site(vec3f(pos.x - reach, pos.y - h, pos.z - reach)), + { + let hi = vec3f(pos.x + reach, pos.y + h, pos.z + reach); + [ + (hi.x / self.cell).ceil() as i32, + (hi.y / self.cell).ceil() as i32, + (hi.z / self.cell).ceil() as i32, + ] + }, + ) + } } } - fn site_in_volumes(&self, w: Vec3f) -> bool { - self.volumes.iter().any(|v| v.contains(w)) + /// Squared distance from a point to the segment `a..b` — the Tunnel + /// capsule test, and the chunk filter that keeps a long tunnel from + /// materializing its whole AABB. + fn seg_dist_sq(p: Vec3f, a: Vec3f, b: Vec3f) -> f32 { + let ab = b - a; + let len_sq = ab.x * ab.x + ab.y * ab.y + ab.z * ab.z; + let t = if len_sq > 1.0e-8 { + let ap = p - a; + ((ap.x * ab.x + ap.y * ab.y + ap.z * ab.z) / len_sq).clamp(0.0, 1.0) + } else { + 0.0 + }; + let c = vec3f(a.x + ab.x * t, a.y + ab.y * t, a.z + ab.z * t); + let d = p - c; + d.x * d.x + d.y * d.y + d.z * d.z } /// Materialize the chunk containing `s` from the base layer, if the cap @@ -568,7 +700,13 @@ impl VoxelField { let d = Self::quantize((y - h) / self.cell); let at = site_index(lx, ly, lz); density[at] = d; - material[at] = if d < 0 { BASE_MATERIAL } else { 0 }; + material[at] = if d < 0 { + // Topsoil band: the untouched surface keeps the + // map's look; digging exposes dirt beneath. + if h - y < self.cell * 2.5 { self.surface_material } else { BASE_MATERIAL } + } else { + 0 + }; } } } @@ -608,53 +746,69 @@ impl VoxelField { log: &mut Vec, ) { let (lo, hi) = self.op_site_bounds(&op); - // Materialize every chunk the op's bounds touch and that intersects - // a volume. Sorted chunk-key order (x, then y, then z loops). - if materialize { + // Materialize every chunk the op's bounds touch — the WHOLE world is + // implicitly editable; lazy materialization is what keeps that free + // until an edit lands. Sorted chunk-key order (x, then y, then z). + // Press never materializes (it only removes solid that exists), and + // Tunnel materializes only chunks its capsule actually passes near — + // a long diagonal tunnel must not swallow its whole AABB. + let wants_chunks = !matches!(op, VoxelOp::Press { .. }); + if materialize && wants_chunks { let k0 = ChunkKey::of_site(lo); let k1 = ChunkKey::of_site(hi); for kx in k0.x..=k1.x { for ky in k0.y..=k1.y { for kz in k0.z..=k1.z { let key = ChunkKey { x: kx, y: ky, z: kz }; - // Only chunks whose region intersects a volume. - let cmin = self.site_world(key.base()); - let cmax = self.site_world([ - key.base()[0] + CHUNK, - key.base()[1] + CHUNK, - key.base()[2] + CHUNK, - ]); - let hit = self.volumes.iter().any(|v| { - cmin.x <= v.max.x - && cmax.x >= v.min.x - && cmin.y <= v.max.y - && cmax.y >= v.min.y - && cmin.z <= v.max.z - && cmax.z >= v.min.z - }); - if hit { - self.materialize(key, base, log); + if let VoxelOp::Tunnel { from, to, r } = op { + let cmin = self.site_world(key.base()); + let half = CHUNK as f32 * self.cell * 0.5; + let center = vec3f(cmin.x + half, cmin.y + half, cmin.z + half); + // Conservative: chunk half-diagonal as slack. + let slack = r.abs() + half * 1.7321 + self.cell; + if Self::seg_dist_sq(center, from, to) > slack * slack { + continue; + } } + self.materialize(key, base, log); } } } } - // The edit itself, site by site, existing chunks only. + // The edit itself — chunk-major over materialized chunks whose site + // range intersects the op bounds (a per-site map lookup over a long + // tunnel's AABB would be millions of misses; the chunk set is ≤ + // MAX_CHUNKS by construction). let mut changed_any = false; - for sz in lo[2]..=hi[2] { - for sy in lo[1]..=hi[1] { - for sx in lo[0]..=hi[0] { + let cell = self.cell; + let keys: Vec = self + .chunks + .keys() + .filter(|k| { + let b = k.base(); + b[0] <= hi[0] + && b[0] + CHUNK > lo[0] + && b[1] <= hi[1] + && b[1] + CHUNK > lo[1] + && b[2] <= hi[2] + && b[2] + CHUNK > lo[2] + }) + .copied() + .collect(); + for key in keys { + let b = key.base(); + let (x0, x1) = (lo[0].max(b[0]), hi[0].min(b[0] + CHUNK - 1)); + let (y0, y1) = (lo[1].max(b[1]), hi[1].min(b[1] + CHUNK - 1)); + let (z0, z1) = (lo[2].max(b[2]), hi[2].min(b[2] + CHUNK - 1)); + let Some(chunk) = self.chunks.get_mut(&key) else { + continue; + }; + for sz in z0..=z1 { + for sy in y0..=y1 { + for sx in x0..=x1 { let s = [sx, sy, sz]; - let w = self.site_world(s); - if !self.site_in_volumes(w) { - continue; - } - let key = ChunkKey::of_site(s); - let Some(chunk) = self.chunks.get_mut(&key) else { - continue; - }; - let b = key.base(); + let w = vec3f(s[0] as f32 * cell, s[1] as f32 * cell, s[2] as f32 * cell); let at = site_index(sx - b[0], sy - b[1], sz - b[2]); let old_d = chunk.density[at]; let old_m = chunk.material[at]; @@ -665,13 +819,13 @@ impl VoxelField { match mode { DigMode::Carve => { // SDF subtract: d = max(d, -(sphere sdf)). - let q = Self::quantize((r - dist) / self.cell); + let q = Self::quantize((r - dist) / cell); let nd = old_d.max(q); (nd, if nd >= 0 { 0 } else { old_m }) } DigMode::Fill => { // SDF union: d = min(d, sphere sdf). - let q = Self::quantize((dist - r) / self.cell); + let q = Self::quantize((dist - r) / cell); let nd = old_d.min(q); let nm = if dist < r && nd < 0 { material.max(1) @@ -682,7 +836,7 @@ impl VoxelField { } DigMode::Flatten => { if dist < r { - let nd = Self::quantize((w.y - pos.y) / self.cell); + let nd = Self::quantize((w.y - pos.y) / cell); let nm = if nd < 0 { if old_d < 0 { old_m } else { material.max(1) } } else { @@ -706,6 +860,27 @@ impl VoxelField { (old_d, old_m) } } + VoxelOp::Tunnel { from, to, r } => { + // Capsule subtract: air within r of the segment. + let dist = Self::seg_dist_sq(w, from, to).sqrt(); + let q = Self::quantize((r - dist) / cell); + let nd = old_d.max(q); + (nd, if nd >= 0 { 0 } else { old_m }) + } + VoxelOp::Press { min, max, y } => { + // Open air above the pad plane inside the box — + // the voxel twin of the heightfield press. + if w.x >= min.x && w.x <= max.x && w.z >= min.z && w.z <= max.z { + let q = Self::quantize((w.y - y) / cell); + let nd = old_d.max(q); + (nd, if nd >= 0 { 0 } else { old_m }) + } else { + (old_d, old_m) + } + } + // World-level appliers own it (crate::landform); + // reaching here is a routing bug, kept harmless. + VoxelOp::Landform { .. } => (old_d, old_m), }; if new_d != old_d || new_m != old_m { chunk.density[at] = new_d; @@ -713,6 +888,7 @@ impl VoxelField { changed_any = true; chunk.rev += 1; } + } } } } @@ -739,6 +915,135 @@ impl VoxelField { if self.pending_ops.len() < 65536 { self.pending_ops.push(op); } + // The persistence tail (drained by the app's debounced saver). + if self.persist_ops.len() < 8192 { + self.persist_ops.push(op); + } else { + self.persist_overflow = true; + self.persist_ops.clear(); + } + } + } + + /// Landform composition over the voxel layer ([`crate::landform`]): + /// apply a per-column surface-target shape to every materialized chunk + /// inside the x/z region, first materializing — in columns that ALREADY + /// hold chunks, never spreading to untouched ones — the chunks covering + /// the `y_lo..y_hi` target band, so a mountain raised over a dug-open + /// pit owns its new surface. `target(x, z)` returns `(raise_to, + /// lower_to)`: raise unions solid below its height (min), lower carves + /// air above its height (max) — both idempotent; both `Some` assigns. + pub fn compose_surface_targets( + &mut self, + min_x: f32, + max_x: f32, + min_z: f32, + max_z: f32, + y_lo: f32, + y_hi: f32, + base: Option<&Terrain>, + log: &mut Vec, + target: &mut dyn FnMut(f32, f32) -> (Option, Option), + ) { + if self.chunks.is_empty() { + return; + } + let cell = self.cell; + let span = CHUNK as f32 * cell; + let cols: std::collections::BTreeSet<(i32, i32)> = self + .chunks + .keys() + .filter(|k| { + let x0 = k.x as f32 * span; + let z0 = k.z as f32 * span; + x0 <= max_x && x0 + span >= min_x && z0 <= max_z && z0 + span >= min_z + }) + .map(|k| (k.x, k.z)) + .collect(); + if cols.is_empty() { + return; + } + let ky0 = (y_lo / span).floor() as i32; + let ky1 = (y_hi / span).floor() as i32; + for &(kx, kz) in &cols { + for ky in ky0..=ky1 { + self.materialize(ChunkKey { x: kx, y: ky, z: kz }, base, log); + } + } + let keys: Vec = self + .chunks + .keys() + .filter(|k| cols.contains(&(k.x, k.z))) + .copied() + .collect(); + let mut changed_keys: Vec = Vec::new(); + for key in keys { + let b = key.base(); + let Some(chunk) = self.chunks.get_mut(&key) else { + continue; + }; + let mut changed = false; + for lz in 0..CHUNK { + for lx in 0..CHUNK { + let x = (b[0] + lx) as f32 * cell; + let z = (b[2] + lz) as f32 * cell; + if x < min_x || x > max_x || z < min_z || z > max_z { + continue; + } + let (raise, lower) = target(x, z); + if raise.is_none() && lower.is_none() { + continue; + } + for ly in 0..CHUNK { + let y = (b[1] + ly) as f32 * cell; + let at = site_index(lx, ly, lz); + let old_d = chunk.density[at]; + let old_m = chunk.material[at]; + let mut nd = old_d; + let mut nm = old_m; + if let Some(t) = raise { + let q = Self::quantize((y - t) / cell); + if q < nd { + nd = q; + } + if nd < 0 && old_d >= 0 { + nm = BASE_MATERIAL; + } + } + if let Some(t) = lower { + let q = Self::quantize((y - t) / cell); + if q > nd { + nd = q; + } + if nd >= 0 { + nm = 0; + } + } + if nd != old_d || nm != old_m { + chunk.density[at] = nd; + chunk.material[at] = nm; + changed = true; + } + } + } + } + if changed { + chunk.rev += 1; + changed_keys.push(key); + } + } + for key in changed_keys { + for dx in -1..=1 { + for dy in -1..=1 { + for dz in -1..=1 { + let k = ChunkKey { x: key.x + dx, y: key.y + dy, z: key.z + dz }; + if self.chunks.contains_key(&k) { + self.mark_dirty(k); + } + } + } + } + self.punch_rev = None; } } @@ -864,6 +1169,9 @@ impl VoxelField { self.punch_rev = None; self.pending_ops.clear(); self.fresh_chunks.clear(); + // Landforms are player state like the chunks: the re-eval rebuilds + // the authored heightfield, then the list replays onto it. + self.land_replay_pending = !self.land_ops.is_empty(); } // ── meshing (T2/T3/T7) ────────────────────────────────────────────── @@ -940,8 +1248,22 @@ impl VoxelField { } None => match base { BaseSample::World(terrain) => { - let d = self.base_density(s, terrain); - (d, if d < 0 { BASE_MATERIAL } else { 0 }) + let w = self.site_world(s); + let h = terrain + .and_then(|t| t.height_at(w.x, w.z)) + .unwrap_or(0.0); + let d = Self::quantize((w.y - h) / self.cell); + let m = if d < 0 { + // Same topsoil rule as materialize(). + if h - w.y < self.cell * 2.5 { + self.surface_material + } else { + BASE_MATERIAL + } + } else { + 0 + }; + (d, m) } BaseSample::Clamp => { // Clamp into this chunk's own site range. @@ -1518,6 +1840,10 @@ fn punch_chunk( /// so implicit samples clamp) — both sides derive meshes locally; only field /// data crosses the wire. A world without a field returns immediately. pub fn update_world_voxel(world: &mut crate::world::GameWorld, authority: bool) { + // Landform replay: after a re-eval rebuilt the heightfield (or a + // structure snapshot delivered the list), re-apply the recorded macro + // landforms — heightfield only; the chunks already carry their history. + crate::landform::replay_land_ops(world); if world.terrain.is_some() { let needs_punch = match (&world.voxel, &world.terrain) { (Some(v), Some(t)) => v.punch_rev != Some(t.revision), @@ -1641,10 +1967,65 @@ mod tests { } #[test] - fn edits_outside_volumes_are_rejected() { - let mut f = field_with_volume(VoxelMode::Smooth); + fn the_whole_world_is_implicitly_editable() { + // No declared volume at all: the main ground is one world-spanning + // editable volume. An edit far from anywhere materializes exactly + // the chunks under the brush and nothing else. + let mut f = VoxelField::new(0.5); + assert_eq!(f.chunk_count(), 0, "unedited field must store nothing"); dig(&mut f, vec3f(500.0, 0.0, 0.0), 3.0, DigMode::Carve); - assert_eq!(f.chunk_count(), 0, "edit outside every volume materialized"); + assert!(f.chunk_count() > 0, "dig without a volume did not materialize"); + assert!( + f.chunk_count() <= 27, + "dig materialized far beyond the brush: {}", + f.chunk_count() + ); + assert!(f.is_carved_air(vec3f(500.0, -1.0, 0.0)), "carve did not open air"); + } + + #[test] + fn tunnel_materializes_the_capsule_not_the_aabb() { + let mut f = VoxelField::new(0.5); + let mut log = Vec::new(); + // A long diagonal tunnel: the AABB covers ~13×13 chunk columns, the + // capsule itself passes through only a corridor of them. + f.apply_op( + VoxelOp::Tunnel { + from: vec3f(-90.0, -3.0, -90.0), + to: vec3f(90.0, -3.0, 90.0), + r: 2.5, + }, + None, + true, + true, + &mut log, + ); + assert!(log.is_empty(), "{log:?}"); + let n = f.chunk_count(); + assert!(n > 0, "tunnel materialized nothing"); + assert!(n < 200, "tunnel swallowed its AABB: {n} chunks"); + // The bore is open along the segment, closed off to the side. + assert!(f.is_carved_air(vec3f(0.0, -3.0, 0.0)), "bore not open"); + assert!(!f.is_carved_air(vec3f(0.0, -3.0, 40.0)), "carved far off axis"); + } + + #[test] + fn surface_seam_reports_pits_and_mounds_but_not_deep_tunnels() { + let mut f = VoxelField::new(0.5); + // Base = ground plane y 0. A pit at the surface owns its column. + dig(&mut f, vec3f(0.0, 0.0, 0.0), 3.0, DigMode::Carve); + let pit = f.surface_at(0.0, 0.0, 0.0).expect("pit does not own surface"); + assert!(pit < -1.0, "pit surface {pit} not below ground"); + // A mound filled on top of the surface answers with its top. + dig(&mut f, vec3f(20.0, 1.0, 0.0), 3.0, DigMode::Fill); + let mound = f.surface_at(20.0, 0.0, 0.0).expect("mound does not own surface"); + assert!(mound > 1.0, "mound surface {mound} not above ground"); + // A deep tunnel far below leaves the surface to the heightfield. + dig(&mut f, vec3f(-40.0, -30.0, 0.0), 3.0, DigMode::Carve); + assert!( + f.surface_at(-40.0, 0.0, 0.0).is_none(), + "deep tunnel stole surface ownership" + ); } #[test] diff --git a/libs/sim/src/world.rs b/libs/sim/src/world.rs index 6cbcd4b34..bb962957b 100644 --- a/libs/sim/src/world.rs +++ b/libs/sim/src/world.rs @@ -219,14 +219,34 @@ impl GameWorld { /// grounded on the terrain today grounds on a map's floor tomorrow /// without learning what a map is. pub fn ground_height_at(&self, x: f32, z: f32, near_y: f32) -> Option { - if let Some(t) = self.terrain.as_ref() { - if let Some(h) = t.height_at(x, z) { - return Some(h); - } + if let Some(h) = self.surface_height_at(x, z) { + return Some(h); } self.level.as_ref().and_then(|level| level.ground_under(x, z, near_y)) } + /// THE world-surface seam: composed ground height at (x, z) — + /// heightfield where no voxel chunk owns the surface, voxel surface + /// where one does (a dug pit answers with its floor, a filled mound or + /// a landform raised over carved ground with its top; a deep tunnel + /// under an untouched ridge changes nothing). Everything that grounds + /// gameplay on "the terrain" — spawns, draping, scatter, AI ground + /// probes — samples through here so terrain edits compose everywhere + /// at once. `None` outside the heightfield (and outside any voxel + /// ownership): flat/streamed worlds keep their own floor rules. + pub fn surface_height_at(&self, x: f32, z: f32) -> Option { + let base = self.terrain.as_ref().and_then(|t| t.height_at(x, z)); + if let Some(v) = self.voxel.as_deref() { + if v.chunk_count() > 0 { + // No terrain = the voxel base layer's y=0 ground plane. + if let Some(h) = v.surface_at(x, z, base.unwrap_or(0.0)) { + return Some(h); + } + } + } + base + } + /// A world with the canonical starting camera (the values the gamemaker /// widget historically seeded: yaw 0.6, pitch -0.35). pub fn new() -> Self { @@ -537,18 +557,25 @@ impl GameWorld { /// Apply one voxel edit op with full authority: materialize chunks from /// the base heightfield under the brush, mutate, queue for replication. /// The verb layer and the host both come through here, in tick order — - /// which IS the determinism story (mix.md D5: edits are ops). No-op - /// without a field (declare a `terrain_volume` first). + /// which IS the determinism story (mix.md D5: edits are ops). The whole + /// world is implicitly editable: a first edit on a world without a + /// field creates one (default lattice; `game.terrain_volume` still + /// pre-creates with finer cells/palette). Landform ops route to + /// [`crate::landform`], which owns their heightfield/voxel composition. pub fn apply_voxel_op(&mut self, op: crate::voxel::VoxelOp) { + if let crate::voxel::VoxelOp::Landform { .. } = op { + crate::landform::host_apply_landform(self, op); + return; + } let GameWorld { voxel, terrain, log_pending, .. } = self; - if let Some(field) = voxel.as_mut() { - field.apply_op(op, terrain.as_ref(), true, true, log_pending); - } + let field = voxel + .get_or_insert_with(|| Box::new(crate::voxel::VoxelField::new(0.5))); + field.apply_op(op, terrain.as_ref(), true, true, log_pending); } } From 5692fabbdf4797303a58e76e0c3488db91f768a0 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 22:15:45 +0200 Subject: [PATCH 012/417] =?UTF-8?q?sim:=20the=20landform=20world=20proves?= =?UTF-8?q?=20itself=20=E2=80=94=20walker=20through=20the=20tunnel=20inclu?= =?UTF-8?q?ded?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- libs/sim/tests/landform_world.rs | 146 +++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 libs/sim/tests/landform_world.rs diff --git a/libs/sim/tests/landform_world.rs b/libs/sim/tests/landform_world.rs new file mode 100644 index 000000000..184a47150 --- /dev/null +++ b/libs/sim/tests/landform_world.rs @@ -0,0 +1,146 @@ +//! Landform + tunnel + dig at world scale: the acceptance shapes of the +//! unified destructible world, meshed to completion, with hard bounds on +//! how far any mesh vertex or heightfield vertex may stand from the ground. +//! Regression net for the "floating curtain wall" class of bug. + +use makepad_game_sim::voxel::DigMode; +use makepad_game_sim::*; +use makepad_math::*; + +fn rolling_terrain() -> Terrain { + let cells = 97; + let cell_size = 200.0 / 96.0; + let origin = -100.0; + let mut heights = vec![0.0f32; cells * cells]; + for gz in 0..cells { + for gx in 0..cells { + let x = origin + gx as f32 * cell_size; + let z = origin + gz as f32 * cell_size; + heights[gz * cells + gx] = 2.0 + (x * 0.03).sin() + (z * 0.025).cos(); + } + } + Terrain { + cells, + cell_size, + origin, + heights, + colors: vec![vec4f(0.4, 0.6, 0.4, 1.0); cells * cells], + revision: 1, + } +} + +#[test] +fn acceptance_shapes_stay_bounded() { + let mut w = GameWorld::new(); + w.terrain = Some(rolling_terrain()); + // Mirror of the live acceptance script: dig, mountain, hill, tunnel. + let g_dig = w.surface_height_at(-20.0, 10.0).unwrap(); + w.apply_voxel_op(VoxelOp::Dig { + pos: vec3f(-20.0, g_dig, 10.0), + r: 6.0, + mode: DigMode::Carve, + material: 1, + }); + w.apply_voxel_op(VoxelOp::Landform { + pos: vec3f(45.0, w.surface_height_at(45.0, -30.0).unwrap(), -30.0), + kind: LandKind::Mountain.to_u8(), + r: 34.0, + height: 22.0, + seed: 9, + }); + w.apply_voxel_op(VoxelOp::Landform { + pos: vec3f(-55.0, w.surface_height_at(-55.0, -50.0).unwrap(), -50.0), + kind: LandKind::Hill.to_u8(), + r: 24.0, + height: 12.0, + seed: 4, + }); + let my = w.surface_height_at(-55.0, -20.0).unwrap() + 1.4; + w.apply_voxel_op(VoxelOp::Tunnel { + from: vec3f(-55.0, my, -20.0), + to: vec3f(-55.0, my, -80.0), + r: 2.4, + }); + + // Heights stay within base + mountain reach. + let t = w.terrain.as_ref().unwrap(); + let (mut hmin, mut hmax) = (f32::MAX, f32::MIN); + for h in &t.heights { + assert!(h.is_finite(), "non-finite height"); + hmin = hmin.min(*h); + hmax = hmax.max(*h); + } + assert!(hmax < 28.0, "heightfield exploded: max {hmax}"); + assert!(hmin > -10.0, "heightfield exploded: min {hmin}"); + + // Mesh everything, then every voxel mesh vertex must hug the ground + // band — no floating curtain walls in the sky. + for _ in 0..4096 { + update_world_voxel(&mut w, true); + if w.voxel.as_deref().map_or(0, |v| v.dirty_len()) == 0 { + break; + } + } + let field = w.voxel.as_deref().unwrap(); + let chunks = field.chunk_count(); + assert!(chunks > 0, "nothing materialized"); + assert!(chunks < 400, "materialization ran away: {chunks} chunks"); + let mut vmax = f32::MIN; + let mut vmin = f32::MAX; + for mesh in field.meshes.values() { + for v in mesh.verts.chunks_exact(makepad_game_sim::voxel::MESH_VERTEX_FLOATS) { + vmax = vmax.max(v[1]); + vmin = vmin.min(v[1]); + } + } + println!( + "chunks {chunks}, heights {hmin:.2}..{hmax:.2}, mesh y {vmin:.2}..{vmax:.2}" + ); + assert!(vmax < 28.0, "voxel mesh towers into the sky: max y {vmax}"); + assert!(vmin > -30.0, "voxel mesh under the world: min y {vmin}"); + + // The tunnel bore is open air mid-hill. + assert!( + field.is_carved_air(vec3f(-55.0, my, -50.0)), + "tunnel bore closed" + ); + // The seam sees the mountain. + let peak = w.surface_height_at(45.0, -30.0).unwrap(); + assert!(peak > 10.0, "mountain missing from the seam: {peak}"); + + // A walker at the mouth strolls INTO the hill through the bore — under + // the raised ground, not over it (the tunnel is the voxel layer's whole + // point). + let id = { + let mut e = Entity::default(); + w.next_id += 1; + e.id = w.next_id; + e.kind = BodyKind::Mover; + e.pos = vec3f(-55.0, my + 0.1, -16.0); + e.half = vec3f(0.35, 0.85, 0.35); + e.collide = true; + let id = e.id; + w.push_entity(e); + id + }; + let mouth_y = my; + for _ in 0..600 { + if let Some(e) = w.entity_mut(id) { + e.vel.x = 0.0; + e.vel.z = -3.0; + } + step_world(&mut w); + } + let e = w.entity(id).unwrap(); + assert!( + e.pos.z < -30.0, + "walker never entered the tunnel (z {})", + e.pos.z + ); + let hill_here = w.terrain.as_ref().unwrap().height_at(e.pos.x, e.pos.z).unwrap(); + assert!( + e.pos.y < mouth_y + 2.5 && e.pos.y < hill_here - 1.0, + "walker went OVER the hill instead of through it (y {} vs hill {hill_here})", + e.pos.y + ); +} From b7fe32cf0745fd64acffb3dfe587bded00ef63a0 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 22:15:45 +0200 Subject: [PATCH 013/417] game brief: a destructible world, path-edited railways, and models that load now MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The doctrine catches up with the engine: landforms and tunnels are one call and digging works anywhere; railways and roads are edited by their path points (crossings generate, styles switch, any model drives); freshly modeled aliases are live immediately — never park a display substitute. Co-Authored-By: Claude Fable 5 --- libs/asset/chat/context/game.md | 56 ++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/libs/asset/chat/context/game.md b/libs/asset/chat/context/game.md index 49b51ecab..db2747243 100644 --- a/libs/asset/chat/context/game.md +++ b/libs/asset/chat/context/game.md @@ -64,6 +64,11 @@ turn does not wait for it. Tell the player it is generating and will appear in the library when finished; never claim it is ready or reference a future alias in the live world yet. The player can see and cancel every costly job in the status area below chat. You may still build a primitive stand-in now. +model.build is different: it finishes within the turn and a successful +build's alias (`gen/csg/`) is in the live model library the moment +the tool answers — place THAT alias now via world.place / world.spawn / +game.model (or drive it with game.train({model})). Never park a catalog +look-alike as a "display" substitute for an object you just modelled. DRIVEABLE CARS: `game.car({pos, model: "kenney/car-kit/", color})` makes a real driveable vehicle — the engine owns the driving physics and @@ -78,20 +83,35 @@ never hand-place their tiles. They are deterministic from seed: `game.dungeon({kit, extent, seed})` build complete layouts. - `game.scatter({models, pos, size, spacing, count, seed})` builds forests or crowds while avoiding earlier roads/buildings. -- `game.road_network({kit, paths})` joins and scales custom road paths. -- `game.racetrack({seed, size, complexity})` returns slots, checkpoints, - start and waypoints. A race's essential shape is: +- `game.road_network({paths: [[vec3,...],...], width})` builds GENERATED + road surfaces — asphalt with markings, graded over the hills with the + ground pressed to match, and a real BRIDGE with piers over anything too + deep to embank. Paths are waypoint lists in world metres: EDIT a road by + moving its waypoints and re-calling. Where a road crosses a railway a + LEVEL CROSSING is generated automatically. +- `game.racetrack({seed, size, complexity})` — a complete circuit as one + generated road surface (true swept corners, graded, bridged) — returns + slots, checkpoints, start and waypoints. A race's essential shape is: let t = game.racetrack({seed: 7}) let car = game.car({model: "kenney/car-kit/race", color: #ff4444}) game.place(car, t.slots[0]) let r = game.car({model: "kenney/car-kit/race", color: #4488ff}) game.place(r, t.slots[1]) game.autodrive(r, {points: t.waypoints, pace: 0.85}) -- `game.traintrack({seed, size})` lays a complete closed RAILWAY from the - train kit — never hand-place track pieces (the joins will not line up; - the generator's are seamless). `game.train({cars})` puts a driveable +- `game.traintrack({seed, size})` lays a complete closed RAILWAY as + generated geometry — ballast, rails and sleepers draped along a smooth + curve, graded to ~3.5% (real cut and fill), becoming a BRIDGE with piers + over gorges and water — never hand-place track pieces. The AUTHORED form + is a path: `game.traintrack({path: [vec3, ...], radius: 12})` lays those + exact waypoints, and the seeded call RETURNS its `waypoints` — so to + edit a railway, inline that list and move points ("move the third curve + east"): same path, same geometry. `style: "monorail"` builds an elevated + beam on pylons from the same call. `game.train({cars})` puts a driveable locomotive with trailing carriages on it: board it like any vehicle, - drive with forward/back only, it cannot leave the rails. A railway's + drive with forward/back only, it cannot leave the rails — and it rides + the graded line, bridges included. `model:`/`carriage:` accept ANY + resolvable model id: a locomotive you just modelled drives the same + railway at its own measured size (front faces -Z). A railway's essential shape is: game.traintrack({seed: 3, size: 90}) game.train({cars: 4}) @@ -164,6 +184,19 @@ game.terrain({size: 160, cells: 65, smooth: true, seed: 3, amp: 8, color: #x3a7d height h; omit it for dry land. Hilly ground: put objects at y ≈ amp, or use amp: 0 where exact placement matters. game.water({min, max, color}) — a wave volume (only when you want water) +THE GROUND IS DESTRUCTIBLE — the whole terrain is ONE editable world; no +setup call needed, edits replicate and survive reload: +game.dig(pos, {r: 3, mode: "carve"|"fill"|"flatten", material}) — sculpt + brush, works ANYWHERE on the map (craters, moats, ramps, buried rooms) +game.landform(pos, {kind: "mountain"|"hill"|"ridge"|"valley"|"crater"|"plateau", r, height, seed}) + — a whole noise-detailed landform in ONE call; it grows from the ground + at (x, z) (pos.y ignored). A mountain is one call, NEVER a loop of digs. +game.tunnel(from, to, {r: 2.5}) — bore a real, walkable, drivable tunnel + through a hill; set mouth heights from `game.ground_y(x, z)` +game.ground_y(x, z) — the LIVE composed surface height (digs, landforms + and tunnels included), the right base for anything you place afterwards +Roads, racetracks and train tracks re-drape onto the edited ground on the +next re-eval: raise a mountain under a road and the road follows it. game.character({pos, model, tint, hue, scale, player: true, view: "third"}) -> id game.player_character({pos, model, tint, hue, scale, speed, jump}) -> id — walker + camera game.model("alias", {pos, yaw, scale, tint, hue, collide, tag}) @@ -261,10 +294,11 @@ EXPLICITLY asks to build something from parts. fountain, cart) `scale: 2`. NEVER give a prop the street scale — a lamp at `scale: 8` is a 30 m tower. Never place kit models unscaled next to people. - STREETS ARE NEVER HAND-LAID: they come from game.city / game.village - / game.racetrack / game.road_network, which apply each kit's measured - scale themselves (a hand-laid road tile next to a real car is 2-3x - too narrow). + STREETS ARE NEVER HAND-LAID: city and village streets come from + game.city / game.village (measured kit tiles at their true scale); + open roads, circuits and railways come from game.road_network / + game.racetrack / game.traintrack, which GENERATE the surface (a + hand-laid road tile next to a real car is 2-3x too narrow). - Layout = a real village: game.village lays the street; 4-6 DIFFERENT complete buildings on both sides facing the street (doors toward it), a small plaza (fantasy-town fountain-round, scale: 2) with trees and a From 929f822ca5e53fcef614cc5fb4cceb609ae8ec46 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 22:20:43 +0200 Subject: [PATCH 014/417] video: the single-frame mp4 encode exists on every platform encode_intra_frame_mp4 was macOS-only, and libs/image_tiles imports it unconditionally, so image-tiles, its example and source-library did not build for Windows (found by a Windows-target cargo check sweep of the workspace; every other crate checks clean). Other platforms now get the same signature answering with an error, the way the rest of this file stubs what it cannot do yet. Co-Authored-By: Claude Fable 5.1 --- platform/video/src/lib.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/platform/video/src/lib.rs b/platform/video/src/lib.rs index 87403fe4b..1a9f5524c 100644 --- a/platform/video/src/lib.rs +++ b/platform/video/src/lib.rs @@ -632,3 +632,25 @@ pub fn encode_intra_frame_mp4( } apple_intra_frame::encode_intra_frame_mp4(nv12, width, height, fps.max(1), bitrate_bps, codec) } + +/// Only the Apple compression session is driven directly today; every other +/// platform answers with an error so a caller (the image-tiles tape baker) +/// can fall back or report, instead of the crate failing to build there. +#[cfg(not(target_os = "macos"))] +pub fn encode_intra_frame_mp4( + _nv12: &[u8], + width: u32, + height: u32, + _fps: u32, + _bitrate_bps: u32, + _codec: VideoFileCodec, +) -> Result, VideoFileError> { + if width == 0 || height == 0 || width % 2 != 0 || height % 2 != 0 { + return Err(VideoFileError::new(format!( + "invalid frame size {width}x{height} (must be nonzero and even)" + ))); + } + Err(VideoFileError::new( + "single-frame mp4 encode is only implemented on macOS", + )) +} From 294cb9ea475577e5113c63aca971706e62120eb8 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 22:24:40 +0200 Subject: [PATCH 015/417] video: the single-frame mp4 is written on every platform, not stubbed encode_intra_frame_mp4 on Windows and Linux now goes through the platform file encoder (Media Foundation sink writer, GStreamer): one keyframe-only stream, one frame, a scratch file read back and removed. It pays the container machinery the Apple session path avoids, but a tile tape baked on any machine reads on any other, which is what the image-tiles library sits on. A round-trip test encodes a frame and decodes it through the platform decoder on whichever platform runs it. Co-Authored-By: Claude Fable 5.1 --- platform/video/src/lib.rs | 97 +++++++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 10 deletions(-) diff --git a/platform/video/src/lib.rs b/platform/video/src/lib.rs index 1a9f5524c..ec15e8a1e 100644 --- a/platform/video/src/lib.rs +++ b/platform/video/src/lib.rs @@ -633,24 +633,101 @@ pub fn encode_intra_frame_mp4( apple_intra_frame::encode_intra_frame_mp4(nv12, width, height, fps.max(1), bitrate_bps, codec) } -/// Only the Apple compression session is driven directly today; every other -/// platform answers with an error so a caller (the image-tiles tape baker) -/// can fall back or report, instead of the crate failing to build there. +/// The same single-frame mp4 on the other platforms, through the platform +/// file encoder (Media Foundation sink writer on Windows, GStreamer on +/// Linux): one keyframe-only stream, one frame, written to a scratch file +/// and read back. It pays the container machinery the Apple path avoids, +/// but the bytes mean the same thing to every decoder, which is what a +/// tile tape needs — the tape format is not a platform's. #[cfg(not(target_os = "macos"))] pub fn encode_intra_frame_mp4( - _nv12: &[u8], + nv12: &[u8], width: u32, height: u32, - _fps: u32, - _bitrate_bps: u32, - _codec: VideoFileCodec, + fps: u32, + bitrate_bps: u32, + codec: VideoFileCodec, ) -> Result, VideoFileError> { if width == 0 || height == 0 || width % 2 != 0 || height % 2 != 0 { return Err(VideoFileError::new(format!( "invalid frame size {width}x{height} (must be nonzero and even)" ))); } - Err(VideoFileError::new( - "single-frame mp4 encode is only implemented on macOS", - )) + let options = VideoFileEncoderOptions { + codec, + width, + height, + fps_num: fps.max(1), + fps_den: 1, + video_bitrate_bps: bitrate_bps, + audio: None, + keyframe_only: true, + }; + // A scratch path of our own: the sink writers want a file name, and the + // caller wants bytes. Unique per process + call so parallel bakers never + // share one. + static SEQ: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0); + let seq = SEQ.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + let path = std::env::temp_dir().join(format!( + "makepad-intra-{}-{seq}.mp4", + std::process::id() + )); + let text = path.to_string_lossy().to_string(); + let result = (|| { + let mut encoder = VideoFileEncoder::new(&text, options)?; + encoder.push_frame_nv12(nv12, Some(0))?; + encoder.finish()?; + std::fs::read(&path).map_err(|e| VideoFileError::new(format!("read {text}: {e}"))) + })(); + let _ = std::fs::remove_file(&path); + let bytes = result?; + if bytes.is_empty() { + return Err(VideoFileError::new(format!("{text}: encoder wrote no bytes"))); + } + Ok(bytes) +} + +#[cfg(test)] +mod intra_frame_tests { + use super::*; + + /// One frame in, one decodable frame of the same size out — on whichever + /// platform runs the test (the Apple session path or the file-encoder + /// path), so a tape baked on one machine reads on another. + #[test] + fn single_frame_round_trips_through_the_platform_decoder() { + let (w, h) = (64u32, 48u32); + let mut nv12 = vec![0u8; nv12::nv12_frame_size(w, h)]; + for y in 0..h as usize { + for x in 0..w as usize { + nv12[y * w as usize + x] = ((x * 255) / (w as usize - 1)) as u8; + } + } + for v in &mut nv12[(w * h) as usize..] { + *v = 128; + } + let bytes = match encode_intra_frame_mp4(&nv12, w, h, 30, 2_000_000, VideoFileCodec::H265) { + Ok(bytes) => bytes, + Err(e) if e.context.contains("not implemented") => return, + Err(e) => panic!("encode: {e:?}"), + }; + assert!(bytes.len() > 64, "{} bytes", bytes.len()); + assert!( + bytes.windows(4).any(|b| b == b"ftyp") && bytes.windows(4).any(|b| b == b"moov"), + "not an mp4 container" + ); + let path = std::env::temp_dir().join(format!("makepad-intra-test-{}.mp4", std::process::id())); + std::fs::write(&path, &bytes).expect("write"); + let text = path.to_string_lossy().to_string(); + let decoded = (|| { + let mut dec = VideoFileDecoder::open(&text)?; + let frame = dec.next_frame()?.ok_or_else(|| VideoFileError::new("no frame"))?; + let second = dec.next_frame()?; + Ok::<_, VideoFileError>(((frame.width, frame.height), second.is_none())) + })(); + let _ = std::fs::remove_file(&path); + let (size, single) = decoded.expect("decode"); + assert_eq!(size, (w, h)); + assert!(single, "exactly one frame"); + } } From f51b5f3bbfa18da3eb4a08d56e5c4bffc9adf92e Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 22:31:12 +0200 Subject: [PATCH 016/417] ai-body: the crate for the native SAM 3D Body port, with its weights reader makepad-ai-body joins the AI model workspace: the constants of the architecture (DINOv3 ViT-H+/16 at 512, the 6-layer promptable decoder, the 519-wide pose head, the 127-joint / 18439-vertex MHR rig) and the single-file safetensors reader for the Comfy-Org repack, which fails closed on a Meta checkpoint-style header and checks the shapes the port is written for at load. The backbone, decoder and rig modules follow in their own lanes against the spec under local/agent_state/sam3dbody. Co-Authored-By: Claude Fable 5.1 --- libs/ai/Cargo.toml | 1 + libs/ai/models/body/Cargo.toml | 10 ++ libs/ai/models/body/src/lib.rs | 69 +++++++++ libs/ai/models/body/src/weights.rs | 241 +++++++++++++++++++++++++++++ 4 files changed, 321 insertions(+) create mode 100644 libs/ai/models/body/Cargo.toml create mode 100644 libs/ai/models/body/src/lib.rs create mode 100644 libs/ai/models/body/src/weights.rs diff --git a/libs/ai/Cargo.toml b/libs/ai/Cargo.toml index 3f51de0db..32dd9fe8f 100644 --- a/libs/ai/Cargo.toml +++ b/libs/ai/Cargo.toml @@ -15,6 +15,7 @@ members = [ "models/h3", "models/flux", "models/vision", + "models/body", "models/rig", "models/motion", "models/rife", diff --git a/libs/ai/models/body/Cargo.toml b/libs/ai/models/body/Cargo.toml new file mode 100644 index 000000000..cb00b1c3a --- /dev/null +++ b/libs/ai/models/body/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "makepad-ai-body" +version = "0.1.0" +edition = "2021" +description = "SAM 3D Body native port: DINOv3 ViT-H+/16 backbone, promptable pose decoder, MHR rig. Our own implementation on the makepad-ai-common gpu_* surface; weights are the Comfy-Org repack, pulled at runtime." +license = "MIT" + +[dependencies] +makepad-ai-common = { path = "../common" } +makepad-ai-loader = { path = "../../loader" } diff --git a/libs/ai/models/body/src/lib.rs b/libs/ai/models/body/src/lib.rs new file mode 100644 index 000000000..5d21f956c --- /dev/null +++ b/libs/ai/models/body/src/lib.rs @@ -0,0 +1,69 @@ +//! SAM 3D Body, natively: one RGB crop of a person -> the MHR body +//! parameters, 70 keypoints and the posed mesh, on the makepad-ai-common +//! `gpu_*` surface (Metal on Apple, CUDA on Linux/Windows), with no Python +//! and no subprocess. +//! +//! The architecture is implemented after the SAM 3D Body paper +//! (arXiv:2602.15989) and the port spec in `local/agent_state/sam3dbody/` +//! (tensor inventory, op order, formulas), the DINOv3 backbone after the +//! Apache-2.0 HF transformers implementation the TRELLIS conditioner in +//! `makepad-ai-trellis` already follows, and the MHR rig after the +//! Apache-2.0 Momentum Human Rig release. Our code stays MIT with the +//! crate. Weights are SAM-Licensed and pulled at runtime from the +//! Comfy-Org repack (`Comfy-Org/sam-3d-body`); this repository never +//! redistributes them and never fetches facebook/* checkpoints. +//! +//! Module map (each a lane of the port; see the spec for the contract): +//! - [`weights`]: the single-file safetensors reader + architecture check. +//! - `dino`: the ViT-H+/16 backbone (32 blocks, 20 heads, SwiGLU, rope). +//! - `decoder`: prompt encoder, ray conditioning, the 6-layer promptable +//! decoder with per-layer pose refinement, the pose/camera/hand-box heads. +//! - `mhr`: the rig — parameter transform, kinematics, blendshapes, pose +//! correctives, linear blend skinning, keypoint regression. + +pub use makepad_ai_common::backend; +pub use makepad_ai_common::error; +pub use makepad_ai_common::{DiffusionError, Result}; + +pub mod weights; + +/// Model input: the person crop the backbone sees. +pub const IMAGE_SIZE: usize = 512; +/// Backbone patch size; `IMAGE_SIZE / PATCH` = 32 patches a side. +pub const PATCH: usize = 16; +pub const PATCHES_SIDE: usize = IMAGE_SIZE / PATCH; +pub const NUM_PATCHES: usize = PATCHES_SIDE * PATCHES_SIDE; +/// Backbone width, depth, heads, SwiGLU hidden, prefix rows (cls + 4). +pub const DINO_DIM: usize = 1280; +pub const DINO_DEPTH: usize = 32; +pub const DINO_HEADS: usize = 20; +pub const DINO_HEAD_DIM: usize = 64; +pub const DINO_FFN: usize = 5120; +pub const DINO_PREFIX_TOKENS: usize = 5; +pub const DINO_NORM_EPS: f32 = 1e-5; +pub const DINO_ROPE_BASE: f32 = 100.0; +/// Decoder token width, attention inner width, heads, FFN width, depth. +pub const DEC_DIM: usize = 1024; +pub const DEC_INNER: usize = 512; +pub const DEC_HEADS: usize = 8; +pub const DEC_FFN: usize = 1024; +pub const DEC_DEPTH: usize = 6; +pub const DEC_NORM_EPS: f32 = 1e-6; +/// Pose head output: 6 (global rot 6d) + 260 (body pose continuous) + 45 +/// (shape) + 28 (scale) + 108 (two hands x 54) + 72 (expression). +pub const NPOSE: usize = 519; +pub const NCAM: usize = 3; +pub const BODY_CONT_DIM: usize = 260; +pub const NUM_SHAPE: usize = 45; +pub const NUM_SCALE: usize = 28; +pub const NUM_HAND: usize = 54; +pub const NUM_EXPR: usize = 72; +pub const NUM_KEYPOINTS: usize = 70; +/// MHR rig sizes. +pub const MHR_JOINTS: usize = 127; +pub const MHR_VERTS: usize = 18439; +pub const MHR_FACES: usize = 36874; +pub const MHR_MODEL_PARAMS: usize = 249; +pub const MHR_JOINT_PARAMS: usize = 889; +pub const MHR_KEYPOINTS_ALL: usize = 308; +pub const ROPE_HALF: usize = DINO_HEAD_DIM / 2; diff --git a/libs/ai/models/body/src/weights.rs b/libs/ai/models/body/src/weights.rs new file mode 100644 index 000000000..88c391799 --- /dev/null +++ b/libs/ai/models/body/src/weights.rs @@ -0,0 +1,241 @@ +//! The Comfy-Org `sam_3d_body_dinov3_bf16.safetensors` reader. +//! +//! One file holds everything the port needs: the backbone (bf16), the two +//! decoders and heads (f32), and the MHR rig data under `mhr.*` (skeleton, +//! parameter transform, blendshape bases, pose-corrective MLP, skinning). +//! Reads are by name with the shape checked at the call site, so a wrong +//! repack fails at load, not mid-inference. + +use makepad_ai_common::dtype::f16_word_to_f32; +use makepad_ai_common::{DiffusionError, Result}; +use makepad_ai_loader::{MlxDType, MlxSafetensorsHeader}; +use std::path::{Path, PathBuf}; + +/// Production identity (`Comfy-Org/sam-3d-body`, revision +/// 60476aced0b8de0a0e82a318c79a85061cc97434). +pub const WEIGHTS_REPO: &str = "Comfy-Org/sam-3d-body"; +pub const WEIGHTS_PATH: &str = "detection/sam_3d_body_dinov3_bf16.safetensors"; +pub const WEIGHTS_SIZE: u64 = 2_830_737_652; + +pub struct BodyWeights { + pub path: PathBuf, + header: MlxSafetensorsHeader, +} + +impl BodyWeights { + pub fn load(path: impl AsRef) -> Result { + let path = path.as_ref().to_path_buf(); + let header = MlxSafetensorsHeader::load(&path).map_err(|err| { + DiffusionError::model(format!("body weights {}: {err:?}", path.display())) + })?; + let weights = Self { path, header }; + weights.validate_architecture()?; + Ok(weights) + } + + pub fn file_len(&self) -> u64 { + self.header.file_len + } + + pub fn has(&self, name: &str) -> bool { + self.header.tensors.contains_key(name) + } + + pub fn tensor_names(&self) -> impl Iterator { + self.header.tensors.keys() + } + + pub fn shape(&self, name: &str) -> Result> { + let entry = self.entry(name)?; + entry + .shape + .iter() + .map(|&value| { + usize::try_from(value).map_err(|_| { + DiffusionError::model(format!("body tensor {name} dimension {value} exceeds usize")) + }) + }) + .collect() + } + + pub fn dtype(&self, name: &str) -> Result { + Ok(self.entry(name)?.dtype) + } + + pub fn bytes(&self, name: &str) -> Result> { + self.header + .read_tensor_bytes(name) + .map_err(|err| DiffusionError::model(format!("body read tensor {name}: {err:?}"))) + } + + /// Any floating tensor as f32 (bf16/f16 widened exactly). + pub fn f32(&self, name: &str) -> Result> { + let dtype = self.dtype(name)?; + let bytes = self.bytes(name)?; + let values = match dtype { + MlxDType::F16 => bytes + .chunks_exact(2) + .map(|c| f16_word_to_f32(u16::from_le_bytes([c[0], c[1]]))) + .collect(), + MlxDType::BF16 => bytes + .chunks_exact(2) + .map(|c| f32::from_bits(u32::from(u16::from_le_bytes([c[0], c[1]])) << 16)) + .collect(), + MlxDType::F32 => bytes + .chunks_exact(4) + .map(|c| f32::from_le_bytes([c[0], c[1], c[2], c[3]])) + .collect(), + other => { + return Err(DiffusionError::model(format!( + "body tensor {name} has unsupported floating dtype {other:?}" + ))) + } + }; + Ok(values) + } + + pub fn f32_shaped(&self, name: &str, expected: &[usize]) -> Result> { + self.expect_shape(name, expected)?; + self.f32(name) + } + + /// bf16 words verbatim (the backbone linears go to the GPU as bf16). + pub fn bf16_words(&self, name: &str) -> Result> { + match self.dtype(name)? { + MlxDType::BF16 => Ok(self + .bytes(name)? + .chunks_exact(2) + .map(|c| u16::from_le_bytes([c[0], c[1]])) + .collect()), + other => Err(DiffusionError::model(format!( + "body tensor {name} is {other:?}, expected bf16" + ))), + } + } + + /// Any integer tensor widened to i64 (`mhr.*` indices, faces). + pub fn i64(&self, name: &str) -> Result> { + let dtype = self.dtype(name)?; + let bytes = self.bytes(name)?; + let values = match dtype { + MlxDType::I32 => bytes + .chunks_exact(4) + .map(|c| i64::from(i32::from_le_bytes([c[0], c[1], c[2], c[3]]))) + .collect(), + MlxDType::I64 => bytes + .chunks_exact(8) + .map(|c| i64::from_le_bytes([c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]])) + .collect(), + MlxDType::Bool | MlxDType::U8 => bytes.iter().map(|&b| i64::from(b)).collect(), + other => { + return Err(DiffusionError::model(format!( + "body tensor {name} has unsupported integer dtype {other:?}" + ))) + } + }; + Ok(values) + } + + pub fn i64_shaped(&self, name: &str, expected: &[usize]) -> Result> { + self.expect_shape(name, expected)?; + self.i64(name) + } + + pub fn expect_shape(&self, name: &str, expected: &[usize]) -> Result<()> { + let shape = self.shape(name)?; + if shape != expected { + return Err(DiffusionError::model(format!( + "body tensor {name} shape {shape:?}, expected {expected:?}" + ))); + } + Ok(()) + } + + fn entry(&self, name: &str) -> Result<&makepad_ai_loader::MlxTensorEntry> { + self.header.tensors.get(name).ok_or_else(|| { + DiffusionError::model(format!( + "body tensor {name} missing from {}", + self.path.display() + )) + }) + } + + fn expect(&self, name: &str, dtype: MlxDType, shape: &[usize]) -> Result<()> { + let actual_dtype = self.dtype(name)?; + let actual_shape = self.shape(name)?; + if actual_dtype != dtype || actual_shape != shape { + return Err(DiffusionError::model(format!( + "body tensor {name} is {actual_dtype:?} {actual_shape:?}, expected {dtype:?} {shape:?}" + ))); + } + Ok(()) + } + + /// Fail closed on anything but the Comfy-Org repack: the HF-transformers + /// backbone naming (`backbone.layer.N.attention.q_proj`), the bundled + /// `mhr.*` rig, the body decoder and heads at the shapes the port is + /// written for. A Meta `.ckpt`-style header (`backbone.encoder.blocks`) + /// is refused by name. + fn validate_architecture(&self) -> Result<()> { + use crate::*; + if self.has("backbone.encoder.blocks.0.attn.qkv.weight") { + return Err(DiffusionError::model( + "body weights refused a Meta checkpoint-style header; only the Comfy-Org repack is accepted", + )); + } + self.expect("backbone.embeddings.cls_token", MlxDType::BF16, &[1, 1, DINO_DIM])?; + self.expect("backbone.embeddings.register_tokens", MlxDType::BF16, &[1, 4, DINO_DIM])?; + self.expect( + "backbone.embeddings.patch_embeddings.weight", + MlxDType::BF16, + &[DINO_DIM, 3, PATCH, PATCH], + )?; + for i in [0, DINO_DEPTH - 1] { + self.expect( + &format!("backbone.layer.{i}.attention.q_proj.weight"), + MlxDType::BF16, + &[DINO_DIM, DINO_DIM], + )?; + self.expect( + &format!("backbone.layer.{i}.mlp.gate_proj.weight"), + MlxDType::BF16, + &[DINO_FFN, DINO_DIM], + )?; + self.expect( + &format!("backbone.layer.{i}.mlp.down_proj.weight"), + MlxDType::BF16, + &[DINO_DIM, DINO_FFN], + )?; + self.expect(&format!("backbone.layer.{i}.layer_scale1.lambda1"), MlxDType::BF16, &[DINO_DIM])?; + } + self.expect("backbone.norm.weight", MlxDType::BF16, &[DINO_DIM])?; + for i in [0, DEC_DEPTH - 1] { + self.expect( + &format!("decoder.layers.{i}.cross_attn.k_proj.weight"), + MlxDType::F32, + &[DEC_INNER, DINO_DIM], + )?; + self.expect( + &format!("decoder.layers.{i}.ffn.layers.0.0.weight"), + MlxDType::F32, + &[DEC_FFN, DEC_DIM], + )?; + } + self.expect("decoder.norm_final.weight", MlxDType::F32, &[DEC_DIM])?; + self.expect("head_pose.proj.layers.1.weight", MlxDType::F32, &[NPOSE, DEC_DIM])?; + self.expect("head_camera.proj.layers.1.weight", MlxDType::F32, &[NCAM, DEC_DIM])?; + self.expect("init_pose.weight", MlxDType::F32, &[1, NPOSE])?; + self.expect("init_to_token_mhr.weight", MlxDType::F32, &[DEC_DIM, NPOSE + NCAM + 3])?; + self.expect("prev_to_token_mhr.weight", MlxDType::F32, &[DEC_DIM, NPOSE + NCAM])?; + self.expect("keypoint_embedding.weight", MlxDType::F32, &[NUM_KEYPOINTS, DEC_DIM])?; + self.expect("ray_cond_emb.conv.weight", MlxDType::F32, &[DINO_DIM, DINO_DIM + 99, 1, 1])?; + self.expect("head_pose.keypoint_mapping", MlxDType::F32, &[MHR_KEYPOINTS_ALL, MHR_VERTS + MHR_JOINTS])?; + self.expect("mhr.base_shape", MlxDType::F32, &[MHR_VERTS, 3])?; + self.expect("mhr.identity_basis", MlxDType::F32, &[NUM_SHAPE, MHR_VERTS, 3])?; + self.expect("mhr.expr_basis", MlxDType::F32, &[NUM_EXPR, MHR_VERTS, 3])?; + self.expect("mhr.param_transform", MlxDType::F32, &[MHR_JOINT_PARAMS, MHR_MODEL_PARAMS])?; + self.expect("mhr.skel_joint_parents", MlxDType::I32, &[MHR_JOINTS])?; + self.expect("mhr.lbs_inverse_bind_pose", MlxDType::F32, &[MHR_JOINTS, 8])?; + Ok(()) + } +} From 8211ae6d85241b021bb559f19d73ff41027bce29 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 22:51:19 +0200 Subject: [PATCH 017/417] ai-body: the MHR rig and the pose head's parameter decoding, oracle-exact mhr.rs is the Momentum Human Rig on the CPU: blendshapes, the 889x249 parameter transform, parents-first similarity kinematics (x,y,z,w quaternions, Rz Ry Rx eulers, 2^s scales), the sparse-then-dense pose corrective MLP over joints 2.., linear blend skinning and the 308-row keypoint regression. pose.rs decodes the 519-wide head output: 6d rotations, the 23 ball / 58 hinge / 6 translation body layout, the mixed-dof hand layout, scale and hand component bases, the camera translation and the perspective projection. Against the reference oracle: vertices within 1e-4 cm with correctives on, keypoints within 1e-6 m, rig parameters within 1e-7. Two conventions the spec could not settle on paper are now settled by the fixture: the head's global rotation triple arrives Z,Y,X-ordered, and the corrective features start at joint 2 (750 wide). Fixture tests skip cleanly without the oracle directory or the weights. Co-Authored-By: Claude Fable 5.1 --- libs/ai/models/body/src/fixture.rs | 101 ++++ libs/ai/models/body/src/lib.rs | 5 + libs/ai/models/body/src/mhr.rs | 725 +++++++++++++++++++++++++++++ libs/ai/models/body/src/pose.rs | 473 +++++++++++++++++++ 4 files changed, 1304 insertions(+) create mode 100644 libs/ai/models/body/src/fixture.rs create mode 100644 libs/ai/models/body/src/mhr.rs create mode 100644 libs/ai/models/body/src/pose.rs diff --git a/libs/ai/models/body/src/fixture.rs b/libs/ai/models/body/src/fixture.rs new file mode 100644 index 000000000..81726bed0 --- /dev/null +++ b/libs/ai/models/body/src/fixture.rs @@ -0,0 +1,101 @@ +//! Optional oracle fixture reader used only by tests. + +use std::path::{Path, PathBuf}; +use std::sync::OnceLock; + +use crate::mhr::MhrRig; +use crate::weights::BodyWeights; + +pub fn oracle_dir() -> Option { + Path::new(env!("CARGO_MANIFEST_DIR")) + .ancestors() + .map(|root| root.join("local/agent_state/sam3dbody/oracle")) + .find(|candidate| candidate.is_dir()) +} + +/// Load `.f32` and its shape from the oracle manifest. +pub fn load(name: &str) -> Option<(Vec, Vec)> { + let root = oracle_dir()?; + let manifest = std::fs::read_to_string(root.join("manifest.json")).ok()?; + let shape = manifest_shape(&manifest, name)?; + let bytes = std::fs::read(root.join(format!("{name}.f32"))).ok()?; + if bytes.len() % 4 != 0 { + return None; + } + let values: Vec = bytes + .chunks_exact(4) + .map(|bytes| f32::from_le_bytes(bytes.try_into().unwrap())) + .collect(); + let expected = shape.iter().try_fold(1usize, |count, &dimension| { + count.checked_mul(dimension) + })?; + (values.len() == expected).then_some((shape, values)) +} + +pub fn weights_path() -> Option { + let root = oracle_dir()?; + let value = std::fs::read_to_string(root.join("weights_path.txt")).ok()?; + let path = PathBuf::from(value.trim()); + let path = if path.is_absolute() { path } else { root.join(path) }; + path.is_file().then_some(path) +} + +pub fn rig() -> Option<&'static MhrRig> { + static RIG: OnceLock> = OnceLock::new(); + RIG.get_or_init(|| { + let path = weights_path()?; + let weights = match BodyWeights::load(path) { + Ok(weights) => weights, + Err(err) => { + eprintln!("fixture rig: weights failed to load: {err:?}"); + return None; + } + }; + match MhrRig::load(&weights) { + Ok(rig) => Some(rig), + Err(err) => { + eprintln!("fixture rig: MHR rig failed to load: {err:?}"); + None + } + } + }) + .as_ref() +} + +fn manifest_shape(manifest: &str, name: &str) -> Option> { + let key = format!("\"{name}\""); + let entry = manifest.get(manifest.find(&key)? + key.len()..)?; + let entry = entry.get(entry.find(':')? + 1..)?.trim_start(); + + // Accepted oracle encodings are `[[dims], "f32"]` and + // `{"shape":[dims], "dtype":"f32"}`. + let shape_text = if entry.starts_with('[') { + let nested = entry.get(1..)?.trim_start(); + nested.get(nested.find('[')? + 1..)? + } else { + let shape_key = entry.find("\"shape\"")?; + let after_key = entry.get(shape_key + "\"shape\"".len()..)?; + after_key.get(after_key.find('[')? + 1..)? + }; + let shape_text = shape_text.get(..shape_text.find(']')?)?; + if shape_text.trim().is_empty() { + return Some(Vec::new()); + } + shape_text + .split(',') + .map(|value| value.trim().parse::().ok()) + .collect() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parses_both_supported_manifest_encodings() { + let pairs = r#"{"x":[[1, 45],"f32"]}"#; + assert_eq!(manifest_shape(pairs, "x"), Some(vec![1, 45])); + let object = r#"{"x":{"shape":[2,3,4],"dtype":"float32"}}"#; + assert_eq!(manifest_shape(object, "x"), Some(vec![2, 3, 4])); + } +} diff --git a/libs/ai/models/body/src/lib.rs b/libs/ai/models/body/src/lib.rs index 5d21f956c..4760ece0e 100644 --- a/libs/ai/models/body/src/lib.rs +++ b/libs/ai/models/body/src/lib.rs @@ -26,6 +26,11 @@ pub use makepad_ai_common::error; pub use makepad_ai_common::{DiffusionError, Result}; pub mod weights; +pub mod mhr; +pub mod pose; + +#[cfg(test)] +pub mod fixture; /// Model input: the person crop the backbone sees. pub const IMAGE_SIZE: usize = 512; diff --git a/libs/ai/models/body/src/mhr.rs b/libs/ai/models/body/src/mhr.rs new file mode 100644 index 000000000..e242f3a71 --- /dev/null +++ b/libs/ai/models/body/src/mhr.rs @@ -0,0 +1,725 @@ +//! CPU implementation of the Momentum Human Rig forward pass. + +use crate::weights::BodyWeights; +use crate::{ + DiffusionError, Result, MHR_JOINTS, MHR_JOINT_PARAMS, MHR_KEYPOINTS_ALL, + MHR_MODEL_PARAMS, MHR_VERTS, NUM_EXPR, NUM_SCALE, NUM_SHAPE, +}; + +const XYZ: usize = 3; +const STATE_WIDTH: usize = 8; +const JOINT_PARAM_WIDTH: usize = 7; +// Corrective features cover joints 2.. (the root and the first child carry no +// pose-corrective term): 125 joints x 6. +const POSE_CORR_FIRST_JOINT: usize = 2; +const POSE_FEATURES: usize = (MHR_JOINTS - POSE_CORR_FIRST_JOINT) * 6; +const POSE_HIDDEN: usize = 3000; +const LBS_ENTRIES: usize = 51337; +const POSE_SPARSE_ENTRIES: usize = 53136; + +pub struct MhrRig { + pub base_shape: Vec, + pub identity_basis: Vec, + pub expr_basis: Vec, + pub param_transform: Vec, + pub skel_joint_parents: Vec, + pub skel_joint_prerotations: Vec, + pub skel_joint_translation_offsets: Vec, + pub skel_pmi: Vec, + pub skel_pmi_buffer_sizes: Vec, + pub lbs_inverse_bind_pose: Vec, + pub lbs_skin_indices: Vec, + pub lbs_skin_weights: Vec, + pub lbs_vert_indices: Vec, + pub pose_corr_sparse_indices: Vec, + pub pose_corr_sparse_weight: Vec, + pub pose_corr_sparse_shape: Vec, + pub pose_corr_weight: Vec, + pub keypoint_mapping: Vec, + + pub(crate) scale_mean: Vec, + pub(crate) scale_comps: Vec, + pub(crate) hand_pose_mean: Vec, + pub(crate) hand_pose_comps: Vec, + pub(crate) hand_joint_idxs_left: Vec, + pub(crate) hand_joint_idxs_right: Vec, + + keypoint_row_offsets: Vec, + keypoint_columns: Vec, + keypoint_values: Vec, +} + +#[derive(Clone, Debug)] +pub struct MhrOutput { + pub verts: Vec, + pub skel_state: Vec, + pub keypoints308: Vec, +} + +impl MhrRig { + pub fn load(weights: &BodyWeights) -> Result { + let base_shape = weights.f32_shaped("mhr.base_shape", &[MHR_VERTS, XYZ])?; + let identity_basis = + weights.f32_shaped("mhr.identity_basis", &[NUM_SHAPE, MHR_VERTS, XYZ])?; + let expr_basis = + weights.f32_shaped("mhr.expr_basis", &[NUM_EXPR, MHR_VERTS, XYZ])?; + let param_transform = weights.f32_shaped( + "mhr.param_transform", + &[MHR_JOINT_PARAMS, MHR_MODEL_PARAMS], + )?; + let skel_joint_parents = + weights.i64_shaped("mhr.skel_joint_parents", &[MHR_JOINTS])?; + let skel_joint_prerotations = + weights.f32_shaped("mhr.skel_joint_prerotations", &[MHR_JOINTS, 4])?; + let skel_joint_translation_offsets = weights.f32_shaped( + "mhr.skel_joint_translation_offsets", + &[MHR_JOINTS, XYZ], + )?; + let skel_pmi = weights.i64_shaped("mhr.skel_pmi", &[2, 266])?; + let skel_pmi_buffer_sizes = + weights.i64_shaped("mhr.skel_pmi_buffer_sizes", &[4])?; + let lbs_inverse_bind_pose = + weights.f32_shaped("mhr.lbs_inverse_bind_pose", &[MHR_JOINTS, STATE_WIDTH])?; + let lbs_skin_indices = u32_tensor( + weights, + "mhr.lbs_skin_indices", + &[LBS_ENTRIES], + MHR_JOINTS, + )?; + let lbs_skin_weights = + weights.f32_shaped("mhr.lbs_skin_weights", &[LBS_ENTRIES])?; + let lbs_vert_indices = u32_tensor( + weights, + "mhr.lbs_vert_indices", + &[LBS_ENTRIES], + MHR_VERTS, + )?; + let pose_corr_sparse_indices = u32_tensor( + weights, + "mhr.pose_corr_sparse_indices", + &[2, POSE_SPARSE_ENTRIES], + usize::MAX, + )?; + let pose_corr_sparse_weight = weights.f32_shaped( + "mhr.pose_corr_sparse_weight", + &[POSE_SPARSE_ENTRIES], + )?; + let pose_corr_sparse_shape = + weights.i64_shaped("mhr.pose_corr_sparse_shape", &[2])?; + if pose_corr_sparse_shape != [POSE_HIDDEN as i64, POSE_FEATURES as i64] { + return Err(DiffusionError::model(format!( + "mhr.pose_corr_sparse_shape is {pose_corr_sparse_shape:?}, expected [{POSE_HIDDEN}, {POSE_FEATURES}]" + ))); + } + for entry in 0..POSE_SPARSE_ENTRIES { + let row = pose_corr_sparse_indices[entry] as usize; + let column = pose_corr_sparse_indices[POSE_SPARSE_ENTRIES + entry] as usize; + if row >= POSE_HIDDEN || column >= POSE_FEATURES { + return Err(DiffusionError::model(format!( + "mhr.pose_corr_sparse_indices entry {entry} is ({row}, {column})" + ))); + } + } + let pose_corr_weight = weights.f32_shaped( + "mhr.pose_corr_weight", + &[MHR_VERTS * XYZ, POSE_HIDDEN], + )?; + let keypoint_mapping = weights.f32_shaped( + "head_pose.keypoint_mapping", + &[MHR_KEYPOINTS_ALL, MHR_VERTS + MHR_JOINTS], + )?; + + let scale_mean = weights.f32_shaped("head_pose.scale_mean", &[68])?; + let scale_comps = weights.f32_shaped("head_pose.scale_comps", &[NUM_SCALE, 68])?; + let hand_pose_mean = weights.f32_shaped("head_pose.hand_pose_mean", &[54])?; + let hand_pose_comps = weights.f32_shaped("head_pose.hand_pose_comps", &[54, 54])?; + let hand_joint_idxs_left = + u32_tensor(weights, "head_pose.hand_joint_idxs_left", &[27], 136)?; + let hand_joint_idxs_right = + u32_tensor(weights, "head_pose.hand_joint_idxs_right", &[27], 136)?; + + validate_parents(&skel_joint_parents)?; + let (keypoint_row_offsets, keypoint_columns, keypoint_values) = + compress_mapping(&keypoint_mapping); + + Ok(Self { + base_shape, + identity_basis, + expr_basis, + param_transform, + skel_joint_parents, + skel_joint_prerotations, + skel_joint_translation_offsets, + skel_pmi, + skel_pmi_buffer_sizes, + lbs_inverse_bind_pose, + lbs_skin_indices, + lbs_skin_weights, + lbs_vert_indices, + pose_corr_sparse_indices, + pose_corr_sparse_weight, + pose_corr_sparse_shape, + pose_corr_weight, + keypoint_mapping, + scale_mean, + scale_comps, + hand_pose_mean, + hand_pose_comps, + hand_joint_idxs_left, + hand_joint_idxs_right, + keypoint_row_offsets, + keypoint_columns, + keypoint_values, + }) + } + + /// Build unposed vertices in rig-space centimetres. + pub fn rest_vertices(&self, identity: &[f32; 45], expr: &[f32; 72]) -> Vec { + let vertex_values = MHR_VERTS * XYZ; + let mut output = self.base_shape.clone(); + for (basis, &coefficient) in identity.iter().enumerate() { + if coefficient == 0.0 { + continue; + } + let source = &self.identity_basis[basis * vertex_values..(basis + 1) * vertex_values]; + for (target, &value) in output.iter_mut().zip(source) { + *target += coefficient * value; + } + } + for (basis, &coefficient) in expr.iter().enumerate() { + if coefficient == 0.0 { + continue; + } + let source = &self.expr_basis[basis * vertex_values..(basis + 1) * vertex_values]; + for (target, &value) in output.iter_mut().zip(source) { + *target += coefficient * value; + } + } + output + } + + pub fn joint_params(&self, model_params: &[f32]) -> Vec { + assert_eq!( + model_params.len(), + MHR_MODEL_PARAMS, + "MHR model parameters must contain 249 values" + ); + let mut output = vec![0.0; MHR_JOINT_PARAMS]; + for (row, target) in output.iter_mut().enumerate() { + let weights = &self.param_transform + [row * MHR_MODEL_PARAMS..(row + 1) * MHR_MODEL_PARAMS]; + *target = dot(weights, model_params); + } + output + } + + /// Evaluate parent-first similarity transforms as `(t3, q_xyzw4, s)`. + pub fn skeleton_state(&self, joint_params: &[f32]) -> Vec { + assert_eq!( + joint_params.len(), + MHR_JOINT_PARAMS, + "MHR joint parameters must contain 889 values" + ); + let mut output = vec![0.0; MHR_JOINTS * STATE_WIDTH]; + for joint in 0..MHR_JOINTS { + let param = &joint_params + [joint * JOINT_PARAM_WIDTH..(joint + 1) * JOINT_PARAM_WIDTH]; + let offset = &self.skel_joint_translation_offsets[joint * XYZ..joint * XYZ + XYZ]; + let local_t = [offset[0] + param[0], offset[1] + param[1], offset[2] + param[2]]; + let prerotation = self.skel_joint_prerotations[joint * 4..joint * 4 + 4] + .try_into() + .unwrap(); + let local_q = quat_mul(prerotation, euler_zyx_quat([param[3], param[4], param[5]])); + let local_s = (param[6] * std::f32::consts::LN_2).exp(); + let local = Transform { + t: local_t, + q: local_q, + s: local_s, + }; + let global = if self.skel_joint_parents[joint] < 0 { + local + } else { + let parent = self.skel_joint_parents[joint] as usize; + compose(read_transform(&output, parent), local) + }; + write_transform(&mut output, joint, global); + } + output + } + + /// Compute the pose-dependent displacement in rig-space centimetres. + pub fn pose_correctives(&self, joint_params: &[f32]) -> Vec { + assert_eq!( + joint_params.len(), + MHR_JOINT_PARAMS, + "MHR joint parameters must contain 889 values" + ); + let mut feature = [0.0; POSE_FEATURES]; + for joint in POSE_CORR_FIRST_JOINT..MHR_JOINTS { + let offset = joint * JOINT_PARAM_WIDTH + 3; + let matrix = euler_zyx_matrix([ + joint_params[offset], + joint_params[offset + 1], + joint_params[offset + 2], + ]); + let slot = joint - POSE_CORR_FIRST_JOINT; + let target = &mut feature[slot * 6..slot * 6 + 6]; + target.copy_from_slice(&[ + matrix[0][0] - 1.0, + matrix[1][0], + matrix[2][0], + matrix[0][1], + matrix[1][1] - 1.0, + matrix[2][1], + ]); + } + + let mut hidden = vec![0.0f32; POSE_HIDDEN]; + for entry in 0..POSE_SPARSE_ENTRIES { + let row = self.pose_corr_sparse_indices[entry] as usize; + let column = self.pose_corr_sparse_indices[POSE_SPARSE_ENTRIES + entry] as usize; + hidden[row] += self.pose_corr_sparse_weight[entry] * feature[column]; + } + for value in &mut hidden { + *value = value.max(0.0); + } + + let mut output = vec![0.0; MHR_VERTS * XYZ]; + for (row, target) in output.iter_mut().enumerate() { + let weights = &self.pose_corr_weight[row * POSE_HIDDEN..(row + 1) * POSE_HIDDEN]; + *target = dot_unrolled(weights, &hidden); + } + output + } + + /// Linear blend skin corrected rest vertices with global skeleton states. + pub fn skin(&self, skel_state: &[f32], rest: &[f32]) -> Vec { + assert_eq!(skel_state.len(), MHR_JOINTS * STATE_WIDTH); + assert_eq!(rest.len(), MHR_VERTS * XYZ); + let mut output = vec![0.0; MHR_VERTS * XYZ]; + let mut touched = vec![false; MHR_VERTS]; + for entry in 0..LBS_ENTRIES { + let vertex = self.lbs_vert_indices[entry] as usize; + let joint = self.lbs_skin_indices[entry] as usize; + let global = read_transform(skel_state, joint); + let inverse_bind = read_transform(&self.lbs_inverse_bind_pose, joint); + let transform = compose(global, inverse_bind); + let point = [rest[vertex * 3], rest[vertex * 3 + 1], rest[vertex * 3 + 2]]; + let posed = apply(transform, point); + let weight = self.lbs_skin_weights[entry]; + output[vertex * 3] += weight * posed[0]; + output[vertex * 3 + 1] += weight * posed[1]; + output[vertex * 3 + 2] += weight * posed[2]; + touched[vertex] = true; + } + for (vertex, touched) in touched.into_iter().enumerate() { + if !touched { + output[vertex * 3..vertex * 3 + 3] + .copy_from_slice(&rest[vertex * 3..vertex * 3 + 3]); + } + } + output + } + + /// Regress all 308 keypoints from vertices followed by joint positions. + pub fn keypoints(&self, verts: &[f32], skel_state: &[f32]) -> Vec { + assert_eq!(verts.len(), MHR_VERTS * XYZ); + assert_eq!(skel_state.len(), MHR_JOINTS * STATE_WIDTH); + let mut output = vec![0.0; MHR_KEYPOINTS_ALL * XYZ]; + for row in 0..MHR_KEYPOINTS_ALL { + for entry in self.keypoint_row_offsets[row]..self.keypoint_row_offsets[row + 1] { + let column = self.keypoint_columns[entry] as usize; + let weight = self.keypoint_values[entry]; + if column < MHR_VERTS { + output[row * 3] += weight * verts[column * 3]; + output[row * 3 + 1] += weight * verts[column * 3 + 1]; + output[row * 3 + 2] += weight * verts[column * 3 + 2]; + } else { + let joint = column - MHR_VERTS; + output[row * 3] += weight * skel_state[joint * STATE_WIDTH]; + output[row * 3 + 1] += weight * skel_state[joint * STATE_WIDTH + 1]; + output[row * 3 + 2] += weight * skel_state[joint * STATE_WIDTH + 2]; + } + } + } + output + } + + /// `model_params` is the 204-wide `[pose (136) | scales (68)]` the pose + /// head assembles; the 45 identity-coefficient slots of the 249-wide rig + /// parameter vector are padded with zeros here, as the rig itself does. + /// A 249-wide vector is accepted as-is. + pub fn forward( + &self, + identity: &[f32], + model_params: &[f32], + expr: &[f32], + correctives: bool, + ) -> MhrOutput { + let identity: &[f32; 45] = identity + .try_into() + .expect("MHR identity coefficients must contain 45 values"); + let expr: &[f32; 72] = expr + .try_into() + .expect("MHR expression coefficients must contain 72 values"); + assert!( + model_params.len() == 204 || model_params.len() == MHR_MODEL_PARAMS, + "MHR model parameters must contain 204 or 249 values" + ); + let mut padded = [0.0f32; MHR_MODEL_PARAMS]; + padded[..model_params.len()].copy_from_slice(model_params); + let mut rest = self.rest_vertices(identity, expr); + let joint_params = self.joint_params(&padded); + let skel_state = self.skeleton_state(&joint_params); + if correctives { + let displacement = self.pose_correctives(&joint_params); + for (value, correction) in rest.iter_mut().zip(displacement) { + *value += correction; + } + } + let verts = self.skin(&skel_state, &rest); + let keypoints308 = self.keypoints(&verts, &skel_state); + MhrOutput { + verts, + skel_state, + keypoints308, + } + } +} + +#[derive(Clone, Copy)] +struct Transform { + t: [f32; 3], + q: [f32; 4], + s: f32, +} + +fn compose(parent: Transform, local: Transform) -> Transform { + let rotated = quat_rotate(parent.q, local.t); + Transform { + t: [ + parent.t[0] + parent.s * rotated[0], + parent.t[1] + parent.s * rotated[1], + parent.t[2] + parent.s * rotated[2], + ], + q: quat_mul(parent.q, local.q), + s: parent.s * local.s, + } +} + +fn apply(transform: Transform, point: [f32; 3]) -> [f32; 3] { + let rotated = quat_rotate(transform.q, point); + [ + transform.s * rotated[0] + transform.t[0], + transform.s * rotated[1] + transform.t[1], + transform.s * rotated[2] + transform.t[2], + ] +} + +fn read_transform(values: &[f32], index: usize) -> Transform { + let offset = index * STATE_WIDTH; + Transform { + t: [values[offset], values[offset + 1], values[offset + 2]], + q: [values[offset + 3], values[offset + 4], values[offset + 5], values[offset + 6]], + s: values[offset + 7], + } +} + +fn write_transform(values: &mut [f32], index: usize, transform: Transform) { + let offset = index * STATE_WIDTH; + values[offset..offset + 3].copy_from_slice(&transform.t); + values[offset + 3..offset + 7].copy_from_slice(&transform.q); + values[offset + 7] = transform.s; +} + +fn quat_mul(a: [f32; 4], b: [f32; 4]) -> [f32; 4] { + [ + a[3] * b[0] + a[0] * b[3] + a[1] * b[2] - a[2] * b[1], + a[3] * b[1] - a[0] * b[2] + a[1] * b[3] + a[2] * b[0], + a[3] * b[2] + a[0] * b[1] - a[1] * b[0] + a[2] * b[3], + a[3] * b[3] - a[0] * b[0] - a[1] * b[1] - a[2] * b[2], + ] +} + +fn quat_rotate(q: [f32; 4], point: [f32; 3]) -> [f32; 3] { + let qv = [q[0], q[1], q[2]]; + let uv = cross3(qv, point); + let uuv = cross3(qv, uv); + [ + point[0] + 2.0 * (q[3] * uv[0] + uuv[0]), + point[1] + 2.0 * (q[3] * uv[1] + uuv[1]), + point[2] + 2.0 * (q[3] * uv[2] + uuv[2]), + ] +} + +fn euler_zyx_quat([rx, ry, rz]: [f32; 3]) -> [f32; 4] { + let (sx, cx) = (0.5 * rx).sin_cos(); + let (sy, cy) = (0.5 * ry).sin_cos(); + let (sz, cz) = (0.5 * rz).sin_cos(); + quat_mul( + [0.0, 0.0, sz, cz], + quat_mul([0.0, sy, 0.0, cy], [sx, 0.0, 0.0, cx]), + ) +} + +fn euler_zyx_matrix([rx, ry, rz]: [f32; 3]) -> [[f32; 3]; 3] { + let (sx, cx) = rx.sin_cos(); + let (sy, cy) = ry.sin_cos(); + let (sz, cz) = rz.sin_cos(); + [ + [cz * cy, cz * sy * sx - sz * cx, cz * sy * cx + sz * sx], + [sz * cy, sz * sy * sx + cz * cx, sz * sy * cx - cz * sx], + [-sy, cy * sx, cy * cx], + ] +} + +fn cross3(a: [f32; 3], b: [f32; 3]) -> [f32; 3] { + [ + a[1] * b[2] - a[2] * b[1], + a[2] * b[0] - a[0] * b[2], + a[0] * b[1] - a[1] * b[0], + ] +} + +fn dot(left: &[f32], right: &[f32]) -> f32 { + left.iter().zip(right).map(|(a, b)| a * b).sum() +} + +fn dot_unrolled(left: &[f32], right: &[f32]) -> f32 { + debug_assert_eq!(left.len(), right.len()); + let mut sums = [0.0f32; 8]; + let chunks = left.len() / 8; + for chunk in 0..chunks { + let offset = chunk * 8; + sums[0] += left[offset] * right[offset]; + sums[1] += left[offset + 1] * right[offset + 1]; + sums[2] += left[offset + 2] * right[offset + 2]; + sums[3] += left[offset + 3] * right[offset + 3]; + sums[4] += left[offset + 4] * right[offset + 4]; + sums[5] += left[offset + 5] * right[offset + 5]; + sums[6] += left[offset + 6] * right[offset + 6]; + sums[7] += left[offset + 7] * right[offset + 7]; + } + let mut output: f32 = sums.into_iter().sum(); + for index in chunks * 8..left.len() { + output += left[index] * right[index]; + } + output +} + +fn u32_tensor( + weights: &BodyWeights, + name: &str, + shape: &[usize], + upper_bound: usize, +) -> Result> { + let values = weights.i64_shaped(name, shape)?; + values + .into_iter() + .enumerate() + .map(|(index, value)| { + let value = u32::try_from(value).map_err(|_| { + DiffusionError::model(format!("body tensor {name}[{index}] is negative or exceeds u32")) + })?; + if (value as usize) >= upper_bound { + return Err(DiffusionError::model(format!( + "body tensor {name}[{index}]={value} exceeds bound {upper_bound}" + ))); + } + Ok(value) + }) + .collect() +} + +fn validate_parents(parents: &[i64]) -> Result<()> { + if parents.first() != Some(&-1) { + return Err(DiffusionError::model("MHR skeleton root parent must be -1")); + } + for (joint, &parent) in parents.iter().enumerate().skip(1) { + if parent < 0 || parent as usize >= joint { + return Err(DiffusionError::model(format!( + "MHR joint {joint} parent {parent} is not parents-first" + ))); + } + } + Ok(()) +} + +fn compress_mapping(mapping: &[f32]) -> (Vec, Vec, Vec) { + let columns = MHR_VERTS + MHR_JOINTS; + let mut offsets = Vec::with_capacity(MHR_KEYPOINTS_ALL + 1); + let mut sparse_columns = Vec::new(); + let mut sparse_values = Vec::new(); + offsets.push(0); + for row in 0..MHR_KEYPOINTS_ALL { + for column in 0..columns { + let value = mapping[row * columns + column]; + if value != 0.0 { + sparse_columns.push(column as u32); + sparse_values.push(value); + } + } + offsets.push(sparse_columns.len()); + } + (offsets, sparse_columns, sparse_values) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::fixture; + use std::f32::consts::FRAC_PI_2; + use std::time::Instant; + + fn assert_vec_near(actual: [f32; 3], expected: [f32; 3]) { + for axis in 0..3 { + assert!( + (actual[axis] - expected[axis]).abs() < 2.0e-6, + "axis {axis}: {} != {}", + actual[axis], + expected[axis] + ); + } + } + + #[test] + fn quaternion_layout_and_zyx_order_are_xyzw() { + let q = euler_zyx_quat([0.0, 0.0, FRAC_PI_2]); + assert_vec_near(quat_rotate(q, [1.0, 0.0, 0.0]), [0.0, 1.0, 0.0]); + let euler = [0.27, -0.41, 0.62]; + let q = euler_zyx_quat(euler); + let matrix = euler_zyx_matrix(euler); + for axis in 0..3 { + let mut basis = [0.0; 3]; + basis[axis] = 1.0; + assert_vec_near( + quat_rotate(q, basis), + [matrix[0][axis], matrix[1][axis], matrix[2][axis]], + ); + } + } + + #[test] + fn similarity_composition_applies_child_first() { + let parent = Transform { + t: [2.0, 3.0, 4.0], + q: euler_zyx_quat([0.0, 0.0, FRAC_PI_2]), + s: 2.0, + }; + let child = Transform { + t: [1.0, 0.0, 0.0], + q: [0.0, 0.0, 0.0, 1.0], + s: 0.5, + }; + let combined = compose(parent, child); + assert_vec_near(combined.t, [2.0, 5.0, 4.0]); + assert!((combined.s - 1.0).abs() < 1.0e-6); + assert_vec_near(apply(combined, [1.0, 0.0, 0.0]), [2.0, 6.0, 4.0]); + } + + #[test] + fn corrective_identity_feature_is_zero() { + let matrix = euler_zyx_matrix([0.0, 0.0, 0.0]); + let feature = [ + matrix[0][0] - 1.0, + matrix[1][0], + matrix[2][0], + matrix[0][1], + matrix[1][1] - 1.0, + matrix[2][1], + ]; + assert_eq!(feature, [0.0; 6]); + } + + fn max_abs(left: &[f32], right: &[f32]) -> f32 { + assert_eq!(left.len(), right.len()); + left.iter() + .zip(right) + .map(|(a, b)| (a - b).abs()) + .fold(0.0, f32::max) + } + + #[test] + fn oracle_mhr_forward_with_pose_correctives() { + let Some(rig) = fixture::rig() else { + eprintln!("SKIP oracle_mhr_forward_with_pose_correctives: fixtures or weights absent"); + return; + }; + let Some((_, identity)) = fixture::load("mhrjit_in_shape_0") else { + eprintln!("SKIP oracle_mhr_forward_with_pose_correctives: input fixture absent"); + return; + }; + let Some((_, params)) = fixture::load("mhrjit_in_params_0") else { + eprintln!("SKIP oracle_mhr_forward_with_pose_correctives: input fixture absent"); + return; + }; + let Some((_, expr)) = fixture::load("mhrjit_in_expr_0") else { + eprintln!("SKIP oracle_mhr_forward_with_pose_correctives: input fixture absent"); + return; + }; + let Some((_, expected_verts)) = fixture::load("mhrjit_out_verts_0") else { + eprintln!("SKIP oracle_mhr_forward_with_pose_correctives: output fixture absent"); + return; + }; + let Some((_, expected_skel)) = fixture::load("mhrjit_out_skel_0") else { + eprintln!("SKIP oracle_mhr_forward_with_pose_correctives: output fixture absent"); + return; + }; + + let without = rig.forward(&identity, ¶ms, &expr, false); + let started = Instant::now(); + let with = rig.forward(&identity, ¶ms, &expr, true); + let elapsed = started.elapsed(); + let vert_error = max_abs(&with.verts, &expected_verts); + let skel_error = max_abs(&with.skel_state, &expected_skel); + let corrective_effect = max_abs(&with.verts, &without.verts); + eprintln!( + "MHR corrective forward: {elapsed:?}, vertex max abs {vert_error:.7} cm, skeleton max abs {skel_error:.7}, corrective effect {corrective_effect:.7} cm" + ); + assert!(vert_error <= 1.0e-3, "vertex max abs error {vert_error} cm"); + assert!(skel_error <= 1.0e-3, "skeleton max abs error {skel_error}"); + // The head's keypoint regression on the same step, in metres, before + // the camera-axis flip. + if let Some((_, expected_kp)) = fixture::load("mhr_out_1_0") { + let metres: Vec = with.keypoints308.iter().map(|v| v / 100.0).collect(); + let kp_error = max_abs(&metres, &expected_kp); + eprintln!("MHR 308-keypoint max abs error {kp_error:.7} m"); + assert!(kp_error <= 1.0e-4, "keypoint max abs error {kp_error} m"); + } + assert!( + corrective_effect > 1.0e-5, + "fixture pose did not exercise pose correctives" + ); + } + + #[test] + fn oracle_keypoints_first_70_in_camera_axes() { + let Some(rig) = fixture::rig() else { + eprintln!("SKIP oracle_keypoints_first_70_in_camera_axes: fixtures or weights absent"); + return; + }; + // The final refinement step (5) is what the reference reports. + let Some((_, verts)) = fixture::load("mhrjit_out_verts_5") else { + eprintln!("SKIP oracle_keypoints_first_70_in_camera_axes: MHR fixture absent"); + return; + }; + let Some((_, skel)) = fixture::load("mhrjit_out_skel_5") else { + eprintln!("SKIP oracle_keypoints_first_70_in_camera_axes: MHR fixture absent"); + return; + }; + let Some((_, expected)) = fixture::load("final_pred_keypoints_3d") else { + eprintln!("SKIP oracle_keypoints_first_70_in_camera_axes: final fixture absent"); + return; + }; + let all = rig.keypoints(&verts, &skel); + let mut actual = all[..70 * 3].to_vec(); + for point in actual.chunks_exact_mut(3) { + point[0] /= 100.0; + point[1] /= -100.0; + point[2] /= -100.0; + } + let error = max_abs(&actual, &expected); + eprintln!("MHR first-70 keypoint max abs error {error:.7} m"); + assert!(error <= 1.0e-4, "keypoint max abs error {error} m"); + } +} diff --git a/libs/ai/models/body/src/pose.rs b/libs/ai/models/body/src/pose.rs new file mode 100644 index 000000000..f0663453e --- /dev/null +++ b/libs/ai/models/body/src/pose.rs @@ -0,0 +1,473 @@ +//! Pose-head parameter decoding and camera projection. + +use crate::mhr::MhrRig; + +const BODY_ROTATION_IDXS: [[usize; 3]; 23] = [ + [0, 2, 4], + [6, 8, 10], + [12, 13, 14], + [15, 16, 17], + [18, 19, 20], + [21, 22, 23], + [24, 25, 26], + [27, 28, 29], + [34, 35, 36], + [37, 38, 39], + [44, 45, 46], + [53, 54, 55], + [64, 65, 66], + [85, 69, 73], + [86, 70, 79], + [87, 71, 82], + [88, 72, 76], + [91, 92, 93], + [112, 96, 100], + [113, 97, 106], + [114, 98, 109], + [115, 99, 103], + [130, 131, 132], +]; + +const BODY_HINGE_IDXS: [usize; 58] = [ + 1, 3, 5, 7, 9, 11, 30, 31, 32, 33, 40, 41, 42, 43, 47, 48, 49, 50, 51, 52, + 56, 57, 58, 59, 60, 61, 62, 63, 67, 68, 74, 75, 77, 78, 80, 81, 83, 84, 89, + 90, 94, 95, 101, 102, 104, 105, 107, 108, 110, 111, 116, 117, 118, 119, 120, + 121, 122, 123, +]; + +const HAND_DOFS: [usize; 16] = [3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 2, 3, 1, 1]; + +/// Convert two proposed rotation columns to a row-major rotation matrix. +pub fn rot6d_to_rotmat(value: [f32; 6]) -> [[f32; 3]; 3] { + let a1 = [value[0], value[1], value[2]]; + let a2 = [value[3], value[4], value[5]]; + let b1 = normalize3(a1); + let projection = dot3(b1, a2); + let b2 = normalize3([ + a2[0] - projection * b1[0], + a2[1] - projection * b1[1], + a2[2] - projection * b1[2], + ]); + let b3 = cross3(b1, b2); + [ + [b1[0], b2[0], b3[0]], + [b1[1], b2[1], b3[1]], + [b1[2], b2[2], b3[2]], + ] +} + +/// Extract `(rx, ry, rz)` for `R = Rz(rz) * Ry(ry) * Rx(rx)`. +pub fn rotmat_to_euler_zyx(matrix: [[f32; 3]; 3]) -> [f32; 3] { + let cy = (matrix[0][0] * matrix[0][0] + matrix[1][0] * matrix[1][0]).sqrt(); + let ry = (-matrix[2][0]).atan2(cy); + if cy < 1.0e-6 { + [(-matrix[1][2]).atan2(matrix[1][1]), ry, 0.0] + } else { + [ + matrix[2][1].atan2(matrix[2][2]), + ry, + matrix[1][0].atan2(matrix[0][0]), + ] + } +} + +/// Decode the 23 ball joints, 58 hinges, and six translations. +pub fn body_cont_to_model_params(value: &[f32; 260]) -> [f32; 133] { + let mut output = [0.0; 133]; + for (joint, indices) in BODY_ROTATION_IDXS.iter().enumerate() { + let offset = joint * 6; + let euler = rotmat_to_euler_zyx(rot6d_to_rotmat([ + value[offset], + value[offset + 1], + value[offset + 2], + value[offset + 3], + value[offset + 4], + value[offset + 5], + ])); + output[indices[0]] = euler[0]; + output[indices[1]] = euler[1]; + output[indices[2]] = euler[2]; + } + let mut offset = 23 * 6; + for &index in &BODY_HINGE_IDXS { + output[index] = value[offset].atan2(value[offset + 1]); + offset += 2; + } + output[124..130].copy_from_slice(&value[offset..offset + 6]); + + // Hand slots and the final decoder-owned rotation are supplied elsewhere. + output[62..116].fill(0.0); + output[130..133].fill(0.0); + output +} + +/// Decode one hand's continuous representation to its 27 scalar parameters. +pub fn hand_cont_to_model_params(value: &[f32; 54]) -> [f32; 27] { + let mut output = [0.0; 27]; + let mut input_offset = 0; + let mut output_offset = 0; + for dofs in HAND_DOFS { + if dofs == 3 { + let euler = rotmat_to_euler_zyx(rot6d_to_rotmat([ + value[input_offset], + value[input_offset + 1], + value[input_offset + 2], + value[input_offset + 3], + value[input_offset + 4], + value[input_offset + 5], + ])); + output[output_offset..output_offset + 3].copy_from_slice(&euler); + } else { + for dof in 0..dofs { + output[output_offset + dof] = + value[input_offset + 2 * dof].atan2(value[input_offset + 2 * dof + 1]); + } + } + input_offset += dofs * 2; + output_offset += dofs; + } + debug_assert_eq!(input_offset, 54); + debug_assert_eq!(output_offset, 27); + output +} + +#[derive(Clone, Debug)] +pub struct PoseHeadParams { + pub global_rot: [f32; 3], + pub body: [f32; 133], + pub shape: [f32; 45], + pub scale: [f32; 28], + pub hands: [f32; 108], + pub expr: [f32; 72], +} + +/// Unpack the accumulated 519-value pose prediction. +pub fn unpack_pose(pred_519: &[f32]) -> PoseHeadParams { + assert_eq!(pred_519.len(), 519, "pose head output must contain 519 values"); + // The reference decomposes the head's rotation with a library routine + // that returns the Z, Y, X angles in that order, and the rig then reads + // the triple positionally as (rx, ry, rz). The network was trained through + // that pairing, so parity means handing the rig the reversed triple + // (oracle-verified: the straight order is 3e-2 off, the reversed 1e-4). + let zyx = rotmat_to_euler_zyx(rot6d_to_rotmat(pred_519[0..6].try_into().unwrap())); + let global_rot = [zyx[2], zyx[1], zyx[0]]; + let body_cont: &[f32; 260] = pred_519[6..266].try_into().unwrap(); + let mut shape = [0.0; 45]; + shape.copy_from_slice(&pred_519[266..311]); + let mut scale = [0.0; 28]; + scale.copy_from_slice(&pred_519[311..339]); + let mut hands = [0.0; 108]; + hands.copy_from_slice(&pred_519[339..447]); + + // The released body path disables the expression channels. + let expr = [0.0; 72]; + PoseHeadParams { + global_rot, + body: body_cont_to_model_params(body_cont), + shape, + scale, + hands, + expr, + } +} + +/// Assemble 136 pose values followed by 68 scale values. +pub fn model_params(rig: &MhrRig, pose: &PoseHeadParams) -> [f32; 204] { + let mut output = [0.0; 204]; + output[3..6].copy_from_slice(&pose.global_rot); + output[6..136].copy_from_slice(&pose.body[..130]); + + for hand in 0..2 { + let input = &pose.hands[hand * 54..(hand + 1) * 54]; + let mut transformed = [0.0; 54]; + for column in 0..54 { + let mut value = rig.hand_pose_mean[column]; + for row in 0..54 { + value += input[row] * rig.hand_pose_comps[row * 54 + column]; + } + transformed[column] = value; + } + let decoded = hand_cont_to_model_params(&transformed); + let indices = if hand == 0 { + &rig.hand_joint_idxs_left + } else { + &rig.hand_joint_idxs_right + }; + for (value, &index) in decoded.iter().zip(indices) { + output[index as usize] = *value; + } + } + + for column in 0..68 { + let mut value = rig.scale_mean[column]; + for row in 0..28 { + value += pose.scale[row] * rig.scale_comps[row * 68 + column]; + } + output[136 + column] = value; + } + output +} + +pub fn camera_translation( + pred_cam: [f32; 3], + bbox_center: [f32; 2], + bbox_side: f32, + focal: f32, + principal: [f32; 2], +) -> [f32; 3] { + let scale = -pred_cam[0]; + let ty = -pred_cam[2]; + let bbox_scale = bbox_side * scale + 1.0e-8; + [ + pred_cam[1] + 2.0 * (bbox_center[0] - principal[0]) / bbox_scale, + ty + 2.0 * (bbox_center[1] - principal[1]) / bbox_scale, + 2.0 * focal / bbox_scale, + ] +} + +/// Project row-major XYZ keypoints and return row-major UV plus camera depth. +pub fn project( + kp3d: &[f32], + cam_t: [f32; 3], + focal: f32, + principal: [f32; 2], +) -> (Vec, Vec) { + assert_eq!(kp3d.len() % 3, 0, "3D keypoints must be XYZ triples"); + let count = kp3d.len() / 3; + let mut kp2d = Vec::with_capacity(count * 2); + let mut depth = Vec::with_capacity(count); + for point in kp3d.chunks_exact(3) { + let x = point[0] + cam_t[0]; + let y = point[1] + cam_t[1]; + let z = point[2] + cam_t[2]; + kp2d.push(focal * x / z + principal[0]); + kp2d.push(focal * y / z + principal[1]); + depth.push(z); + } + (kp2d, depth) +} + +fn dot3(a: [f32; 3], b: [f32; 3]) -> f32 { + a[0] * b[0] + a[1] * b[1] + a[2] * b[2] +} + +fn normalize3(value: [f32; 3]) -> [f32; 3] { + let inverse = 1.0 / dot3(value, value).sqrt().max(1.0e-12); + [value[0] * inverse, value[1] * inverse, value[2] * inverse] +} + +fn cross3(a: [f32; 3], b: [f32; 3]) -> [f32; 3] { + [ + a[1] * b[2] - a[2] * b[1], + a[2] * b[0] - a[0] * b[2], + a[0] * b[1] - a[1] * b[0], + ] +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::fixture; + use crate::weights::BodyWeights; + use std::f32::consts::FRAC_PI_2; + + fn euler_matrix([rx, ry, rz]: [f32; 3]) -> [[f32; 3]; 3] { + let (sx, cx) = rx.sin_cos(); + let (sy, cy) = ry.sin_cos(); + let (sz, cz) = rz.sin_cos(); + [ + [cz * cy, cz * sy * sx - sz * cx, cz * sy * cx + sz * sx], + [sz * cy, sz * sy * sx + cz * cx, sz * sy * cx - cz * sx], + [-sy, cy * sx, cy * cx], + ] + } + + fn rot6d_from_euler(euler: [f32; 3]) -> [f32; 6] { + let matrix = euler_matrix(euler); + [ + matrix[0][0], + matrix[1][0], + matrix[2][0], + matrix[0][1], + matrix[1][1], + matrix[2][1], + ] + } + + fn assert_near(actual: f32, expected: f32) { + assert!((actual - expected).abs() < 2.0e-5, "{actual} != {expected}"); + } + + #[test] + fn rotation_6d_and_zyx_euler_round_trip() { + let identity = rot6d_to_rotmat([1.0, 0.0, 0.0, 0.0, 1.0, 0.0]); + assert_eq!(identity, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]); + + let expected = [0.31, -0.42, 0.73]; + let matrix = rot6d_to_rotmat(rot6d_from_euler(expected)); + let actual = rotmat_to_euler_zyx(matrix); + for axis in 0..3 { + assert_near(actual[axis], expected[axis]); + } + } + + #[test] + fn zyx_extraction_uses_singular_guard() { + let matrix = euler_matrix([0.35, FRAC_PI_2, -0.2]); + let euler = rotmat_to_euler_zyx(matrix); + assert_near(euler[1], FRAC_PI_2); + assert_eq!(euler[2], 0.0); + let rebuilt = euler_matrix(euler); + for row in 0..3 { + for column in 0..3 { + assert_near(rebuilt[row][column], matrix[row][column]); + } + } + } + + #[test] + fn body_continuous_values_land_at_documented_indices() { + let mut value = [0.0; 260]; + for joint in 0..23 { + let euler = [0.01 * joint as f32, -0.02 * joint as f32, 0.03 * joint as f32]; + value[joint * 6..joint * 6 + 6].copy_from_slice(&rot6d_from_euler(euler)); + } + for hinge in 0..58 { + let angle = 0.005 * (hinge + 1) as f32; + let (sin, cos) = angle.sin_cos(); + value[138 + hinge * 2] = sin; + value[139 + hinge * 2] = cos; + } + value[254..260].copy_from_slice(&[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]); + + let output = body_cont_to_model_params(&value); + assert_near(output[0], 0.0); + assert_near(output[34], 0.08); + assert_near(output[35], -0.16); + assert_near(output[36], 0.24); + assert_near(output[1], 0.005); + assert_eq!(&output[62..116], &[0.0; 54]); + assert_near(output[116], 0.005 * 51.0); + assert_near(output[123], 0.005 * 58.0); + assert_eq!(&output[124..130], &[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]); + assert_eq!(&output[130..133], &[0.0; 3]); + } + + #[test] + fn hand_continuous_mixed_dofs_decode_in_order() { + let mut value = [0.0; 54]; + let mut input = 0; + for dofs in HAND_DOFS { + if dofs == 3 { + value[input..input + 6] + .copy_from_slice(&rot6d_from_euler([0.1, -0.2, 0.3])); + } else { + for dof in 0..dofs { + let angle = 0.04 * (dof + 1) as f32; + let (sin, cos) = angle.sin_cos(); + value[input + 2 * dof] = sin; + value[input + 2 * dof + 1] = cos; + } + } + input += 2 * dofs; + } + let output = hand_cont_to_model_params(&value); + assert_near(output[0], 0.1); + assert_near(output[1], -0.2); + assert_near(output[2], 0.3); + assert_near(output[3], 0.04); + assert_near(output[20], 0.04); + assert_near(output[21], 0.08); + assert_near(output[22], 0.1); + } + + #[test] + fn camera_and_projection_follow_full_image_convention() { + let translation = camera_translation([-2.0, 0.5, -0.25], [300.0, 220.0], 100.0, 500.0, [250.0, 200.0]); + assert_near(translation[0], 1.0); + assert_near(translation[1], 0.45); + assert_near(translation[2], 5.0); + let (points, depth) = project(&[1.0, 2.0, 5.0], translation, 500.0, [250.0, 200.0]); + assert_near(points[0], 350.0); + assert_near(points[1], 322.5); + assert_near(depth[0], 10.0); + } + + fn max_abs(left: &[f32], right: &[f32]) -> f32 { + assert_eq!(left.len(), right.len()); + left.iter() + .zip(right) + .map(|(a, b)| (a - b).abs()) + .fold(0.0, f32::max) + } + + #[test] + fn oracle_pose_unpack_and_model_assembly() { + let Some((_, projected)) = fixture::load("head_pose_proj_out_0") else { + eprintln!("SKIP oracle_pose_unpack_and_model_assembly: pose fixture absent"); + return; + }; + let Some((_, init_pose_fixture)) = fixture::load("init_pose") else { + eprintln!("SKIP oracle_pose_unpack_and_model_assembly: init_pose.f32 absent"); + return; + }; + let Some(weights_path) = fixture::weights_path() else { + eprintln!("SKIP oracle_pose_unpack_and_model_assembly: weights absent"); + return; + }; + let weights = BodyWeights::load(weights_path).expect("oracle weights must load"); + let init_pose = weights + .f32_shaped("init_pose.weight", &[1, 519]) + .expect("init_pose.weight must load"); + assert!( + max_abs(&init_pose, &init_pose_fixture) <= 1.0e-6, + "oracle init_pose differs from weights" + ); + assert_eq!(projected.len(), 519); + let pred: Vec = projected + .iter() + .zip(&init_pose) + .map(|(value, initial)| value + initial) + .collect(); + let pose = unpack_pose(&pred); + + let Some((_, expected_global)) = fixture::load("mhr_in_global_rot_0") else { + eprintln!("SKIP oracle_pose_unpack_and_model_assembly: MHR inputs absent"); + return; + }; + let Some((_, expected_body)) = fixture::load("mhr_in_body_pose_params_0") else { + eprintln!("SKIP oracle_pose_unpack_and_model_assembly: MHR inputs absent"); + return; + }; + let Some((_, expected_scale)) = fixture::load("mhr_in_scale_params_0") else { + eprintln!("SKIP oracle_pose_unpack_and_model_assembly: MHR inputs absent"); + return; + }; + let Some((_, expected_shape)) = fixture::load("mhr_in_shape_params_0") else { + eprintln!("SKIP oracle_pose_unpack_and_model_assembly: MHR inputs absent"); + return; + }; + let Some((_, expected_hands)) = fixture::load("mhr_in_hand_pose_params_0") else { + eprintln!("SKIP oracle_pose_unpack_and_model_assembly: MHR inputs absent"); + return; + }; + let Some((_, expected_params)) = fixture::load("mhrjit_in_params_0") else { + eprintln!("SKIP oracle_pose_unpack_and_model_assembly: MHR JIT input absent"); + return; + }; + + let global_error = max_abs(&pose.global_rot, &expected_global); + eprintln!("pose oracle global rotation max abs error {global_error:.7}"); + assert!(global_error <= 1.0e-4, "global rotation triple order (see unpack_pose)"); + assert!(max_abs(&pose.body, &expected_body) <= 1.0e-4); + assert!(max_abs(&pose.scale, &expected_scale) <= 1.0e-4); + assert!(max_abs(&pose.shape, &expected_shape) <= 1.0e-4); + assert!(max_abs(&pose.hands, &expected_hands) <= 1.0e-4); + + let rig = fixture::rig().expect("oracle rig must load after weights check"); + let model = model_params(rig, &pose); + let model_error = max_abs(&model, &expected_params); + eprintln!("pose oracle MHR parameter max abs error {model_error:.7}"); + assert!(model_error <= 1.0e-4); + } +} From 9e343a8f201ff9e5bd8accd9e417cc54616f0bdf Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 22:56:46 +0200 Subject: [PATCH 018/417] ai-body: the DINOv3 ViT-H+/16 backbone, crop and ray conditioning; Metal gains rope-half and affine layer norm dino.rs is the 32-block ViT-H+/16 on the gpu_* surface after the TRELLIS conditioner: bf16-resident linears with f32 accumulation, layer scale folded into the output projections, rotate-half rope, SwiGLU, the model's own final norm. preprocess.rs is the crop (box -> 1.25 pad -> 3:4 -> square -> 512 bilinear warp, ImageNet normalisation), the CLIFF condition vector and the patch rays; condition.rs is the dense positional encoding and the ray-conditioned decoder context. Against the reference oracle on Metal: backbone 1.1% mean relative (bf16 noise), ray-conditioned context 8e-5, crop within one u8 rounding step, rays and dense PE 1e-7. One reference detail the paper does not state: its shrink of the ray field is an antialiased filter whose taps clip at the image edge, so the two edge patches sample inside their block centre (9.03 and 501.97 rather than 7.5 and 503.5); block centres left 0.1 of error. The Metal tensor backend was missing rope_half (it aliased the interleaved layout) and layer_norm_mul_add; both now exist with the CUDA contract, which is what lets this backbone run on Apple silicon. Co-Authored-By: Claude Fable 5.1 --- libs/ai/metal/src/gpu_tensor.rs | 69 +++- libs/ai/models/body/src/condition.rs | 315 +++++++++++++++++++ libs/ai/models/body/src/dino.rs | 435 ++++++++++++++++++++++++++ libs/ai/models/body/src/fixture.rs | 37 ++- libs/ai/models/body/src/lib.rs | 7 +- libs/ai/models/body/src/preprocess.rs | 304 ++++++++++++++++++ libs/ai/models/common/src/gpu.rs | 27 +- 7 files changed, 1179 insertions(+), 15 deletions(-) create mode 100644 libs/ai/models/body/src/condition.rs create mode 100644 libs/ai/models/body/src/dino.rs create mode 100644 libs/ai/models/body/src/preprocess.rs diff --git a/libs/ai/metal/src/gpu_tensor.rs b/libs/ai/metal/src/gpu_tensor.rs index 85753de57..322bc3f3b 100644 --- a/libs/ai/metal/src/gpu_tensor.rs +++ b/libs/ai/metal/src/gpu_tensor.rs @@ -684,13 +684,80 @@ pub fn rope_interleaved( Ok(tensor(x.rows, x.cols, out)) } +/// Rotate-half rope (the DINOv3 / LLaMA layout): within each head the first +/// `rot_half` lanes pair with the next `rot_half`, `out1 = x1 c - x2 s`, +/// `out2 = x2 c + x1 s`, with one `[rows, rot_half]` cos/sin table shared by +/// both halves; lanes past `2 * rot_half` pass through. Same contract as the +/// CUDA `rope_half` kernel. pub fn rope_half( x: &GpuTensor, heads: usize, + rot_half: usize, cos: &GpuTensor, sin: &GpuTensor, ) -> Result { - rope_interleaved(x, heads, cos, sin) + if heads == 0 || x.cols % heads != 0 { + return Err("metal rope_half head mismatch".to_string()); + } + let dim = x.cols / heads; + if rot_half * 2 > dim { + return Err("metal rope_half rotary span exceeds head dim".to_string()); + } + if cos.rows != x.rows || cos.cols != rot_half || sin.rows != x.rows || sin.cols != rot_half { + return Err("metal rope_half table mismatch".to_string()); + } + let xd = data(x)?; + let cd = data(cos)?; + let sd = data(sin)?; + let mut out = xd.clone(); + for r in 0..x.rows { + for h in 0..heads { + let base = r * x.cols + h * dim; + for i in 0..rot_half { + let c = cd[r * rot_half + i]; + let s = sd[r * rot_half + i]; + let x1 = xd[base + i]; + let x2 = xd[base + rot_half + i]; + out[base + i] = x1 * c - x2 * s; + out[base + rot_half + i] = x2 * c + x1 * s; + } + } + } + Ok(tensor(x.rows, x.cols, out)) +} + +/// Per-row layer norm with an affine: `(x - mean) / sqrt(var + eps) * mul + add` +/// (biased variance), `mul`/`add` one value per column. +pub fn layer_norm_mul_add( + x: &GpuTensor, + mul: &[f32], + add: &[f32], + eps: f32, +) -> Result { + if mul.len() != x.cols || add.len() != x.cols { + return Err(format!( + "metal layer_norm_mul_add affine width {}/{} != {} cols", + mul.len(), + add.len(), + x.cols + )); + } + let xd = data(x)?; + let out = try_layer_norm_mul_add_f32(&xd, &[x.rows, x.cols], mul, &[x.cols], add, &[x.cols], eps) + .unwrap_or_else(|| { + let mut out = vec![0.0; xd.len()]; + for r in 0..x.rows { + let row = &xd[r * x.cols..(r + 1) * x.cols]; + let mean = row.iter().sum::() / x.cols as f32; + let var = row.iter().map(|v| (v - mean) * (v - mean)).sum::() / x.cols as f32; + let inv = (var + eps).sqrt().recip(); + for c in 0..x.cols { + out[r * x.cols + c] = (row[c] - mean) * inv * mul[c] + add[c]; + } + } + out + }); + Ok(tensor(x.rows, x.cols, out)) } pub fn rpb_expand( diff --git a/libs/ai/models/body/src/condition.rs b/libs/ai/models/body/src/condition.rs new file mode 100644 index 000000000..ede5af6aa --- /dev/null +++ b/libs/ai/models/body/src/condition.rs @@ -0,0 +1,315 @@ +//! Dense image positional encoding and ray-conditioned decoder context. + +use crate::backend::{ + gpu_download, gpu_layer_norm_mul_add, gpu_linear_f32_resident, gpu_upload, GpuTensor, +}; +use crate::weights::BodyWeights; +use crate::{DiffusionError, Result, DEC_NORM_EPS, DINO_DIM, NUM_PATCHES, PATCHES_SIDE}; + +const PE_HALF: usize = DINO_DIM / 2; +const RAY_FEATURES: usize = 99; +const RAY_FREQUENCIES: usize = 16; + +pub fn dense_pe(g: &[f32]) -> Vec { + assert_eq!(g.len(), 2 * PE_HALF, "dense PE matrix must be 2x640"); + let mut output = vec![0.0f32; NUM_PATCHES * DINO_DIM]; + for gy in 0..PATCHES_SIDE { + let y = 2.0 * ((gy as f32 + 0.5) / PATCHES_SIDE as f32) - 1.0; + for gx in 0..PATCHES_SIDE { + let x = 2.0 * ((gx as f32 + 0.5) / PATCHES_SIDE as f32) - 1.0; + let row = gy * PATCHES_SIDE + gx; + for k in 0..PE_HALF { + let angle = 2.0 * std::f32::consts::PI * (x * g[k] + y * g[PE_HALF + k]); + output[row * DINO_DIM + k] = angle.sin(); + output[row * DINO_DIM + PE_HALF + k] = angle.cos(); + } + } + } + output +} + +pub fn ray_features(rays: &[f32]) -> Vec { + assert_eq!(rays.len(), NUM_PATCHES * 2, "patch rays must be 1024x2"); + let mut output = vec![0.0f32; NUM_PATCHES * RAY_FEATURES]; + for token in 0..NUM_PATCHES { + let ray = [rays[token * 2], rays[token * 2 + 1], 1.0]; + let row = &mut output[token * RAY_FEATURES..(token + 1) * RAY_FEATURES]; + row[..3].copy_from_slice(&ray); + for d in 0..3 { + for k in 0..RAY_FREQUENCIES { + let frequency = 1.0 + 31.0 * k as f32 / (RAY_FREQUENCIES - 1) as f32; + let angle = std::f32::consts::PI * ray[d] * frequency; + row[3 + d * RAY_FREQUENCIES + k] = angle.sin(); + row[3 + 3 * RAY_FREQUENCIES + d * RAY_FREQUENCIES + k] = angle.cos(); + } + } + } + output +} + +pub struct RayCond { + pub conv_w: GpuTensor, + pub norm_w: Vec, + pub norm_b: Vec, +} + +impl RayCond { + pub fn prepare(weights: &BodyWeights) -> Result { + let conv = weights.f32_shaped( + "ray_cond_emb.conv.weight", + &[DINO_DIM, DINO_DIM + RAY_FEATURES, 1, 1], + )?; + Ok(Self { + conv_w: gpu_upload(&conv, DINO_DIM, DINO_DIM + RAY_FEATURES) + .map_err(DiffusionError::model)?, + norm_w: weights.f32_shaped("ray_cond_emb.norm.weight", &[DINO_DIM])?, + norm_b: weights.f32_shaped("ray_cond_emb.norm.bias", &[DINO_DIM])?, + }) + } + + pub fn apply( + &self, + e: &GpuTensor, + no_mask_embed: &[f32; DINO_DIM], + feats: &[f32], + ) -> Result { + if e.rows() != NUM_PATCHES || e.cols() != DINO_DIM { + return Err(DiffusionError::workflow(format!( + "ray conditioning image shape is {}x{}, expected {NUM_PATCHES}x{DINO_DIM}", + e.rows(), + e.cols() + ))); + } + if feats.len() != NUM_PATCHES * RAY_FEATURES { + return Err(DiffusionError::workflow(format!( + "ray conditioning features have {} values, expected {}", + feats.len(), + NUM_PATCHES * RAY_FEATURES + ))); + } + + // Host assembly avoids requiring a device-specific broadcast/concat + // path; the convolution and normalization remain device-resident. + let image = gpu_download(e).map_err(DiffusionError::model)?; + let cols = DINO_DIM + RAY_FEATURES; + let mut joined = vec![0.0f32; NUM_PATCHES * cols]; + for row in 0..NUM_PATCHES { + let dst = &mut joined[row * cols..(row + 1) * cols]; + for c in 0..DINO_DIM { + dst[c] = image[row * DINO_DIM + c] + no_mask_embed[c]; + } + dst[DINO_DIM..].copy_from_slice( + &feats[row * RAY_FEATURES..(row + 1) * RAY_FEATURES], + ); + } + let joined = gpu_upload(&joined, NUM_PATCHES, cols).map_err(DiffusionError::model)?; + let projected = gpu_linear_f32_resident(&joined, &self.conv_w, None) + .map_err(DiffusionError::model)?; + gpu_layer_norm_mul_add(&projected, &self.norm_w, &self.norm_b, DEC_NORM_EPS) + .map_err(DiffusionError::model) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::backend::{gpu_device_available, gpu_download, gpu_upload}; + + fn assert_close(actual: f32, expected: f32, tolerance: f32) { + assert!( + (actual - expected).abs() <= tolerance, + "actual={actual} expected={expected} tolerance={tolerance}" + ); + } + + fn planar_to_tokens(values: &[f32], channels: usize) -> Vec { + let mut output = vec![0.0f32; NUM_PATCHES * channels]; + for c in 0..channels { + for token in 0..NUM_PATCHES { + output[token * channels + c] = values[c * NUM_PATCHES + token]; + } + } + output + } + + fn matrix_from_dense_pe(pe: &[f32]) -> Vec { + let mut matrix = vec![0.0f32; 2 * PE_HALF]; + let coordinate = 2.0 * (0.5 / PATCHES_SIDE as f32) - 1.0; + for k in 0..PE_HALF { + let phase = |token: usize| { + let row = token * DINO_DIM; + (pe[row + k], pe[row + PE_HALF + k]) + }; + let (s00, c00) = phase(0); + let (sx, cx) = phase(1); + let (sy, cy) = phase(PATCHES_SIDE); + let dx = (sx * c00 - cx * s00).atan2(cx * c00 + sx * s00); + let dy = (sy * c00 - cy * s00).atan2(cy * c00 + sy * s00); + let mut gx = dx * 16.0 / (2.0 * std::f32::consts::PI); + let gy = dy * 16.0 / (2.0 * std::f32::consts::PI); + let base = 2.0 * std::f32::consts::PI * coordinate * (gx + gy); + if base.sin() * s00 + base.cos() * c00 < 0.0 { + // A 16.0 frequency shift preserves adjacent phase deltas but + // flips every value on this half-offset 32x32 grid. + gx += 16.0; + } + matrix[k] = gx; + matrix[PE_HALF + k] = gy; + } + matrix + } + + #[test] + fn ray_feature_order_is_exact() { + let mut rays = vec![0.0f32; NUM_PATCHES * 2]; + rays[0] = 0.25; + rays[1] = -0.5; + let features = ray_features(&rays); + assert_eq!(&features[..3], &[0.25, -0.5, 1.0]); + for d in 0..3 { + let ray = [0.25f32, -0.5, 1.0][d]; + for k in 0..16 { + let frequency = 1.0 + 31.0 * k as f32 / 15.0; + let expected = (std::f32::consts::PI * ray * frequency).sin(); + assert_close(features[3 + d * 16 + k], expected, 1e-7); + } + } + assert_close(features[3], (std::f32::consts::PI * 0.25).sin(), 1e-7); + assert_close(features[3 + 15], (std::f32::consts::PI * 0.25 * 32.0).sin(), 1e-6); + } + + #[test] + fn dense_pe_is_sin_then_cos_and_corner_symmetric() { + let mut g = vec![0.0f32; 2 * PE_HALF]; + g[0] = 0.25; + g[PE_HALF] = -0.5; + g[7] = 0.125; + let pe = dense_pe(&g); + let coord = 2.0 * (0.5 / PATCHES_SIDE as f32) - 1.0; + let angle = 2.0 * std::f32::consts::PI * (coord * 0.25 + coord * -0.5); + assert_close(pe[0], angle.sin(), 1e-7); + assert_close(pe[PE_HALF], angle.cos(), 1e-7); + let opposite = (NUM_PATCHES - 1) * DINO_DIM; + for k in 0..PE_HALF { + assert_close(pe[opposite + k], -pe[k], 2e-6); + assert_close(pe[opposite + PE_HALF + k], pe[PE_HALF + k], 2e-6); + } + } + + #[test] + fn fixture_dense_pe() { + let Some((expected_shape, expected)) = crate::fixture::load("decoder_image_augment_in") else { + eprintln!("body oracle fixtures absent; skipping dense-PE parity"); + return; + }; + let expected_tokens = if expected_shape.ends_with(&[DINO_DIM, PATCHES_SIDE, PATCHES_SIDE]) { + planar_to_tokens(&expected, DINO_DIM) + } else { + expected + }; + let matrix_names = [ + "positional_encoding_gaussian_matrix", + "prompt_encoder.pe_layer.positional_encoding_gaussian_matrix", + "dense_pe_g", + ]; + let mut matrix = matrix_names + .iter() + .find_map(|name| crate::fixture::load(name).map(|(_, values)| values)); + if matrix.is_none() { + if let Some(path) = crate::fixture::weights_path() { + matrix = BodyWeights::load(path).ok().and_then(|weights| { + weights + .f32_shaped( + "prompt_encoder.pe_layer.positional_encoding_gaussian_matrix", + &[2, PE_HALF], + ) + .ok() + }); + } + } + // The phase deltas in the oracle PE recover an equivalent matrix on + // the half-offset 32x32 grid when the standalone matrix is omitted. + let matrix = matrix.unwrap_or_else(|| matrix_from_dense_pe(&expected_tokens)); + let actual = dense_pe(&matrix); + assert_eq!(actual.len(), expected_tokens.len()); + let max_error = actual + .iter() + .zip(&expected_tokens) + .map(|(a, b)| (a - b).abs()) + .fold(0.0f32, f32::max); + eprintln!("body dense-PE max abs error: {max_error:.7}"); + assert!(max_error <= 1e-4); + } + + #[test] + fn gpu_fixture_ray_conditioning() { + let Some((_, image_planar)) = crate::fixture::load("raycond_img_in") else { + eprintln!("body oracle fixtures absent; skipping ray-condition GPU parity"); + return; + }; + let Some((_, rays_planar)) = crate::fixture::load("raycond_rays_in") else { + eprintln!("body ray fixture absent; skipping ray-condition GPU parity"); + return; + }; + let Some((expected_shape, expected_planar)) = crate::fixture::load("raycond_out") else { + eprintln!("body ray output fixture absent; skipping ray-condition GPU parity"); + return; + }; + let Some(weights_path) = crate::fixture::weights_path() else { + eprintln!("body weights path absent; skipping ray-condition GPU parity"); + return; + }; + if !gpu_device_available() || !crate::fixture::gpu_required_ops_available() { + eprintln!("body GPU unavailable; skipping ray-condition GPU parity"); + return; + } + let image = planar_to_tokens(&image_planar, DINO_DIM); + let plane = crate::IMAGE_SIZE * crate::IMAGE_SIZE; + assert_eq!(rays_planar.len(), 2 * plane); + // The ray field is affine: sample it at the antialiased tap positions + // (what the reference's shrink-by-16 amounts to), per axis. + let sample = |c: usize, x: f32, y: f32| { + let x0 = x.floor() as usize; + let y0 = y.floor() as usize; + let (x1, y1) = ((x0 + 1).min(crate::IMAGE_SIZE - 1), (y0 + 1).min(crate::IMAGE_SIZE - 1)); + let (fx, fy) = (x - x0 as f32, y - y0 as f32); + let at = |xx: usize, yy: usize| rays_planar[c * plane + yy * crate::IMAGE_SIZE + xx]; + (at(x0, y0) * (1.0 - fx) + at(x1, y0) * fx) * (1.0 - fy) + + (at(x0, y1) * (1.0 - fx) + at(x1, y1) * fx) * fy + }; + let mut patch = vec![0.0f32; NUM_PATCHES * 2]; + for gy in 0..PATCHES_SIDE { + for gx in 0..PATCHES_SIDE { + let token = gy * PATCHES_SIDE + gx; + let (x, y) = ( + crate::preprocess::patch_sample_coord(gx), + crate::preprocess::patch_sample_coord(gy), + ); + for c in 0..2 { + patch[token * 2 + c] = sample(c, x, y); + } + } + } + let feats = ray_features(&patch); + let weights = BodyWeights::load(weights_path).expect("load body weights"); + let ray_cond = RayCond::prepare(&weights).expect("prepare ray conditioning"); + let image = gpu_upload(&image, NUM_PATCHES, DINO_DIM).expect("upload raycond image"); + // raycond_img_in already contains the no-mask embedding. + let output = ray_cond + .apply(&image, &[0.0; DINO_DIM], &feats) + .expect("ray conditioning forward"); + let output = gpu_download(&output).expect("download ray conditioning"); + let expected = if expected_shape.ends_with(&[DINO_DIM, PATCHES_SIDE, PATCHES_SIDE]) { + planar_to_tokens(&expected_planar, DINO_DIM) + } else { + expected_planar + }; + let max_error = output + .iter() + .zip(&expected) + .map(|(a, b)| (a - b).abs()) + .fold(0.0f32, f32::max); + eprintln!("body ray conditioning max abs error: {max_error:.7}"); + assert!(max_error <= 1e-3); + } +} diff --git a/libs/ai/models/body/src/dino.rs b/libs/ai/models/body/src/dino.rs new file mode 100644 index 000000000..495072324 --- /dev/null +++ b/libs/ai/models/body/src/dino.rs @@ -0,0 +1,435 @@ +//! DINOv3 ViT-H+/16 backbone for SAM 3D Body. +//! +//! Matrix weights stay as packed bf16 cache entries and use +//! `gpu_linear_nt_cached_bf16_f32acc`; activations and reductions are f32. +//! LayerScale is folded into the output projection rows and biases at load. + +use crate::backend::{ + gpu_add, gpu_attention_packed_cross, gpu_concat_rows_many, gpu_download, + gpu_layer_norm_mul_add, gpu_linear_nt_cached_bf16_f32acc, gpu_mul, gpu_rope_half, + gpu_silu, gpu_slice_rows, gpu_upload, GpuLinearPart, GpuTensor, +}; +use crate::weights::BodyWeights; +use crate::{ + emit_progress, DiffusionError, ProgressHook, Result, DINO_DEPTH, DINO_DIM, DINO_FFN, + DINO_HEADS, DINO_HEAD_DIM, DINO_NORM_EPS, DINO_PREFIX_TOKENS, DINO_ROPE_BASE, IMAGE_SIZE, + NUM_PATCHES, PATCH, PATCHES_SIDE, ROPE_HALF, +}; +use makepad_ai_common::quant::GGML_TYPE_BF16; +use makepad_ai_loader::MlxDType; + +const PATCH_DIM: usize = 3 * PATCH * PATCH; +const CACHE_NAMESPACE: &str = "body-dinov3-hplus-bf16"; + +struct Bf16Linear { + bytes: Vec, + key: String, + out: usize, + bias: Vec, +} + +impl Bf16Linear { + fn load( + weights: &BodyWeights, + name: &str, + out: usize, + inn: usize, + bias: bool, + ) -> Result { + let bytes = bf16_bytes_shaped(weights, &format!("{name}.weight"), &[out, inn])?; + let bias = if bias { + weights.f32_shaped(&format!("{name}.bias"), &[out])? + } else { + Vec::new() + }; + Ok(Self { + bytes, + key: name.to_string(), + out, + bias, + }) + } + + fn load_folded( + weights: &BodyWeights, + name: &str, + scale_name: &str, + out: usize, + inn: usize, + ) -> Result { + let mut matrix = weights.f32_shaped(&format!("{name}.weight"), &[out, inn])?; + let mut bias = weights.f32_shaped(&format!("{name}.bias"), &[out])?; + let scale = weights.f32_shaped(scale_name, &[out])?; + for row in 0..out { + for value in &mut matrix[row * inn..(row + 1) * inn] { + *value *= scale[row]; + } + bias[row] *= scale[row]; + } + Ok(Self { + bytes: f32_to_bf16_bytes(&matrix), + key: format!("{name}.layerscale_folded"), + out, + bias, + }) + } + + fn load_patch(weights: &BodyWeights) -> Result { + let name = "backbone.embeddings.patch_embeddings"; + Ok(Self { + bytes: bf16_bytes_shaped( + weights, + &format!("{name}.weight"), + &[DINO_DIM, 3, PATCH, PATCH], + )?, + key: name.to_string(), + out: DINO_DIM, + bias: weights.f32_shaped(&format!("{name}.bias"), &[DINO_DIM])?, + }) + } + + fn forward(&self, input: &GpuTensor) -> Result { + gpu_linear_nt_cached_bf16_f32acc( + input, + CACHE_NAMESPACE, + &[GpuLinearPart { + bt_ggml_type: GGML_TYPE_BF16, + n: self.out, + cache_key: &self.key, + bytes: &self.bytes, + }], + &self.bias, + ) + .map_err(DiffusionError::model) + } +} + +struct DinoLayer { + norm1_w: Vec, + norm1_b: Vec, + q: Bf16Linear, + k: Bf16Linear, + v: Bf16Linear, + out: Bf16Linear, + norm2_w: Vec, + norm2_b: Vec, + gate: Bf16Linear, + up: Bf16Linear, + down: Bf16Linear, +} + +pub struct BodyDino { + patch: Bf16Linear, + prefix: GpuTensor, + layers: Vec, + final_norm_w: Vec, + final_norm_b: Vec, +} + +fn bf16_bytes_shaped( + weights: &BodyWeights, + name: &str, + expected: &[usize], +) -> Result> { + weights.expect_shape(name, expected)?; + if weights.dtype(name)? != MlxDType::BF16 { + return Err(DiffusionError::model(format!( + "body DINO tensor {name} is not bf16" + ))); + } + let bytes = weights.bytes(name)?; + let values = expected.iter().try_fold(1usize, |product, &dimension| { + product.checked_mul(dimension).ok_or_else(|| { + DiffusionError::model(format!("body DINO tensor {name} shape overflows usize")) + }) + })?; + if bytes.len() != values * 2 { + return Err(DiffusionError::model(format!( + "body DINO tensor {name} has {} bytes, expected {}", + bytes.len(), + values * 2 + ))); + } + Ok(bytes) +} + +fn f32_to_bf16_bytes(values: &[f32]) -> Vec { + let mut bytes = Vec::with_capacity(values.len() * 2); + for &value in values { + let bits = value.to_bits(); + let rounded = ((bits.wrapping_add(0x7fff + ((bits >> 16) & 1))) >> 16) as u16; + bytes.extend_from_slice(&rounded.to_le_bytes()); + } + bytes +} + +impl BodyDino { + pub fn prepare(weights: &BodyWeights) -> Result { + Self::prepare_with_progress(weights, None) + } + + pub fn prepare_with_progress( + weights: &BodyWeights, + mut progress: Option, + ) -> Result { + let cls = weights.f32_shaped("backbone.embeddings.cls_token", &[1, 1, DINO_DIM])?; + let registers = weights.f32_shaped( + "backbone.embeddings.register_tokens", + &[1, DINO_PREFIX_TOKENS - 1, DINO_DIM], + )?; + let mut prefix = cls; + prefix.extend_from_slice(®isters); + + let patch = Bf16Linear::load_patch(weights)?; + let mut layers = Vec::with_capacity(DINO_DEPTH); + for i in 0..DINO_DEPTH { + if progress.is_some() { + emit_progress( + &mut progress, + &format!("load body dino block {}/{DINO_DEPTH}", i + 1), + i as f64 / DINO_DEPTH as f64, + )?; + } + let p = format!("backbone.layer.{i}"); + layers.push(DinoLayer { + norm1_w: weights.f32_shaped(&format!("{p}.norm1.weight"), &[DINO_DIM])?, + norm1_b: weights.f32_shaped(&format!("{p}.norm1.bias"), &[DINO_DIM])?, + q: Bf16Linear::load( + weights, + &format!("{p}.attention.q_proj"), + DINO_DIM, + DINO_DIM, + true, + )?, + k: Bf16Linear::load( + weights, + &format!("{p}.attention.k_proj"), + DINO_DIM, + DINO_DIM, + false, + )?, + v: Bf16Linear::load( + weights, + &format!("{p}.attention.v_proj"), + DINO_DIM, + DINO_DIM, + true, + )?, + out: Bf16Linear::load_folded( + weights, + &format!("{p}.attention.o_proj"), + &format!("{p}.layer_scale1.lambda1"), + DINO_DIM, + DINO_DIM, + )?, + norm2_w: weights.f32_shaped(&format!("{p}.norm2.weight"), &[DINO_DIM])?, + norm2_b: weights.f32_shaped(&format!("{p}.norm2.bias"), &[DINO_DIM])?, + gate: Bf16Linear::load( + weights, + &format!("{p}.mlp.gate_proj"), + DINO_FFN, + DINO_DIM, + true, + )?, + up: Bf16Linear::load( + weights, + &format!("{p}.mlp.up_proj"), + DINO_FFN, + DINO_DIM, + true, + )?, + down: Bf16Linear::load_folded( + weights, + &format!("{p}.mlp.down_proj"), + &format!("{p}.layer_scale2.lambda1"), + DINO_DIM, + DINO_FFN, + )?, + }); + } + + Ok(Self { + patch, + prefix: gpu_upload(&prefix, DINO_PREFIX_TOKENS, DINO_DIM) + .map_err(DiffusionError::model)?, + layers, + final_norm_w: weights.f32_shaped("backbone.norm.weight", &[DINO_DIM])?, + final_norm_b: weights.f32_shaped("backbone.norm.bias", &[DINO_DIM])?, + }) + } + + fn rope_tables(&self) -> (Vec, Vec) { + let rows = DINO_PREFIX_TOKENS + NUM_PATCHES; + let mut inv_freq = [0.0f32; 16]; + for (j, value) in inv_freq.iter_mut().enumerate() { + *value = 1.0 / DINO_ROPE_BASE.powf(j as f32 * 4.0 / DINO_HEAD_DIM as f32); + } + let mut cos = vec![1.0f32; rows * ROPE_HALF]; + let mut sin = vec![0.0f32; rows * ROPE_HALF]; + for gy in 0..PATCHES_SIDE { + for gx in 0..PATCHES_SIDE { + let row = DINO_PREFIX_TOKENS + gy * PATCHES_SIDE + gx; + let y = 2.0 * ((gy as f32 + 0.5) / PATCHES_SIDE as f32) - 1.0; + let x = 2.0 * ((gx as f32 + 0.5) / PATCHES_SIDE as f32) - 1.0; + for (j, frequency) in inv_freq.iter().enumerate() { + let ay = 2.0 * std::f32::consts::PI * y * frequency; + let ax = 2.0 * std::f32::consts::PI * x * frequency; + cos[row * ROPE_HALF + j] = ay.cos(); + sin[row * ROPE_HALF + j] = ay.sin(); + cos[row * ROPE_HALF + 16 + j] = ax.cos(); + sin[row * ROPE_HALF + 16 + j] = ax.sin(); + } + } + } + (cos, sin) + } + + pub fn forward_normalized(&self, pixels: &[f32]) -> Result { + if pixels.len() != 3 * IMAGE_SIZE * IMAGE_SIZE { + return Err(DiffusionError::workflow(format!( + "body DINO input has {} values, expected {}", + pixels.len(), + 3 * IMAGE_SIZE * IMAGE_SIZE + ))); + } + + // Patch vectors use [channel][patch_y][patch_x], matching flattened + // conv2d weights [out, channel, patch_y, patch_x]. + let mut patch_rows = vec![0.0f32; NUM_PATCHES * PATCH_DIM]; + let plane = IMAGE_SIZE * IMAGE_SIZE; + for gy in 0..PATCHES_SIDE { + for gx in 0..PATCHES_SIDE { + let row = gy * PATCHES_SIDE + gx; + let base = row * PATCH_DIM; + for c in 0..3 { + for py in 0..PATCH { + let src = c * plane + (gy * PATCH + py) * IMAGE_SIZE + gx * PATCH; + let dst = base + c * PATCH * PATCH + py * PATCH; + patch_rows[dst..dst + PATCH].copy_from_slice(&pixels[src..src + PATCH]); + } + } + } + } + let patch_rows = gpu_upload(&patch_rows, NUM_PATCHES, PATCH_DIM) + .map_err(DiffusionError::model)?; + let patches = self.patch.forward(&patch_rows)?; + let mut hidden = gpu_concat_rows_many(&[&self.prefix, &patches]) + .map_err(DiffusionError::model)?; + + let rows = DINO_PREFIX_TOKENS + NUM_PATCHES; + let (cos, sin) = self.rope_tables(); + let cos = gpu_upload(&cos, rows, ROPE_HALF).map_err(DiffusionError::model)?; + let sin = gpu_upload(&sin, rows, ROPE_HALF).map_err(DiffusionError::model)?; + + for layer in &self.layers { + let normed = gpu_layer_norm_mul_add( + &hidden, + &layer.norm1_w, + &layer.norm1_b, + DINO_NORM_EPS, + ) + .map_err(DiffusionError::model)?; + let q = layer.q.forward(&normed)?; + let k = layer.k.forward(&normed)?; + let v = layer.v.forward(&normed)?; + let q = gpu_rope_half(&q, DINO_HEADS, ROPE_HALF, &cos, &sin) + .map_err(DiffusionError::model)?; + let k = gpu_rope_half(&k, DINO_HEADS, ROPE_HALF, &cos, &sin) + .map_err(DiffusionError::model)?; + let attention = gpu_attention_packed_cross(&q, &k, &v, DINO_HEADS, 0.125) + .map_err(DiffusionError::model)?; + let attention = layer.out.forward(&attention)?; + hidden = gpu_add(&hidden, &attention).map_err(DiffusionError::model)?; + + let normed = gpu_layer_norm_mul_add( + &hidden, + &layer.norm2_w, + &layer.norm2_b, + DINO_NORM_EPS, + ) + .map_err(DiffusionError::model)?; + let gate = layer.gate.forward(&normed)?; + let up = layer.up.forward(&normed)?; + let gate = gpu_silu(&gate).map_err(DiffusionError::model)?; + let ff = gpu_mul(&gate, &up).map_err(DiffusionError::model)?; + let ff = layer.down.forward(&ff)?; + hidden = gpu_add(&hidden, &ff).map_err(DiffusionError::model)?; + } + + let normalized = gpu_layer_norm_mul_add( + &hidden, + &self.final_norm_w, + &self.final_norm_b, + DINO_NORM_EPS, + ) + .map_err(DiffusionError::model)?; + gpu_slice_rows(&normalized, DINO_PREFIX_TOKENS, NUM_PATCHES) + .map_err(DiffusionError::model) + } + + pub fn forward_normalized_host(&self, pixels: &[f32]) -> Result> { + let output = self.forward_normalized(pixels)?; + gpu_download(&output).map_err(DiffusionError::model) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::backend::gpu_device_available; + + fn planar_to_tokens(values: &[f32]) -> Vec { + let mut output = vec![0.0f32; NUM_PATCHES * DINO_DIM]; + for c in 0..DINO_DIM { + for token in 0..NUM_PATCHES { + output[token * DINO_DIM + c] = values[c * NUM_PATCHES + token]; + } + } + output + } + + #[test] + fn gpu_fixture_backbone() { + let Some((_, input)) = crate::fixture::load("backbone_in") else { + eprintln!("body oracle fixtures absent; skipping backbone GPU parity"); + return; + }; + let Some((expected_shape, expected)) = crate::fixture::load("backbone_out") else { + eprintln!("body backbone output fixture absent; skipping backbone GPU parity"); + return; + }; + let Some(weights_path) = crate::fixture::weights_path() else { + eprintln!("body weights path absent; skipping backbone GPU parity"); + return; + }; + if !gpu_device_available() || !crate::fixture::gpu_required_ops_available() { + eprintln!("body GPU unavailable; skipping backbone GPU parity"); + return; + } + let weights = BodyWeights::load(weights_path).expect("load body weights"); + let dino = BodyDino::prepare(&weights).expect("prepare body DINO"); + let actual = dino + .forward_normalized_host(&input) + .expect("body DINO forward"); + let expected = if expected_shape.ends_with(&[DINO_DIM, PATCHES_SIDE, PATCHES_SIDE]) { + planar_to_tokens(&expected) + } else { + expected + }; + assert_eq!(actual.len(), expected.len()); + let mut max_abs = 0.0f32; + let mut abs_error_sum = 0.0f64; + let mut reference_abs_sum = 0.0f64; + for (a, b) in actual.iter().zip(&expected) { + let error = (a - b).abs(); + max_abs = max_abs.max(error); + abs_error_sum += error as f64; + reference_abs_sum += b.abs() as f64; + } + let mean_relative = abs_error_sum / reference_abs_sum.max(f64::EPSILON); + eprintln!( + "body backbone max abs error: {max_abs:.6}; relative mean error: {mean_relative:.6}" + ); + assert!(mean_relative < 3e-2); + } +} diff --git a/libs/ai/models/body/src/fixture.rs b/libs/ai/models/body/src/fixture.rs index 81726bed0..0f83a3a09 100644 --- a/libs/ai/models/body/src/fixture.rs +++ b/libs/ai/models/body/src/fixture.rs @@ -13,19 +13,29 @@ pub fn oracle_dir() -> Option { .find(|candidate| candidate.is_dir()) } -/// Load `.f32` and its shape from the oracle manifest. +/// Load `.f32` (or `.u8`, widened) and its shape from the +/// oracle manifest. pub fn load(name: &str) -> Option<(Vec, Vec)> { let root = oracle_dir()?; let manifest = std::fs::read_to_string(root.join("manifest.json")).ok()?; let shape = manifest_shape(&manifest, name)?; - let bytes = std::fs::read(root.join(format!("{name}.f32"))).ok()?; - if bytes.len() % 4 != 0 { - return None; - } - let values: Vec = bytes - .chunks_exact(4) - .map(|bytes| f32::from_le_bytes(bytes.try_into().unwrap())) - .collect(); + let f32_path = root.join(format!("{name}.f32")); + let values: Vec = if f32_path.is_file() { + let bytes = std::fs::read(f32_path).ok()?; + if bytes.len() % 4 != 0 { + return None; + } + bytes + .chunks_exact(4) + .map(|bytes| f32::from_le_bytes(bytes.try_into().unwrap())) + .collect() + } else { + std::fs::read(root.join(format!("{name}.u8"))) + .ok()? + .into_iter() + .map(f32::from) + .collect() + }; let expected = shape.iter().try_fold(1usize, |count, &dimension| { count.checked_mul(dimension) })?; @@ -62,6 +72,15 @@ pub fn rig() -> Option<&'static MhrRig> { .as_ref() } +/// The GPU tests need a device AND the layer-norm op family; a build without +/// either skips them. +pub fn gpu_required_ops_available() -> bool { + let Ok(input) = crate::backend::gpu_upload(&[0.0], 1, 1) else { + return false; + }; + crate::backend::gpu_layer_norm_mul_add(&input, &[1.0], &[0.0], 1e-5).is_ok() +} + fn manifest_shape(manifest: &str, name: &str) -> Option> { let key = format!("\"{name}\""); let entry = manifest.get(manifest.find(&key)? + key.len()..)?; diff --git a/libs/ai/models/body/src/lib.rs b/libs/ai/models/body/src/lib.rs index 4760ece0e..d54ea0355 100644 --- a/libs/ai/models/body/src/lib.rs +++ b/libs/ai/models/body/src/lib.rs @@ -23,11 +23,14 @@ pub use makepad_ai_common::backend; pub use makepad_ai_common::error; -pub use makepad_ai_common::{DiffusionError, Result}; +pub use makepad_ai_common::{emit_progress, DiffusionError, ProgressHook, Result}; -pub mod weights; +pub mod condition; +pub mod dino; pub mod mhr; pub mod pose; +pub mod preprocess; +pub mod weights; #[cfg(test)] pub mod fixture; diff --git a/libs/ai/models/body/src/preprocess.rs b/libs/ai/models/body/src/preprocess.rs new file mode 100644 index 000000000..c67deaf14 --- /dev/null +++ b/libs/ai/models/body/src/preprocess.rs @@ -0,0 +1,304 @@ +//! CPU crop, camera conditioning, and patch-ray construction. + +use crate::{IMAGE_SIZE, PATCH, PATCHES_SIDE}; + +const IMAGENET_MEAN: [f32; 3] = [0.485, 0.456, 0.406]; +const IMAGENET_STD: [f32; 3] = [0.229, 0.224, 0.225]; + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct CropGeometry { + pub center: [f32; 2], + pub side: f32, + /// Row-major 2x3 affine mapping full-image pixels to crop pixels. + pub affine: [f32; 6], + pub focal: f32, + pub principal: [f32; 2], +} + +pub fn crop_geometry( + bbox_xyxy: [f32; 4], + image_w: usize, + image_h: usize, + intrinsics: Option<[f32; 3]>, +) -> CropGeometry { + let center = [ + 0.5 * (bbox_xyxy[0] + bbox_xyxy[2]), + 0.5 * (bbox_xyxy[1] + bbox_xyxy[3]), + ]; + let mut scale = [ + (bbox_xyxy[2] - bbox_xyxy[0]) * 1.25, + (bbox_xyxy[3] - bbox_xyxy[1]) * 1.25, + ]; + if scale[0] > scale[1] * 0.75 { + scale[1] = scale[0] / 0.75; + } else { + scale[0] = scale[1] * 0.75; + } + let side = scale[0].max(scale[1]); + let k = IMAGE_SIZE as f32 / side; + let affine = [ + k, + 0.0, + 0.5 * IMAGE_SIZE as f32 - k * center[0], + 0.0, + k, + 0.5 * IMAGE_SIZE as f32 - k * center[1], + ]; + let [focal, cx, cy] = intrinsics.unwrap_or_else(|| { + let w = image_w as f32; + let h = image_h as f32; + [(w * w + h * h).sqrt(), 0.5 * w, 0.5 * h] + }); + CropGeometry { + center, + side, + affine, + focal, + principal: [cx, cy], + } +} + +fn rgb_at(rgb: &[u8], w: usize, h: usize, x: isize, y: isize, c: usize) -> f32 { + if x < 0 || y < 0 || x >= w as isize || y >= h as isize { + return 0.0; + } + let index = (y as usize * w + x as usize) * 3 + c; + rgb.get(index).copied().unwrap_or(0) as f32 +} + +fn bilinear_zero_border(rgb: &[u8], w: usize, h: usize, x: f32, y: f32, c: usize) -> f32 { + let x0 = x.floor() as isize; + let y0 = y.floor() as isize; + let fx = x - x0 as f32; + let fy = y - y0 as f32; + let top = rgb_at(rgb, w, h, x0, y0, c) * (1.0 - fx) + + rgb_at(rgb, w, h, x0 + 1, y0, c) * fx; + let bottom = rgb_at(rgb, w, h, x0, y0 + 1, c) * (1.0 - fx) + + rgb_at(rgb, w, h, x0 + 1, y0 + 1, c) * fx; + (top * (1.0 - fy) + bottom * fy).clamp(0.0, 255.0) +} + +pub fn crop_normalized( + rgb: &[u8], + w: usize, + h: usize, + geo: &CropGeometry, +) -> Vec { + let mut output = vec![0.0; 3 * IMAGE_SIZE * IMAGE_SIZE]; + let k = geo.affine[0]; + let plane = IMAGE_SIZE * IMAGE_SIZE; + for v in 0..IMAGE_SIZE { + let src_y = (v as f32 - geo.affine[5]) / k; + for u in 0..IMAGE_SIZE { + let src_x = (u as f32 - geo.affine[2]) / k; + for c in 0..3 { + let pixel = bilinear_zero_border(rgb, w, h, src_x, src_y, c) / 255.0; + output[c * plane + v * IMAGE_SIZE + u] = + (pixel - IMAGENET_MEAN[c]) / IMAGENET_STD[c]; + } + } + } + output +} + +pub fn condition_info(geo: &CropGeometry) -> [f32; 3] { + [ + (geo.center[0] - geo.principal[0]) / geo.focal, + (geo.center[1] - geo.principal[1]) / geo.focal, + geo.side / geo.focal, + ] +} + +/// Where patch `index` samples the 512-wide crop axis: the reference shrinks +/// the ray field by 16 with an antialiased bilinear filter, a triangle of +/// half-width 16 taps centred on `(index + 0.5) * 16 - 0.5`, normalised over +/// the taps that fall inside the image. The rays are affine, so the filter +/// reduces to sampling at the taps' weighted mean position: the block centre +/// for interior patches, pulled inward at the two edges (oracle-verified: +/// block centres are 0.1 off in the conditioned context, this is 1e-3). +pub fn patch_sample_coord(index: usize) -> f32 { + let centre = (index as f32 + 0.5) * PATCH as f32 - 0.5; + let mut weight_sum = 0.0f32; + let mut coord_sum = 0.0f32; + let lo = (centre - PATCH as f32).floor().max(0.0) as usize; + let hi = ((centre + PATCH as f32).ceil() as usize).min(IMAGE_SIZE - 1); + for tap in lo..=hi { + let weight = (1.0 - (tap as f32 - centre).abs() / PATCH as f32).max(0.0); + weight_sum += weight; + coord_sum += weight * tap as f32; + } + coord_sum / weight_sum +} + +pub fn patch_rays(geo: &CropGeometry) -> Vec { + let mut rays = Vec::with_capacity(PATCHES_SIDE * PATCHES_SIDE * 2); + let k = geo.affine[0]; + let coords: Vec = (0..PATCHES_SIDE).map(patch_sample_coord).collect(); + for gy in 0..PATCHES_SIDE { + let full_y = (coords[gy] - geo.affine[5]) / k; + for gx in 0..PATCHES_SIDE { + let full_x = (coords[gx] - geo.affine[2]) / k; + rays.push((full_x - geo.principal[0]) / geo.focal); + rays.push((full_y - geo.principal[1]) / geo.focal); + } + } + rays +} + +pub fn full_to_crop(kp2d_full: &[f32], geo: &CropGeometry) -> Vec { + let mut output = Vec::with_capacity(kp2d_full.len() / 2 * 2); + for point in kp2d_full.chunks_exact(2) { + let x = geo.affine[0] * point[0] + geo.affine[1] * point[1] + geo.affine[2]; + let y = geo.affine[3] * point[0] + geo.affine[4] * point[1] + geo.affine[5]; + output.push(x / IMAGE_SIZE as f32 - 0.5); + output.push(y / IMAGE_SIZE as f32 - 0.5); + } + output +} + +#[cfg(test)] +mod tests { + use super::*; + + fn assert_close(actual: f32, expected: f32, tolerance: f32) { + assert!( + (actual - expected).abs() <= tolerance, + "actual={actual} expected={expected} tolerance={tolerance}" + ); + } + + #[test] + fn geometry_fixes_aspect_and_centers_affine() { + let geo = crop_geometry([10.0, 20.0, 50.0, 50.0], 100, 80, Some([100.0, 50.0, 40.0])); + assert_eq!(geo.center, [30.0, 35.0]); + // 1.25 * width = 50; the 0.75 aspect fix makes height 50 / 0.75. + assert_close(geo.side, 200.0 / 3.0, 1e-5); + let mapped_x = geo.affine[0] * geo.center[0] + geo.affine[2]; + let mapped_y = geo.affine[4] * geo.center[1] + geo.affine[5]; + assert_close(mapped_x, 256.0, 1e-5); + assert_close(mapped_y, 256.0, 1e-5); + } + + #[test] + fn patch_rays_use_antialiased_tap_positions() { + // Interior patches sit on their block centre; the two edge patches + // are pulled inward by the clipped triangle filter (symmetrically). + assert_close(patch_sample_coord(1), 23.5, 1e-5); + assert_close(patch_sample_coord(16), 263.5, 1e-5); + assert_close(patch_sample_coord(0), 9.026_786, 1e-4); + assert_close(patch_sample_coord(31), 511.0 - 9.026_786, 1e-4); + let geo = CropGeometry { + center: [256.0, 256.0], + side: 512.0, + affine: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0], + focal: 512.0, + principal: [256.0, 256.0], + }; + let rays = patch_rays(&geo); + assert_eq!(rays.len(), 1024 * 2); + let token = 5 * PATCHES_SIDE + 3; + assert_close(rays[token * 2], (55.5 - 256.0) / 512.0, 1e-6); + assert_close(rays[token * 2 + 1], (87.5 - 256.0) / 512.0, 1e-6); + } + + #[test] + fn fixture_preprocess_condition_and_rays() { + let Some((image_shape, image_values)) = crate::fixture::load("input_rgb_u8") else { + eprintln!("body oracle fixtures absent; skipping preprocessing parity"); + return; + }; + let Some((_, center)) = crate::fixture::load("batch_bbox_center") else { + eprintln!("body bbox-center fixture absent; skipping preprocessing parity"); + return; + }; + let Some((_, scale)) = crate::fixture::load("batch_bbox_scale") else { + eprintln!("body bbox-scale fixture absent; skipping preprocessing parity"); + return; + }; + let Some((_, cam)) = crate::fixture::load("batch_cam_int") else { + eprintln!("body camera fixture absent; skipping preprocessing parity"); + return; + }; + let Some((_, expected_crop)) = crate::fixture::load("backbone_in") else { + eprintln!("body backbone-input fixture absent; skipping preprocessing parity"); + return; + }; + assert_eq!(image_shape.len(), 3); + let (h, w) = (image_shape[0], image_shape[1]); + let center = [center[center.len() - 2], center[center.len() - 1]]; + let side = scale[scale.len() - 2].max(scale[scale.len() - 1]); + let (focal, cx, cy) = if cam.len() >= 9 { + (cam[0], cam[2], cam[5]) + } else { + (cam[0], cam[cam.len() - 2], cam[cam.len() - 1]) + }; + let k = IMAGE_SIZE as f32 / side; + let geo = CropGeometry { + center, + side, + affine: [ + k, + 0.0, + 256.0 - k * center[0], + 0.0, + k, + 256.0 - k * center[1], + ], + focal, + principal: [cx, cy], + }; + let rgb: Vec = image_values.iter().map(|value| *value as u8).collect(); + let crop = crop_normalized(&rgb, w, h, &geo); + assert_eq!(crop.len(), expected_crop.len()); + let (max_crop_index, max_crop_error) = crop + .iter() + .zip(&expected_crop) + .enumerate() + .map(|(index, (a, b))| (index, (a - b).abs())) + .max_by(|a, b| a.1.total_cmp(&b.1)) + .unwrap(); + eprintln!( + "body crop max abs error: {max_crop_error:.6} at {max_crop_index}: actual={} expected={}", + crop[max_crop_index], expected_crop[max_crop_index] + ); + assert!(max_crop_error <= 2e-2); + + if let Some((_, expected_condition)) = crate::fixture::load("condition_info") { + let actual = condition_info(&geo); + for i in 0..3 { + assert_close(actual[i], expected_condition[i], 1e-5); + } + } + + if let Some((_, full_rays)) = crate::fixture::load("raycond_rays_in") { + // The full-resolution ray field is affine in (x, y): the patch + // ray must equal the field sampled (bilinearly) at the + // antialiased tap position on each axis. + assert_eq!(full_rays.len(), 2 * IMAGE_SIZE * IMAGE_SIZE); + let actual = patch_rays(&geo); + let plane = IMAGE_SIZE * IMAGE_SIZE; + let sample = |c: usize, x: f32, y: f32| { + let x0 = x.floor() as usize; + let y0 = y.floor() as usize; + let (x1, y1) = ((x0 + 1).min(IMAGE_SIZE - 1), (y0 + 1).min(IMAGE_SIZE - 1)); + let (fx, fy) = (x - x0 as f32, y - y0 as f32); + let at = |xx: usize, yy: usize| full_rays[c * plane + yy * IMAGE_SIZE + xx]; + (at(x0, y0) * (1.0 - fx) + at(x1, y0) * fx) * (1.0 - fy) + + (at(x0, y1) * (1.0 - fx) + at(x1, y1) * fx) * fy + }; + let mut max_ray_error = 0.0f32; + for gy in 0..PATCHES_SIDE { + for gx in 0..PATCHES_SIDE { + let token = gy * PATCHES_SIDE + gx; + let (x, y) = (patch_sample_coord(gx), patch_sample_coord(gy)); + for c in 0..2 { + let expected = sample(c, x, y); + max_ray_error = max_ray_error.max((actual[token * 2 + c] - expected).abs()); + } + } + } + eprintln!("body patch-ray max abs error: {max_ray_error:.7}"); + assert!(max_ray_error <= 1e-4); + } + } +} diff --git a/libs/ai/models/common/src/gpu.rs b/libs/ai/models/common/src/gpu.rs index 650c0782f..99c9b10ab 100644 --- a/libs/ai/models/common/src/gpu.rs +++ b/libs/ai/models/common/src/gpu.rs @@ -2326,7 +2326,14 @@ mod imp { _add: &[f32], _eps: f32, ) -> Result { - Err(GPU_UNAVAILABLE.to_string()) + #[cfg(target_os = "macos")] + { + return makepad_ai_metal::gpu_tensor::layer_norm_mul_add(_x, _mul, _add, _eps); + } + #[cfg(not(target_os = "macos"))] + { + Err(GPU_UNAVAILABLE.to_string()) + } } pub fn gpu_layer_norm_mul_add_cached( @@ -2337,7 +2344,14 @@ mod imp { _add: &[f32], _eps: f32, ) -> Result { - Err(GPU_UNAVAILABLE.to_string()) + #[cfg(target_os = "macos")] + { + return makepad_ai_metal::gpu_tensor::layer_norm_mul_add(_x, _mul, _add, _eps); + } + #[cfg(not(target_os = "macos"))] + { + Err(GPU_UNAVAILABLE.to_string()) + } } pub fn gpu_layer_norm_pytorch( @@ -2754,7 +2768,14 @@ mod imp { _cos_table: &GpuTensor, _sin_table: &GpuTensor, ) -> Result { - Err(GPU_UNAVAILABLE.to_string()) + #[cfg(target_os = "macos")] + { + return makepad_ai_metal::gpu_tensor::rope_half(_x, _head_count, _rot_half, _cos_table, _sin_table); + } + #[cfg(not(target_os = "macos"))] + { + Err(GPU_UNAVAILABLE.to_string()) + } } pub fn gpu_rope_half_bf16( From 69d842c4008d838e087825cb3852e09cb29840f1 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 22:58:29 +0200 Subject: [PATCH 019/417] ai-body: the promptable pose decoder and its refinement loop, oracle-matched on Metal decoder.rs builds the 145-row token set (pose, previous, prompt, two hand-box rows, 70 keypoint rows, 70 3D-keypoint rows), runs the six layers with the SAM-style repeated positional encoding (none on the first layer's self-attention), cross-attends against the ray-conditioned context, and after each step hands the normalised pose token to the heads and updates the keypoint rows from the caller's feedback: the 2D-keypoint positional FFN and the bilinearly sampled context features on the valid rows, the pelvis-centred 3D positional FFN on the rest. heads.rs holds the host-side ReLU FFN heads, the refinement FFNs, the hand-box MLP and the hand classifier. Against the oracle on Metal, every layer's residual stream is within 6e-3, every step's pose head within 8e-4 and camera head within 2e-5; token assembly and the host heads match to 1e-4. Co-Authored-By: Claude Fable 5.1 --- libs/ai/models/body/src/decoder.rs | 1043 ++++++++++++++++++++++++++++ libs/ai/models/body/src/heads.rs | 215 ++++++ libs/ai/models/body/src/lib.rs | 2 + 3 files changed, 1260 insertions(+) create mode 100644 libs/ai/models/body/src/decoder.rs create mode 100644 libs/ai/models/body/src/heads.rs diff --git a/libs/ai/models/body/src/decoder.rs b/libs/ai/models/body/src/decoder.rs new file mode 100644 index 000000000..e9bbaef8b --- /dev/null +++ b/libs/ai/models/body/src/decoder.rs @@ -0,0 +1,1043 @@ +//! Promptable body-pose decoder and its six-step refinement loop. + +use crate::backend::{ + gpu_add, gpu_attention_packed_cross, gpu_download, gpu_gelu_erf, + gpu_layer_norm_mul_add, gpu_linear_f32_resident, gpu_upload, GpuTensor, +}; +use crate::heads::{DecoderHeads, HostLinear}; +use crate::weights::BodyWeights; +use crate::{ + DEC_DEPTH, DEC_DIM, DEC_FFN, DEC_HEADS, DEC_INNER, DEC_NORM_EPS, DINO_DIM, NCAM, + NPOSE, NUM_KEYPOINTS, NUM_PATCHES, PATCHES_SIDE, DiffusionError, Result, +}; + +pub const TOKEN_ROWS: usize = 5 + 2 * NUM_KEYPOINTS; +const KEYPOINT_ROW: usize = 5; +const KEYPOINT3D_ROW: usize = KEYPOINT_ROW + NUM_KEYPOINTS; +const ATTN_SCALE: f32 = 0.125; + +#[derive(Clone)] +struct NormWeights { + weight: Vec, + bias: Vec, +} + +impl NormWeights { + fn load(weights: &BodyWeights, name: &str, dim: usize) -> Result { + Ok(Self { + weight: weights.f32_shaped(&format!("{name}.weight"), &[dim])?, + bias: weights.f32_shaped(&format!("{name}.bias"), &[dim])?, + }) + } +} + +#[derive(Clone)] +struct AttentionWeights { + q: HostLinear, + k: HostLinear, + v: HostLinear, + out: HostLinear, +} + +impl AttentionWeights { + fn load( + weights: &BodyWeights, + name: &str, + query_dim: usize, + key_value_dim: usize, + output_name: &str, + ) -> Result { + Ok(Self { + q: HostLinear::load(weights, &format!("{name}.q_proj"), DEC_INNER, query_dim)?, + k: HostLinear::load( + weights, + &format!("{name}.k_proj"), + DEC_INNER, + key_value_dim, + )?, + v: HostLinear::load( + weights, + &format!("{name}.v_proj"), + DEC_INNER, + key_value_dim, + )?, + out: HostLinear::load(weights, &format!("{name}.{output_name}"), DEC_DIM, DEC_INNER)?, + }) + } +} + +#[derive(Clone)] +struct DecoderLayerWeights { + ln_pe_1: NormWeights, + ln_pe_2: NormWeights, + ln1: NormWeights, + self_attn: AttentionWeights, + ln2_1: NormWeights, + ln2_2: NormWeights, + cross_attn: AttentionWeights, + ln3: NormWeights, + ffn_first: HostLinear, + ffn_second: HostLinear, +} + +#[derive(Clone)] +struct TokenWeights { + init_to_token: HostLinear, + prev_to_token: HostLinear, + prompt_to_token: HostLinear, + invalid_point_embed: Vec, + hand_box_embedding: Vec, + keypoint_embedding: Vec, + keypoint3d_embedding: Vec, +} + +/// Host representation of every f32 tensor owned by the decoder lane. +/// Loading this type does not require a GPU and is used by fixture tests for +/// token assembly and head parity. +pub struct DecoderWeights { + layers: Vec, + norm_final: NormWeights, + heads: DecoderHeads, + init_pose: Vec, + init_camera: Vec, + tokens: TokenWeights, +} + +impl DecoderWeights { + pub fn load(weights: &BodyWeights) -> Result { + let mut layers = Vec::with_capacity(DEC_DEPTH); + for index in 0..DEC_DEPTH { + let prefix = format!("decoder.layers.{index}"); + layers.push(DecoderLayerWeights { + ln_pe_1: NormWeights::load(weights, &format!("{prefix}.ln_pe_1"), DEC_DIM)?, + ln_pe_2: NormWeights::load(weights, &format!("{prefix}.ln_pe_2"), DINO_DIM)?, + ln1: NormWeights::load(weights, &format!("{prefix}.ln1"), DEC_DIM)?, + self_attn: AttentionWeights::load( + weights, + &format!("{prefix}.self_attn"), + DEC_DIM, + DEC_DIM, + "proj", + )?, + ln2_1: NormWeights::load(weights, &format!("{prefix}.ln2_1"), DEC_DIM)?, + ln2_2: NormWeights::load(weights, &format!("{prefix}.ln2_2"), DINO_DIM)?, + cross_attn: AttentionWeights::load( + weights, + &format!("{prefix}.cross_attn"), + DEC_DIM, + DINO_DIM, + "proj", + )?, + ln3: NormWeights::load(weights, &format!("{prefix}.ln3"), DEC_DIM)?, + ffn_first: HostLinear::load( + weights, + &format!("{prefix}.ffn.layers.0.0"), + DEC_FFN, + DEC_DIM, + )?, + ffn_second: HostLinear::load( + weights, + &format!("{prefix}.ffn.layers.1"), + DEC_DIM, + DEC_FFN, + )?, + }); + } + Ok(Self { + layers, + norm_final: NormWeights::load(weights, "decoder.norm_final", DEC_DIM)?, + heads: DecoderHeads::load(weights)?, + init_pose: weights.f32_shaped("init_pose.weight", &[1, NPOSE])?, + init_camera: weights.f32_shaped("init_camera.weight", &[1, NCAM])?, + tokens: TokenWeights { + init_to_token: HostLinear::load( + weights, + "init_to_token_mhr", + DEC_DIM, + NPOSE + NCAM + 3, + )?, + prev_to_token: HostLinear::load( + weights, + "prev_to_token_mhr", + DEC_DIM, + NPOSE + NCAM, + )?, + prompt_to_token: HostLinear::load( + weights, + "prompt_to_token", + DEC_DIM, + DINO_DIM, + )?, + invalid_point_embed: weights.f32_shaped( + "prompt_encoder.invalid_point_embed.weight", + &[1, DINO_DIM], + )?, + hand_box_embedding: weights + .f32_shaped("hand_box_embedding.weight", &[2, DEC_DIM])?, + keypoint_embedding: weights + .f32_shaped("keypoint_embedding.weight", &[NUM_KEYPOINTS, DEC_DIM])?, + keypoint3d_embedding: weights + .f32_shaped("keypoint3d_embedding.weight", &[NUM_KEYPOINTS, DEC_DIM])?, + }, + }) + } + + pub fn build_tokens(&self, condition_info: [f32; 3]) -> TokenSet { + build_tokens(&self.tokens, &self.init_pose, &self.init_camera, condition_info) + } + + pub fn pose_head_raw(&self, input: &[f32]) -> Vec { + self.heads.pose(input) + } + + pub fn camera_head_raw(&self, input: &[f32]) -> Vec { + self.heads.camera(input) + } + + pub fn keypoint_posemb(&self, input: &[f32]) -> Vec { + self.heads.keypoint_posemb(input) + } + + pub fn keypoint3d_posemb(&self, input: &[f32]) -> Vec { + self.heads.keypoint3d_posemb(input) + } + + pub fn keypoint_features(&self, input: &[f32]) -> Vec { + self.heads.keypoint_features(input) + } +} + +struct GpuLinear { + weight: GpuTensor, + bias: GpuTensor, +} + +impl GpuLinear { + fn upload(linear: HostLinear) -> Result { + let (weight, bias, output, input) = linear.into_parts(); + Ok(Self { + weight: gpu_upload(&weight, output, input).map_err(DiffusionError::model)?, + bias: gpu_upload(&bias, 1, output).map_err(DiffusionError::model)?, + }) + } + + fn forward(&self, input: &GpuTensor) -> Result { + gpu_linear_f32_resident(input, &self.weight, Some(&self.bias)) + .map_err(DiffusionError::model) + } +} + +struct GpuAttention { + q: GpuLinear, + k: GpuLinear, + v: GpuLinear, + out: GpuLinear, +} + +impl GpuAttention { + fn upload(weights: AttentionWeights) -> Result { + Ok(Self { + q: GpuLinear::upload(weights.q)?, + k: GpuLinear::upload(weights.k)?, + v: GpuLinear::upload(weights.v)?, + out: GpuLinear::upload(weights.out)?, + }) + } + + fn forward(&self, query: &GpuTensor, key: &GpuTensor, value: &GpuTensor) -> Result { + let query = self.q.forward(query)?; + let key = self.k.forward(key)?; + let value = self.v.forward(value)?; + let attended = gpu_attention_packed_cross( + &query, + &key, + &value, + DEC_HEADS, + ATTN_SCALE, + ) + .map_err(DiffusionError::model)?; + self.out.forward(&attended) + } +} + +struct DecoderLayer { + ln_pe_1: NormWeights, + ln_pe_2: NormWeights, + ln1: NormWeights, + self_attn: GpuAttention, + ln2_1: NormWeights, + ln2_2: NormWeights, + cross_attn: GpuAttention, + ln3: NormWeights, + ffn_first: GpuLinear, + ffn_second: GpuLinear, +} + +impl DecoderLayer { + fn upload(weights: DecoderLayerWeights) -> Result { + Ok(Self { + ln_pe_1: weights.ln_pe_1, + ln_pe_2: weights.ln_pe_2, + ln1: weights.ln1, + self_attn: GpuAttention::upload(weights.self_attn)?, + ln2_1: weights.ln2_1, + ln2_2: weights.ln2_2, + cross_attn: GpuAttention::upload(weights.cross_attn)?, + ln3: weights.ln3, + ffn_first: GpuLinear::upload(weights.ffn_first)?, + ffn_second: GpuLinear::upload(weights.ffn_second)?, + }) + } +} + +pub struct Decoder { + layers: Vec, + norm_final: NormWeights, + heads: DecoderHeads, + init_pose: Vec, + init_camera: Vec, + tokens: TokenWeights, +} + +#[derive(Clone, Debug)] +pub struct TokenSet { + pub tokens: Vec, + pub token_augment: Vec, +} + +#[derive(Clone, Debug)] +pub struct StepInput { + pub layer: usize, + pub pose_pred_519: Vec, + pub cam_pred_3: Vec, + pub tokens_normed_row0: Vec, +} + +#[derive(Clone, Debug, Default)] +pub struct StepFeedback { + pub kp2d_cropped: Vec, + pub depth: Vec, + pub kp3d: Vec, +} + +#[derive(Clone, Debug)] +pub struct DecoderOutput { + pub tokens_normed: Vec, + pub hand_boxes: [[f32; 4]; 2], + pub hand_logits: [[f32; 2]; 2], + pub last_pose_pred: Vec, + pub last_cam_pred: Vec, +} + +impl Decoder { + pub fn load(weights: &BodyWeights) -> Result { + Self::from_weights(DecoderWeights::load(weights)?) + } + + fn from_weights(weights: DecoderWeights) -> Result { + let mut layers = Vec::with_capacity(DEC_DEPTH); + for layer in weights.layers { + layers.push(DecoderLayer::upload(layer)?); + } + Ok(Self { + layers, + norm_final: weights.norm_final, + heads: weights.heads, + init_pose: weights.init_pose, + init_camera: weights.init_camera, + tokens: weights.tokens, + }) + } + + pub fn build_tokens(&self, condition_info: [f32; 3]) -> TokenSet { + build_tokens(&self.tokens, &self.init_pose, &self.init_camera, condition_info) + } + + pub fn run( + &self, + tokens: TokenSet, + context: &GpuTensor, + context_pe: &[f32], + step: impl FnMut(StepInput) -> StepFeedback, + ) -> Result { + self.run_impl(tokens, context, context_pe, step, None) + } + + fn run_impl( + &self, + mut tokens: TokenSet, + context: &GpuTensor, + context_pe: &[f32], + mut step: F, + mut trace: Option<&mut dyn FnMut(usize, &GpuTensor, &[f32]) -> Result<()>>, + ) -> Result + where + F: FnMut(StepInput) -> StepFeedback, + { + validate_run_inputs(&tokens, context, context_pe)?; + let context_host = gpu_download(context).map_err(DiffusionError::model)?; + let context_pe = gpu_upload(context_pe, NUM_PATCHES, DINO_DIM) + .map_err(DiffusionError::model)?; + let mut hidden = gpu_upload(&tokens.tokens, TOKEN_ROWS, DEC_DIM) + .map_err(DiffusionError::model)?; + let mut final_normed = Vec::new(); + let mut last_pose = Vec::new(); + let mut last_camera = Vec::new(); + + for (layer_index, layer) in self.layers.iter().enumerate() { + let token_pe = gpu_upload(&tokens.token_augment, TOKEN_ROWS, DEC_DIM) + .map_err(DiffusionError::model)?; + let token_pe = layer_norm_gpu(&token_pe, &layer.ln_pe_1)?; + let image_pe = layer_norm_gpu(&context_pe, &layer.ln_pe_2)?; + + let normed = layer_norm_gpu(&hidden, &layer.ln1)?; + let self_update = if layer_index == 0 { + layer.self_attn.forward(&normed, &normed, &normed)? + } else { + let qk = gpu_add(&normed, &token_pe).map_err(DiffusionError::model)?; + layer.self_attn.forward(&qk, &qk, &normed)? + }; + hidden = gpu_add(&hidden, &self_update).map_err(DiffusionError::model)?; + + let query = layer_norm_gpu(&hidden, &layer.ln2_1)?; + let query = gpu_add(&query, &token_pe).map_err(DiffusionError::model)?; + let context_normed = layer_norm_gpu(context, &layer.ln2_2)?; + let key = gpu_add(&context_normed, &image_pe).map_err(DiffusionError::model)?; + let cross_update = layer + .cross_attn + .forward(&query, &key, &context_normed)?; + hidden = gpu_add(&hidden, &cross_update).map_err(DiffusionError::model)?; + + let normed = layer_norm_gpu(&hidden, &layer.ln3)?; + let ffn = layer.ffn_first.forward(&normed)?; + let ffn = gpu_gelu_erf(&ffn).map_err(DiffusionError::model)?; + let ffn = layer.ffn_second.forward(&ffn)?; + hidden = gpu_add(&hidden, &ffn).map_err(DiffusionError::model)?; + + let normed = layer_norm_gpu(&hidden, &self.norm_final)?; + final_normed = gpu_download(&normed).map_err(DiffusionError::model)?; + if let Some(callback) = &mut trace { + (**callback)(layer_index, &hidden, &final_normed)?; + } + let pose_token = &final_normed[..DEC_DIM]; + last_pose = self.heads.pose(pose_token); + add_in_place(&mut last_pose, &self.init_pose); + last_camera = self.heads.camera(pose_token); + add_in_place(&mut last_camera, &self.init_camera); + let feedback = step(StepInput { + layer: layer_index, + pose_pred_519: last_pose.clone(), + cam_pred_3: last_camera.clone(), + tokens_normed_row0: pose_token.to_vec(), + }); + + if layer_index + 1 < DEC_DEPTH { + let delta = self.refinement_update(&mut tokens.token_augment, &context_host, feedback)?; + let delta = gpu_upload(&delta, TOKEN_ROWS, DEC_DIM) + .map_err(DiffusionError::model)?; + hidden = gpu_add(&hidden, &delta).map_err(DiffusionError::model)?; + } + } + + let mut hand_boxes = [[0.0; 4]; 2]; + let mut hand_logits = [[0.0; 2]; 2]; + for hand in 0..2 { + let row = &final_normed[(3 + hand) * DEC_DIM..(4 + hand) * DEC_DIM]; + hand_boxes[hand] = self.heads.bbox(row); + hand_logits[hand] = self.heads.hand_logits(row); + } + Ok(DecoderOutput { + tokens_normed: final_normed, + hand_boxes, + hand_logits, + last_pose_pred: last_pose, + last_cam_pred: last_camera, + }) + } + + fn refinement_update( + &self, + token_augment: &mut [f32], + context: &[f32], + feedback: StepFeedback, + ) -> Result> { + if feedback.kp2d_cropped.len() != NUM_KEYPOINTS * 2 + || feedback.depth.len() != NUM_KEYPOINTS + || feedback.kp3d.len() != NUM_KEYPOINTS * 3 + { + return Err(DiffusionError::workflow(format!( + "decoder feedback shapes are kp2d={} depth={} kp3d={}, expected {}, {}, {}", + feedback.kp2d_cropped.len(), + feedback.depth.len(), + feedback.kp3d.len(), + NUM_KEYPOINTS * 2, + NUM_KEYPOINTS, + NUM_KEYPOINTS * 3, + ))); + } + + let valid: Vec = feedback + .kp2d_cropped + .chunks_exact(2) + .zip(&feedback.depth) + .map(|(point, &depth)| { + (0.0..=1.0).contains(&(point[0] + 0.5)) + && (0.0..=1.0).contains(&(point[1] + 0.5)) + && depth >= 1e-5 + }) + .collect(); + let posemb = self.heads.keypoint_posemb(&feedback.kp2d_cropped); + let mut sampled = vec![0.0f32; NUM_KEYPOINTS * DINO_DIM]; + for (index, point) in feedback.kp2d_cropped.chunks_exact(2).enumerate() { + if valid[index] { + let value = bilinear_sample( + context, + PATCHES_SIDE, + PATCHES_SIDE, + DINO_DIM, + 2.0 * point[0], + 2.0 * point[1], + ); + sampled[index * DINO_DIM..(index + 1) * DINO_DIM] + .copy_from_slice(&value); + } + } + let features = self.heads.keypoint_features(&sampled); + + let hip9 = &feedback.kp3d[9 * 3..10 * 3]; + let hip10 = &feedback.kp3d[10 * 3..11 * 3]; + let pelvis = [ + 0.5 * (hip9[0] + hip10[0]), + 0.5 * (hip9[1] + hip10[1]), + 0.5 * (hip9[2] + hip10[2]), + ]; + let mut centered = feedback.kp3d; + for point in centered.chunks_exact_mut(3) { + for axis in 0..3 { + point[axis] -= pelvis[axis]; + } + } + let posemb3d = self.heads.keypoint3d_posemb(¢ered); + + let mut delta = vec![0.0f32; TOKEN_ROWS * DEC_DIM]; + for index in 0..NUM_KEYPOINTS { + let row2d = (KEYPOINT_ROW + index) * DEC_DIM; + if valid[index] { + token_augment[row2d..row2d + DEC_DIM] + .copy_from_slice(&posemb[index * DEC_DIM..(index + 1) * DEC_DIM]); + delta[row2d..row2d + DEC_DIM] + .copy_from_slice(&features[index * DEC_DIM..(index + 1) * DEC_DIM]); + } else { + token_augment[row2d..row2d + DEC_DIM].fill(0.0); + } + let row3d = (KEYPOINT3D_ROW + index) * DEC_DIM; + token_augment[row3d..row3d + DEC_DIM] + .copy_from_slice(&posemb3d[index * DEC_DIM..(index + 1) * DEC_DIM]); + } + Ok(delta) + } +} + +fn build_tokens( + weights: &TokenWeights, + init_pose: &[f32], + init_camera: &[f32], + condition_info: [f32; 3], +) -> TokenSet { + let mut init_input = Vec::with_capacity(3 + NPOSE + NCAM); + init_input.extend_from_slice(&condition_info); + init_input.extend_from_slice(init_pose); + init_input.extend_from_slice(init_camera); + let pose_token = weights.init_to_token.forward_row(&init_input); + + let mut previous_input = Vec::with_capacity(NPOSE + NCAM); + previous_input.extend_from_slice(init_pose); + previous_input.extend_from_slice(init_camera); + let previous_token = weights.prev_to_token.forward_row(&previous_input); + let prompt_token = weights + .prompt_to_token + .forward_row(&weights.invalid_point_embed); + + let mut tokens = Vec::with_capacity(TOKEN_ROWS * DEC_DIM); + tokens.extend_from_slice(&pose_token); + tokens.extend_from_slice(&previous_token); + tokens.extend_from_slice(&prompt_token); + tokens.extend_from_slice(&weights.hand_box_embedding); + tokens.extend_from_slice(&weights.keypoint_embedding); + tokens.extend_from_slice(&weights.keypoint3d_embedding); + debug_assert_eq!(tokens.len(), TOKEN_ROWS * DEC_DIM); + + let mut token_augment = vec![0.0f32; TOKEN_ROWS * DEC_DIM]; + token_augment[DEC_DIM..2 * DEC_DIM].copy_from_slice(&previous_token); + token_augment[2 * DEC_DIM..3 * DEC_DIM].copy_from_slice(&prompt_token); + TokenSet { + tokens, + token_augment, + } +} + +fn validate_run_inputs(tokens: &TokenSet, context: &GpuTensor, context_pe: &[f32]) -> Result<()> { + if tokens.tokens.len() != TOKEN_ROWS * DEC_DIM + || tokens.token_augment.len() != TOKEN_ROWS * DEC_DIM + { + return Err(DiffusionError::workflow(format!( + "decoder token shapes are {} and {}, expected {}", + tokens.tokens.len(), + tokens.token_augment.len(), + TOKEN_ROWS * DEC_DIM, + ))); + } + if context.rows() != NUM_PATCHES || context.cols() != DINO_DIM { + return Err(DiffusionError::workflow(format!( + "decoder context is {}x{}, expected {}x{}", + context.rows(), + context.cols(), + NUM_PATCHES, + DINO_DIM, + ))); + } + if context_pe.len() != NUM_PATCHES * DINO_DIM { + return Err(DiffusionError::workflow(format!( + "decoder context PE has {} values, expected {}", + context_pe.len(), + NUM_PATCHES * DINO_DIM, + ))); + } + Ok(()) +} + +fn layer_norm_gpu(input: &GpuTensor, norm: &NormWeights) -> Result { + gpu_layer_norm_mul_add(input, &norm.weight, &norm.bias, DEC_NORM_EPS) + .map_err(DiffusionError::model) +} + +fn add_in_place(values: &mut [f32], offsets: &[f32]) { + debug_assert_eq!(values.len(), offsets.len()); + for (value, offset) in values.iter_mut().zip(offsets) { + *value += offset; + } +} + +#[cfg(test)] +fn self_attention_qk_input(layer: usize, normed: &[f32], token_pe: &[f32]) -> Vec { + debug_assert_eq!(normed.len(), token_pe.len()); + if layer == 0 { + normed.to_vec() + } else { + normed.iter().zip(token_pe).map(|(x, pe)| x + pe).collect() + } +} + +#[cfg(test)] +fn layer_norm_host( + input: &[f32], + rows: usize, + cols: usize, + weight: &[f32], + bias: &[f32], + eps: f32, +) -> Vec { + debug_assert_eq!(input.len(), rows * cols); + debug_assert_eq!(weight.len(), cols); + debug_assert_eq!(bias.len(), cols); + let mut output = vec![0.0f32; input.len()]; + for (source, target) in input + .chunks_exact(cols) + .zip(output.chunks_exact_mut(cols)) + { + let mean = source.iter().sum::() / cols as f32; + let variance = source + .iter() + .map(|value| { + let centered = value - mean; + centered * centered + }) + .sum::() + / cols as f32; + let inv_std = 1.0 / (variance + eps).sqrt(); + for column in 0..cols { + target[column] = (source[column] - mean) * inv_std * weight[column] + bias[column]; + } + } + output +} + +/// Align-corners-false bilinear sampling of an interleaved HWC grid. +fn bilinear_sample( + grid: &[f32], + width: usize, + height: usize, + channels: usize, + normalized_x: f32, + normalized_y: f32, +) -> Vec { + debug_assert_eq!(grid.len(), width * height * channels); + let x = (normalized_x + 1.0) * 0.5 * width as f32 - 0.5; + let y = (normalized_y + 1.0) * 0.5 * height as f32 - 0.5; + let x0 = x.floor() as isize; + let y0 = y.floor() as isize; + let dx = x - x0 as f32; + let dy = y - y0 as f32; + let neighbors = [ + (x0, y0, (1.0 - dx) * (1.0 - dy)), + (x0 + 1, y0, dx * (1.0 - dy)), + (x0, y0 + 1, (1.0 - dx) * dy), + (x0 + 1, y0 + 1, dx * dy), + ]; + let mut output = vec![0.0f32; channels]; + for (nx, ny, weight) in neighbors { + if nx < 0 || ny < 0 || nx >= width as isize || ny >= height as isize { + continue; + } + let offset = (ny as usize * width + nx as usize) * channels; + for channel in 0..channels { + output[channel] += weight * grid[offset + channel]; + } + } + output +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::backend::gpu_device_available; + use crate::fixture; + + fn identity(input: &[f32]) -> Vec { + input.to_vec() + } + + #[test] + fn token_layout_and_augment_rows_match_contract() { + let pose = vec![1.0; DEC_DIM]; + let previous = vec![2.0; DEC_DIM]; + let prompt = vec![3.0; DEC_DIM]; + let hand: Vec = (0..2 * DEC_DIM).map(|i| 10.0 + i as f32).collect(); + let keypoint: Vec = (0..NUM_KEYPOINTS * DEC_DIM) + .map(|i| 20.0 + i as f32) + .collect(); + let keypoint3d: Vec = (0..NUM_KEYPOINTS * DEC_DIM) + .map(|i| 30.0 + i as f32) + .collect(); + let weights = TokenWeights { + init_to_token: HostLinear::constant(NPOSE + NCAM + 3, pose.clone()), + prev_to_token: HostLinear::constant(NPOSE + NCAM, previous.clone()), + prompt_to_token: HostLinear::constant(DINO_DIM, prompt.clone()), + invalid_point_embed: vec![0.0; DINO_DIM], + hand_box_embedding: hand.clone(), + keypoint_embedding: keypoint.clone(), + keypoint3d_embedding: keypoint3d.clone(), + }; + let tokens = build_tokens( + &weights, + &vec![0.0; NPOSE], + &vec![0.0; NCAM], + [0.0; 3], + ); + assert_eq!(&tokens.tokens[..DEC_DIM], pose); + assert_eq!(&tokens.tokens[DEC_DIM..2 * DEC_DIM], previous); + assert_eq!(&tokens.tokens[2 * DEC_DIM..3 * DEC_DIM], prompt); + assert_eq!(&tokens.tokens[3 * DEC_DIM..5 * DEC_DIM], hand); + assert_eq!( + &tokens.tokens[KEYPOINT_ROW * DEC_DIM..KEYPOINT3D_ROW * DEC_DIM], + keypoint, + ); + assert_eq!(&tokens.tokens[KEYPOINT3D_ROW * DEC_DIM..], keypoint3d); + assert_eq!( + &tokens.token_augment[DEC_DIM..2 * DEC_DIM], + previous, + ); + assert_eq!(&tokens.token_augment[2 * DEC_DIM..3 * DEC_DIM], prompt); + assert!(tokens.token_augment[..DEC_DIM].iter().all(|&x| x == 0.0)); + assert!(tokens.token_augment[3 * DEC_DIM..] + .iter() + .all(|&x| x == 0.0)); + } + + #[test] + fn bilinear_sampling_matches_centers_and_padding() { + let grid = vec![1.0, 10.0, 2.0, 20.0, 3.0, 30.0, 4.0, 40.0]; + for y in 0..2 { + for x in 0..2 { + let nx = 2.0 * (x as f32 + 0.5) / 2.0 - 1.0; + let ny = 2.0 * (y as f32 + 0.5) / 2.0 - 1.0; + let sampled = bilinear_sample(&grid, 2, 2, 2, nx, ny); + let offset = (y * 2 + x) * 2; + assert_eq!(sampled, grid[offset..offset + 2]); + } + } + assert_eq!(bilinear_sample(&grid, 2, 2, 2, 2.0, 2.0), [0.0, 0.0]); + } + + #[test] + fn first_layer_skips_token_pe_for_self_attention() { + let normed = [1.0, 2.0, 3.0, 4.0]; + let pe = [10.0, 20.0, 30.0, 40.0]; + let layer0 = identity(&self_attention_qk_input(0, &normed, &pe)); + let layer1 = identity(&self_attention_qk_input(1, &normed, &pe)); + assert_eq!(layer0, normed); + assert_eq!(layer1, [11.0, 22.0, 33.0, 44.0]); + } + + #[test] + fn host_layer_norm_uses_biased_variance() { + let output = layer_norm_host( + &[1.0, 2.0, 3.0, 4.0], + 1, + 4, + &[1.0, 2.0, 3.0, 4.0], + &[0.5, 0.5, 0.5, 0.5], + 0.0, + ); + let inv_std = 1.0 / 1.25f32.sqrt(); + let expected = [ + -1.5 * inv_std + 0.5, + -0.5 * inv_std * 2.0 + 0.5, + 0.5 * inv_std * 3.0 + 0.5, + 1.5 * inv_std * 4.0 + 0.5, + ]; + for (actual, expected) in output.iter().zip(expected) { + assert!((actual - expected).abs() < 1e-6, "{actual} != {expected}"); + } + } + + fn planar_to_tokens(values: &[f32]) -> Vec { + assert_eq!(values.len(), DINO_DIM * NUM_PATCHES); + let mut output = vec![0.0f32; NUM_PATCHES * DINO_DIM]; + for channel in 0..DINO_DIM { + for token in 0..NUM_PATCHES { + output[token * DINO_DIM + channel] = values[channel * NUM_PATCHES + token]; + } + } + output + } + + fn fixture_values(name: &str) -> Vec { + fixture::load(name) + .unwrap_or_else(|| panic!("missing fixture {name}")) + .1 + } + + fn fixture_weights() -> Option { + let Some(path) = fixture::weights_path() else { + eprintln!("skipping body decoder fixture: weights_path.txt is absent"); + return None; + }; + Some(BodyWeights::load(&path).unwrap_or_else(|error| { + panic!("failed to load fixture weights {}: {error}", path.display()) + })) + } + + fn assert_close(name: &str, actual: &[f32], expected: &[f32], tolerance: f32) { + assert_eq!( + actual.len(), + expected.len(), + "{name} length {} != {}", + actual.len(), + expected.len(), + ); + let (index, max) = actual + .iter() + .zip(expected) + .enumerate() + .map(|(index, (actual, expected))| (index, (actual - expected).abs())) + .max_by(|a, b| a.1.total_cmp(&b.1)) + .unwrap_or((0, 0.0)); + eprintln!("body decoder parity {name}: max abs {max:.6}"); + assert!( + max <= tolerance, + "{name} max abs {max} at {index}: actual={} expected={} tolerance={tolerance}", + actual.get(index).copied().unwrap_or(0.0), + expected.get(index).copied().unwrap_or(0.0), + ); + } + + // GPU matmul/attention accumulation order differs from the reference's; + // the residual stream is O(10) wide, the heads O(1). + const TOKEN_TOLERANCE: f32 = 5e-2; + const HEAD_TOLERANCE: f32 = 2e-2; + + #[test] + fn fixture_token_assembly() { + if fixture::oracle_dir().is_none() { + eprintln!("skipping body decoder fixture: oracle directory is absent"); + return; + } + let Some(weights) = fixture_weights() else { + return; + }; + let weights = DecoderWeights::load(&weights).expect("load decoder weights"); + let condition = fixture_values("condition_info"); + assert_eq!(condition.len(), 3); + let tokens = weights.build_tokens([condition[0], condition[1], condition[2]]); + assert_close( + "decoder_tokens_in", + &tokens.tokens, + &fixture_values("decoder_tokens_in"), + 1e-4, + ); + assert_close( + "decoder_token_augment_in", + &tokens.token_augment, + &fixture_values("decoder_token_augment_in"), + 1e-4, + ); + } + + #[test] + fn fixture_host_heads_and_refinement_ffns() { + if fixture::oracle_dir().is_none() { + eprintln!("skipping body head fixture: oracle directory is absent"); + return; + } + let Some(weights) = fixture_weights() else { + return; + }; + let heads = DecoderHeads::load(&weights).expect("load decoder heads"); + assert_close( + "head_pose_proj_out_0", + &heads.pose(&fixture_values("head_pose_proj_in_0")), + &fixture_values("head_pose_proj_out_0"), + 1e-4, + ); + assert_close( + "head_camera_proj_out_0", + &heads.camera(&fixture_values("head_camera_proj_in_0")), + &fixture_values("head_camera_proj_out_0"), + 1e-4, + ); + assert_close( + "kp_posemb_out_0", + &heads.keypoint_posemb(&fixture_values("kp_posemb_in_0")), + &fixture_values("kp_posemb_out_0"), + 1e-4, + ); + assert_close( + "kp3d_posemb_out_0", + &heads.keypoint3d_posemb(&fixture_values("kp3d_posemb_in_0")), + &fixture_values("kp3d_posemb_out_0"), + 1e-4, + ); + let expected_features = fixture_values("kp_feat_out_0"); + let mut actual_features = heads.keypoint_features(&fixture_values("kp_feat_in_0")); + for (actual, expected) in actual_features + .chunks_exact_mut(DEC_DIM) + .zip(expected_features.chunks_exact(DEC_DIM)) + { + if expected.iter().all(|&value| value == 0.0) { + actual.fill(0.0); + } + } + assert_close( + "kp_feat_out_0", + &actual_features, + &expected_features, + 1e-4, + ); + } + + #[test] + fn fixture_gpu_decoder_layers() { + if fixture::oracle_dir().is_none() { + eprintln!("skipping body decoder GPU fixture: oracle directory is absent"); + return; + } + if !gpu_device_available() { + eprintln!("skipping body decoder GPU fixture: GPU device is absent"); + return; + } + let Some(weights) = fixture_weights() else { + return; + }; + let decoder = Decoder::load(&weights).expect("load GPU decoder"); + // The oracle captured the context and its PE channel-first + // ([1280, 32, 32]); the decoder takes them as token rows. + let context_values = planar_to_tokens(&fixture_values("decoder_image_in")); + let context = gpu_upload(&context_values, NUM_PATCHES, DINO_DIM) + .expect("upload decoder fixture context"); + let context_pe = planar_to_tokens(&fixture_values("decoder_image_augment_in")); + let token_set = TokenSet { + tokens: fixture_values("decoder_tokens_in"), + token_augment: fixture_values("decoder_token_augment_in"), + }; + let mut trace = |layer: usize, hidden: &GpuTensor, normed: &[f32]| -> Result<()> { + let hidden = gpu_download(hidden).map_err(DiffusionError::model)?; + assert_close( + &format!("dec{layer}_tokens_out"), + &hidden, + &fixture_values(&format!("dec{layer}_tokens_out")), + TOKEN_TOLERANCE, + ); + assert_close( + &format!("norm_final_out_{layer}"), + normed, + &fixture_values(&format!("norm_final_out_{layer}")), + HEAD_TOLERANCE, + ); + Ok(()) + }; + let step = |input: StepInput| -> StepFeedback { + let layer = input.layer; + assert_close( + &format!("head_pose_proj_in_{layer}"), + &input.tokens_normed_row0, + &fixture_values(&format!("head_pose_proj_in_{layer}")), + HEAD_TOLERANCE, + ); + let pose_raw: Vec = input + .pose_pred_519 + .iter() + .zip(&decoder.init_pose) + .map(|(value, offset)| value - offset) + .collect(); + assert_close( + &format!("head_pose_proj_out_{layer}"), + &pose_raw, + &fixture_values(&format!("head_pose_proj_out_{layer}")), + HEAD_TOLERANCE, + ); + let camera_raw: Vec = input + .cam_pred_3 + .iter() + .zip(&decoder.init_camera) + .map(|(value, offset)| value - offset) + .collect(); + assert_close( + &format!("head_camera_proj_out_{layer}"), + &camera_raw, + &fixture_values(&format!("head_camera_proj_out_{layer}")), + HEAD_TOLERANCE, + ); + if layer + 1 == DEC_DEPTH { + return StepFeedback::default(); + } + let kp2d = fixture_values(&format!("kp_posemb_in_{layer}")); + let kp3d = fixture_values(&format!("kp3d_posemb_in_{layer}")); + let feature_output = fixture_values(&format!("kp_feat_out_{layer}")); + let depth = feature_output + .chunks_exact(DEC_DIM) + .map(|row| { + if row.iter().all(|&value| value == 0.0) { + 0.0 + } else { + 1.0 + } + }) + .collect(); + StepFeedback { + kp2d_cropped: kp2d, + depth, + kp3d, + } + }; + let output = decoder + .run_impl(token_set, &context, &context_pe, step, Some(&mut trace)) + .expect("run decoder fixture"); + assert_close( + "norm_final_out_5", + &output.tokens_normed, + &fixture_values("norm_final_out_5"), + HEAD_TOLERANCE, + ); + } +} diff --git a/libs/ai/models/body/src/heads.rs b/libs/ai/models/body/src/heads.rs new file mode 100644 index 000000000..f343f75ec --- /dev/null +++ b/libs/ai/models/body/src/heads.rs @@ -0,0 +1,215 @@ +//! Host-side decoder heads and refinement embeddings. + +use crate::weights::BodyWeights; +use crate::{DEC_DIM, DINO_DIM, NCAM, NPOSE, Result}; + +#[derive(Clone)] +pub(crate) struct HostLinear { + weight: Vec, + bias: Vec, + input: usize, + output: usize, +} + +impl HostLinear { + pub(crate) fn load( + weights: &BodyWeights, + name: &str, + output: usize, + input: usize, + ) -> Result { + Ok(Self { + weight: weights.f32_shaped(&format!("{name}.weight"), &[output, input])?, + bias: weights.f32_shaped(&format!("{name}.bias"), &[output])?, + input, + output, + }) + } + + pub(crate) fn forward_row(&self, input: &[f32]) -> Vec { + debug_assert_eq!(input.len(), self.input); + let mut output = self.bias.clone(); + for (row, value) in self.weight.chunks_exact(self.input).zip(&mut output) { + let mut sum = *value; + for (&x, &w) in input.iter().zip(row) { + sum += x * w; + } + *value = sum; + } + output + } + + pub(crate) fn forward_rows(&self, input: &[f32]) -> Vec { + debug_assert_eq!(input.len() % self.input, 0); + let rows = input.len() / self.input; + let mut output = Vec::with_capacity(rows * self.output); + for row in input.chunks_exact(self.input) { + output.extend(self.forward_row(row)); + } + output + } + + pub(crate) fn into_parts(self) -> (Vec, Vec, usize, usize) { + (self.weight, self.bias, self.output, self.input) + } + + #[cfg(test)] + pub(crate) fn constant(input: usize, bias: Vec) -> Self { + let output = bias.len(); + Self { + weight: vec![0.0; input * output], + bias, + input, + output, + } + } +} + +#[derive(Clone)] +pub(crate) struct ReluFfn { + first: HostLinear, + second: HostLinear, +} + +impl ReluFfn { + pub(crate) fn load( + weights: &BodyWeights, + prefix: &str, + input: usize, + hidden: usize, + output: usize, + ) -> Result { + Ok(Self { + first: HostLinear::load( + weights, + &format!("{prefix}.layers.0.0"), + hidden, + input, + )?, + second: HostLinear::load(weights, &format!("{prefix}.layers.1"), output, hidden)?, + }) + } + + pub(crate) fn forward_row(&self, input: &[f32]) -> Vec { + let mut hidden = self.first.forward_row(input); + relu_in_place(&mut hidden); + self.second.forward_row(&hidden) + } + + pub(crate) fn forward_rows(&self, input: &[f32]) -> Vec { + debug_assert_eq!(input.len() % self.first.input, 0); + let rows = input.len() / self.first.input; + let mut output = Vec::with_capacity(rows * self.second.output); + for row in input.chunks_exact(self.first.input) { + output.extend(self.forward_row(row)); + } + output + } +} + +#[derive(Clone)] +pub(crate) struct BboxMlp { + first: HostLinear, + second: HostLinear, + third: HostLinear, +} + +impl BboxMlp { + fn load(weights: &BodyWeights) -> Result { + Ok(Self { + first: HostLinear::load(weights, "bbox_embed.layers.0", DEC_DIM, DEC_DIM)?, + second: HostLinear::load(weights, "bbox_embed.layers.1", DEC_DIM, DEC_DIM)?, + third: HostLinear::load(weights, "bbox_embed.layers.2", 4, DEC_DIM)?, + }) + } + + fn forward(&self, input: &[f32]) -> [f32; 4] { + let mut hidden = self.first.forward_row(input); + relu_in_place(&mut hidden); + let mut hidden = self.second.forward_row(&hidden); + relu_in_place(&mut hidden); + let output = self.third.forward_row(&hidden); + std::array::from_fn(|i| sigmoid(output[i])) + } +} + +#[derive(Clone)] +pub(crate) struct DecoderHeads { + pose: ReluFfn, + camera: ReluFfn, + keypoint_posemb: ReluFfn, + keypoint3d_posemb: ReluFfn, + keypoint_feat: HostLinear, + bbox: BboxMlp, + hand_cls: HostLinear, +} + +impl DecoderHeads { + pub(crate) fn load(weights: &BodyWeights) -> Result { + Ok(Self { + pose: ReluFfn::load(weights, "head_pose.proj", DEC_DIM, DEC_DIM, NPOSE)?, + camera: ReluFfn::load(weights, "head_camera.proj", DEC_DIM, DEC_DIM, NCAM)?, + keypoint_posemb: ReluFfn::load( + weights, + "keypoint_posemb_linear", + 2, + DEC_DIM, + DEC_DIM, + )?, + keypoint3d_posemb: ReluFfn::load( + weights, + "keypoint3d_posemb_linear", + 3, + DEC_DIM, + DEC_DIM, + )?, + keypoint_feat: HostLinear::load( + weights, + "keypoint_feat_linear", + DEC_DIM, + DINO_DIM, + )?, + bbox: BboxMlp::load(weights)?, + hand_cls: HostLinear::load(weights, "hand_cls_embed", 2, DEC_DIM)?, + }) + } + + pub(crate) fn pose(&self, input: &[f32]) -> Vec { + self.pose.forward_row(input) + } + + pub(crate) fn camera(&self, input: &[f32]) -> Vec { + self.camera.forward_row(input) + } + + pub(crate) fn keypoint_posemb(&self, input: &[f32]) -> Vec { + self.keypoint_posemb.forward_rows(input) + } + + pub(crate) fn keypoint3d_posemb(&self, input: &[f32]) -> Vec { + self.keypoint3d_posemb.forward_rows(input) + } + + pub(crate) fn keypoint_features(&self, input: &[f32]) -> Vec { + self.keypoint_feat.forward_rows(input) + } + + pub(crate) fn bbox(&self, input: &[f32]) -> [f32; 4] { + self.bbox.forward(input) + } + + pub(crate) fn hand_logits(&self, input: &[f32]) -> [f32; 2] { + let output = self.hand_cls.forward_row(input); + [output[0], output[1]] + } +} + +fn relu_in_place(values: &mut [f32]) { + for value in values { + *value = value.max(0.0); + } +} + +fn sigmoid(value: f32) -> f32 { + 1.0 / (1.0 + (-value).exp()) +} diff --git a/libs/ai/models/body/src/lib.rs b/libs/ai/models/body/src/lib.rs index d54ea0355..4342b16c0 100644 --- a/libs/ai/models/body/src/lib.rs +++ b/libs/ai/models/body/src/lib.rs @@ -26,7 +26,9 @@ pub use makepad_ai_common::error; pub use makepad_ai_common::{emit_progress, DiffusionError, ProgressHook, Result}; pub mod condition; +pub mod decoder; pub mod dino; +mod heads; pub mod mhr; pub mod pose; pub mod preprocess; From 66e5e2f1177e4267a8d97081761be8e9e6ff98bd Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 23:01:49 +0200 Subject: [PATCH 020/417] =?UTF-8?q?ai-hub:=20SAM=203D=20Body=20runs=20nati?= =?UTF-8?q?vely=20=E2=80=94=20`sam3dbody`=20on=20the=20body=20domain,=20or?= =?UTF-8?q?acle-matched=20end=20to=20end?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit model.rs closes the loop: crop -> backbone -> ray-conditioned context -> six decoder steps, each through the pose head, the rig, the camera and the projection, then the packet the sandbox already reads (kp3d/kp2d in camera axes, the 204 rig parameters, global rotation, camera translation, joint positions). Against the reference on the oracle image, on Metal: 3D keypoints within 1.7 mm, 2D within 0.4 px, rig parameters, camera and rotation within 2e-3. packet.rs writes the JSON by hand with the reference worker's rounding and field order. The hub gains the `body-native` feature (default on): registry entry `sam3dbody` pinned to the Comfy-Org repack by revision, size and sha, body_native_backend.rs beside the subprocess reference backend with the same live_step contract, the `body` capability advertised when the feature is compiled, and a stubbed test double for the CPU-only tests. Co-Authored-By: Claude Fable 5.1 --- apps/ai-hub/Cargo.toml | 3 +- libs/ai/hub/Cargo.toml | 24 +- libs/ai/hub/registry.json | 52 ++++ libs/ai/hub/src/backend.rs | 28 +- libs/ai/hub/src/body_native_backend.rs | 386 +++++++++++++++++++++++++ libs/ai/hub/src/lib.rs | 5 + libs/ai/hub/src/registry.rs | 36 ++- libs/ai/models/body/src/lib.rs | 2 + libs/ai/models/body/src/model.rs | 267 +++++++++++++++++ libs/ai/models/body/src/packet.rs | 134 +++++++++ 10 files changed, 930 insertions(+), 7 deletions(-) create mode 100644 libs/ai/hub/src/body_native_backend.rs create mode 100644 libs/ai/models/body/src/model.rs create mode 100644 libs/ai/models/body/src/packet.rs diff --git a/apps/ai-hub/Cargo.toml b/apps/ai-hub/Cargo.toml index 0ecb86897..264af2b46 100644 --- a/apps/ai-hub/Cargo.toml +++ b/apps/ai-hub/Cargo.toml @@ -14,7 +14,7 @@ makepad-ai-hub = { path = "../../libs/ai/hub", default-features = false } # Feature passthrough: the headless node exposes exactly the library's # feature set, so box launch scripts keep their --features flags working. [features] -default = ["flux", "paint", "paint-cuda", "llm", "tts", "indextts", "video", "interpolate", "audio", "mesh", "matte-native", "depth-native", "segment-native", "upscale-native", "motion-native", "rig-native", "splat-native"] +default = ["flux", "paint", "paint-cuda", "llm", "tts", "indextts", "video", "interpolate", "audio", "mesh", "matte-native", "depth-native", "segment-native", "body-native", "upscale-native", "motion-native", "rig-native", "splat-native"] python-backends = ["makepad-ai-hub/python-backends"] flux = ["makepad-ai-hub/flux"] paint = ["makepad-ai-hub/paint"] @@ -29,6 +29,7 @@ mesh = ["makepad-ai-hub/mesh"] matte-native = ["makepad-ai-hub/matte-native"] depth-native = ["makepad-ai-hub/depth-native"] segment-native = ["makepad-ai-hub/segment-native"] +body-native = ["makepad-ai-hub/body-native"] upscale-native = ["makepad-ai-hub/upscale-native"] motion-native = ["makepad-ai-hub/motion-native"] splat-native = ["makepad-ai-hub/splat-native"] diff --git a/libs/ai/hub/Cargo.toml b/libs/ai/hub/Cargo.toml index 962ffe022..ce9c69072 100644 --- a/libs/ai/hub/Cargo.toml +++ b/libs/ai/hub/Cargo.toml @@ -20,6 +20,8 @@ default = [ "llm", "tts", "indextts", + "speech", + "stt", "video", "interpolate", "audio", @@ -27,6 +29,7 @@ default = [ "matte-native", "depth-native", "segment-native", + "body-native", "upscale-native", "motion-native", "rig-native", @@ -48,10 +51,15 @@ paint = ["dep:makepad-ai-paint", "dep:makepad-gltf", "dep:makepad-remesh", "dep: paint-cuda = ["paint", "makepad-ai-paint/cuda-taps"] # Real LLM prompt expansion via makepad-ai-llm (Qwen3.5/3.6 GGUF). llm = ["dep:makepad-ai-llm"] +# Speech sessions (AiHub::start_stt / start_tts): the OS engines as the +# stt.system / tts.system pipes plus the in-process / machine / LAN ladder. +speech = ["dep:makepad-system-speech"] +# Whisper speech-to-text (stt.whisper), in-process and on the wire. +stt = ["speech", "dep:makepad-ai-speech", "makepad-ai-speech/whisper"] # Real Kokoro speech synthesis via makepad-ai-speech. -tts = ["dep:makepad-ai-speech"] +tts = ["dep:makepad-ai-speech", "makepad-ai-speech/kokoro"] # Real IndexTTS-2.5 character-voice TTS via makepad-ai-speech. -indextts = ["dep:makepad-ai-speech", "dep:makepad-ai-common"] +indextts = ["dep:makepad-ai-speech", "makepad-ai-speech/indextts", "dep:makepad-ai-common"] # Real MiniMax H3 video generation via makepad-ai-h3 plus the hardware # video file encoder (makepad-video). Does NOT pull the UI platform crate. video = ["dep:makepad-ai-h3", "dep:makepad-ai-common", "dep:makepad-video"] @@ -73,6 +81,8 @@ matte-native = ["dep:makepad-ai-vision", "dep:makepad-ai-common"] depth-native = ["dep:makepad-ai-vision", "dep:makepad-ai-common"] # Native SAM 3.1 multiplex segmentation. Independent of `mesh`. segment-native = ["dep:makepad-ai-vision", "dep:makepad-ai-common"] +# Native SAM 3D Body pose estimation. +body-native = ["dep:makepad-ai-body", "dep:makepad-ai-common"] # Native RealESRGAN x4plus general-image upscaling. Independent of `mesh`. upscale-native = ["dep:makepad-ai-vision", "dep:makepad-ai-common"] # Native HY-Motion decode -> rig retarget -> animated GLB. @@ -107,6 +117,7 @@ makepad-ai-flux = { path = "../../ai/models/flux", optional = true } makepad-ai-h3 = { path = "../../ai/models/h3", optional = true } makepad-ai-rife = { path = "../../ai/models/rife", optional = true } makepad-ai-vision = { path = "../../ai/models/vision", optional = true } +makepad-ai-body = { path = "../models/body", optional = true } makepad-ai-rig = { path = "../../ai/models/rig", optional = true } makepad-ai-motion = { path = "../../ai/models/motion", optional = true } makepad-ai-sfx = { path = "../../ai/models/sfx", optional = true } @@ -119,7 +130,8 @@ makepad-gltf = { path = "../../gltf", optional = true } makepad-xatlas = { path = "../../xatlas", optional = true } makepad-render = { path = "../../render", optional = true } makepad-ai-llm = { path = "../../ai/llm", optional = true } -makepad-ai-speech = { path = "../../ai/models/speech", optional = true } +makepad-ai-speech = { path = "../../ai/models/speech", default-features = false, optional = true } +makepad-system-speech = { path = "../../system_speech", optional = true } makepad-video = { path = "../../../platform/video", optional = true } # The `mkfl` motion payload: ONE definition, shared with the VJ's import # converter (which fills the same box from a classical, model-free flow @@ -165,3 +177,9 @@ path = "src/bin/context_ladder.rs" [[bin]] name = "ocr-bench" path = "src/bin/ocr_bench.rs" + +# TTS -> STT through the hub's own speech sessions, scored as word error rate: +# the scoreboard for comparing engines and the end-to-end check of the ladder. +[[bin]] +name = "speech-roundtrip" +path = "src/bin/speech_roundtrip.rs" diff --git a/libs/ai/hub/registry.json b/libs/ai/hub/registry.json index deb1c88d9..cfe5cccd7 100644 --- a/libs/ai/hub/registry.json +++ b/libs/ai/hub/registry.json @@ -623,6 +623,32 @@ } ] }, + { + "id": "whisper-large-v3-turbo", + "domain": "stt", + "backend": "whisper", + "available": true, + "gated": false, + "license": { + "name": "MIT License", + "url": "https://huggingface.co/ggerganov/whisper.cpp", + "summary": "OpenAI Whisper large-v3-turbo weights in ggml format as distributed by ggerganov/whisper.cpp (MIT). Permissive use, including commercial.", + "restriction": "none" + }, + "vram_gb": 2.0, + "note": "Whisper large-v3-turbo speech-to-text via the in-repo pure-Rust port (makepad-ai-speech whisper module; Metal/CUDA/CPU). Request: input_b64 audio/wav (any rate/channels, downmixed + resampled to 16 kHz) + language. Output: one application/json TranscriptJson {text, segments[{start_ms,end_ms,text}]}. The wire side of the stt.whisper pipe; apps reach it through AiHub::start_stt.", + "files": [ + { + "repo": "ggerganov/whisper.cpp", + "path": "ggml-large-v3-turbo.bin", + "revision": "5359861c739e955e79d9a303bcbc70fb988958b1", + "cache_as": "stt/ggml-large-v3-turbo.bin", + "size": 1624555275, + "sha256": "1fc70f774d38eb169993ac391eea357ef47c88757ef72ee5943879b7e8e2bc69", + "local": false + } + ] + }, { "id": "kokoro", "domain": "speech", @@ -1741,6 +1767,32 @@ } ] }, + { + "id": "sam3dbody", + "domain": "body", + "backend": "body-native", + "available": true, + "gated": false, + "license": { + "name": "SAM License", + "url": "https://huggingface.co/Comfy-Org/sam-3d-body", + "summary": "SAM 3D Body is under the SAM License / Meta acceptable-use terms published with the checkpoint. Review the model card before production use. This stack never downloads facebook/* checkpoints.", + "restriction": "community" + }, + "vram_gb": 4.5, + "note": "SAM 3D Body (Comfy-Org/sam-3d-body, SAM License) RGB image -> application/json human pose packet. Native Rust inference; no Python, Torch, subprocess, or silent fallback. facebook/* checkpoints are never fetched. The checkpoint is pinned to an immutable revision, byte size, and SHA-256.", + "files": [ + { + "role": "native-body", + "repo": "Comfy-Org/sam-3d-body", + "path": "detection/sam_3d_body_dinov3_bf16.safetensors", + "revision": "60476aced0b8de0a0e82a318c79a85061cc97434", + "cache_as": "body/sam3dbody/sam_3d_body_dinov3_bf16.safetensors", + "size": 2830737652, + "sha256": "59fa45200c504c5b56625004d7d3385daf48c616613e88099e43bf83b3e249cf" + } + ] + }, { "id": "sam3dbody-ref", "domain": "body", diff --git a/libs/ai/hub/src/backend.rs b/libs/ai/hub/src/backend.rs index a710c782c..49d1b9fd9 100644 --- a/libs/ai/hub/src/backend.rs +++ b/libs/ai/hub/src/backend.rs @@ -93,6 +93,8 @@ pub struct GenerateParams { pub text: String, pub voice: String, pub speed: f32, + /// Speech language hint (`language` on the wire); "" = model default. + pub language: String, /// 8-slot emotion vector (indextts), validated to length 8 and clamped /// per-slot to [0, 1.2]; `None` = neutral. pub emotion: Option<[f32; 8]>, @@ -343,6 +345,7 @@ impl GenerateParams { text: request.text.clone().unwrap_or_default(), voice: request.voice.clone().unwrap_or_default(), + language: request.language.clone().unwrap_or_default(), speed: if speed.is_finite() && speed > 0.0 { speed.clamp(0.25, 4.0) as f32 } else { @@ -1567,6 +1570,7 @@ pub fn backend_compiled(name: &str) -> bool { "vision" => cfg!(feature = "llm"), "ocr" => cfg!(feature = "llm"), "kokoro" => cfg!(feature = "tts"), + "whisper" => cfg!(feature = "stt"), "indextts" => cfg!(feature = "indextts"), // The `fast` (FastH3) lane rides the H3 pipeline: same feature. "h3" | "fast" => cfg!(feature = "video"), @@ -1579,6 +1583,7 @@ pub fn backend_compiled(name: &str) -> bool { "matte-native" => cfg!(feature = "matte-native"), "depth-native" => cfg!(feature = "depth-native"), "segment-native" => cfg!(feature = "segment-native"), + "body-native" => cfg!(feature = "body-native"), "upscale-native" => cfg!(feature = "upscale-native"), "video-enhance" => { cfg!(feature = "upscale-native") @@ -1635,9 +1640,12 @@ pub fn backend_provisioned(name: &str) -> bool { // on macOS, CUDA on Windows/Linux, probed once and memoised. "vision" => crate::vision_backend::vision_provisioned(), "ocr" => crate::vision_backend::vision_provisioned(), - "body" => crate::body_backend::body_provisioned(), + "body" => { + crate::body_backend::body_provisioned() || cfg!(feature = "body-native") + } "depth-native" => cfg!(feature = "depth-native"), "segment-native" => cfg!(feature = "segment-native"), + "body-native" => cfg!(feature = "body-native"), "upscale-native" => cfg!(feature = "upscale-native"), "video-enhance" => { cfg!(feature = "upscale-native") @@ -1768,6 +1776,15 @@ pub fn create_backend(spec: &ModelSpec) -> Result, Asset &spec.id, ))), "body" => Ok(Box::new(crate::body_backend::BodyBackend::new(&spec.id))), + #[cfg(feature = "body-native")] + "body-native" => Ok(Box::new( + crate::body_native_backend::BodyNativeBackend::new_native(&spec.id), + )), + #[cfg(not(feature = "body-native"))] + "body-native" => Err(AssetAiError::Unavailable(format!( + "model {} needs a build with the 'body-native' cargo feature", + spec.id + ))), #[cfg(feature = "flux")] "flux" => Ok(Box::new(crate::flux_backend::FluxBackend::new(&spec.id))), #[cfg(not(feature = "flux"))] @@ -1817,6 +1834,15 @@ pub fn create_backend(spec: &ModelSpec) -> Result, Asset "model {} needs a build with the 'llm' cargo feature", spec.id ))), + #[cfg(feature = "stt")] + "whisper" => Ok(Box::new(crate::whisper_backend::WhisperBackend::new_whisper( + &spec.id, + ))), + #[cfg(not(feature = "stt"))] + "whisper" => Err(AssetAiError::Unavailable(format!( + "model {} needs a build with the 'stt' cargo feature", + spec.id + ))), #[cfg(feature = "tts")] "kokoro" => Ok(Box::new(crate::kokoro_backend::KokoroBackend::new_kokoro( &spec.id, diff --git a/libs/ai/hub/src/body_native_backend.rs b/libs/ai/hub/src/body_native_backend.rs new file mode 100644 index 000000000..e8ccfe9aa --- /dev/null +++ b/libs/ai/hub/src/body_native_backend.rs @@ -0,0 +1,386 @@ +//! Native SAM 3D Body backend: RGB image -> structured pose JSON. + +use crate::backend::{ + ArtifactData, BackendCtx, CancelToken, ContentBackend, GenerateParams, LiveFrameIn, + LiveFrameOut, ProgressSink, +}; +use crate::error::AssetAiError; +use crate::subproc_img::png_header; +#[cfg(feature = "body-native")] +use makepad_ai_body::model::BodyModel; +#[cfg(feature = "body-native")] +use makepad_ai_common::DiffusionError; +#[cfg(feature = "body-native")] +use std::path::PathBuf; +use std::time::Instant; + +/// Pluggable inference for CPU-only backend tests. +pub type BodyFn = Box< + dyn FnMut(&[u8], u32, u32, Option<[f32; 4]>) -> Result + Send, +>; + +enum Gen { + Stub(BodyFn), + #[cfg(feature = "body-native")] + Native, +} + +pub struct BodyNativeBackend { + model_id: String, + gen: Gen, + #[cfg(feature = "body-native")] + model_path: Option, + #[cfg(feature = "body-native")] + model: Option, +} + +impl BodyNativeBackend { + pub fn with_stub(model_id: &str, gen: BodyFn) -> Self { + Self { + model_id: model_id.to_string(), + gen: Gen::Stub(gen), + #[cfg(feature = "body-native")] + model_path: None, + #[cfg(feature = "body-native")] + model: None, + } + } + + #[cfg(feature = "body-native")] + pub fn new_native(model_id: &str) -> Self { + Self { + model_id: model_id.to_string(), + gen: Gen::Native, + model_path: None, + model: None, + } + } + + fn infer_rgb( + &mut self, + rgb: &[u8], + width: u32, + height: u32, + bbox: Option<[f32; 4]>, + ) -> Result { + let packet = match &mut self.gen { + Gen::Stub(gen) => gen(rgb, width, height, bbox)?, + #[cfg(feature = "body-native")] + Gen::Native => { + let model = self.model.as_mut().ok_or_else(|| { + AssetAiError::Backend( + "native body used before ensure_loaded".to_string(), + ) + })?; + let start = Instant::now(); + let mut packet = model + .infer(rgb, width, height, bbox) + .map_err(diffusion_err)?; + packet.ms = start.elapsed().as_secs_f32() * 1000.0; + packet.to_json() + } + }; + crate::body_backend::validate_pose_packet(&packet)?; + Ok(packet) + } +} + +#[cfg(feature = "body-native")] +fn diffusion_err(err: DiffusionError) -> AssetAiError { + match err { + DiffusionError::Cancelled => AssetAiError::Cancelled, + other => AssetAiError::Backend(format!("body: {other}")), + } +} + +impl ContentBackend for BodyNativeBackend { + fn model_id(&self) -> &str { + &self.model_id + } + + fn ensure_loaded(&mut self, ctx: &mut BackendCtx) -> Result<(), AssetAiError> { + ctx.ensure_files()?; + match &self.gen { + Gen::Stub(_) => Ok(()), + #[cfg(feature = "body-native")] + Gen::Native => { + let path = ctx.path_by_role("native-body")?; + if self.model.is_some() && self.model_path.as_ref() == Some(&path) { + return Ok(()); + } + self.model = None; + let model = BodyModel::load(&path).map_err(diffusion_err)?; + self.model_path = Some(path); + self.model = Some(model); + Ok(()) + } + } + } + + fn is_resident(&self) -> bool { + #[cfg(feature = "body-native")] + { + return self.model.is_some(); + } + #[cfg(not(feature = "body-native"))] + false + } + + fn unload(&mut self) -> Result<(), AssetAiError> { + #[cfg(feature = "body-native")] + { + self.model = None; + self.model_path = None; + } + Ok(()) + } + + fn generate( + &mut self, + params: &GenerateParams, + progress: ProgressSink, + cancel: &CancelToken, + ) -> Result, AssetAiError> { + if params.input_bytes.is_empty() { + return Err(AssetAiError::Params(format!( + "{} needs an input image (input_b64 png)", + self.model_id + ))); + } + if png_header(¶ms.input_bytes).is_none() { + return Err(AssetAiError::Params( + "sam3dbody input_b64 is not a png".to_string(), + )); + } + cancel.check()?; + progress("body: infer", 0.05); + let (rgb, width, height) = crate::testpattern::decode_png_rgb8(¶ms.input_bytes)?; + let packet = self.infer_rgb(&rgb, width, height, None)?; + cancel.check()?; + progress("done", 1.0); + Ok(vec![ArtifactData { + content_type: "application/json", + ext: "json", + bytes: packet.into_bytes(), + }]) + } + + fn live_supported(&self) -> bool { + true + } + + fn live_step( + &mut self, + frame: LiveFrameIn<'_>, + cancel: &CancelToken, + ) -> Result { + cancel.check()?; + let start = Instant::now(); + let init = frame.init.ok_or_else(|| { + AssetAiError::Params("sam3dbody live step requires an input frame".to_string()) + })?; + let packet = self.infer_rgb(&init.data, init.width, init.height, None)?; + cancel.check()?; + Ok(LiveFrameOut { + image: init.clone(), + aux_json: Some(packet), + model_ms: start.elapsed().as_secs_f64() * 1000.0, + text_encode_ms: 0.0, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::backend::{LiveConfig, RgbImage}; + use crate::protocol::GenerateRequestJson; + + fn params(request: GenerateRequestJson) -> GenerateParams { + GenerateParams::from_request(&request).unwrap() + } + + fn b64(bytes: &[u8]) -> String { + String::from_utf8(makepad_base64::base64_encode( + bytes, + &makepad_base64::BASE64_STANDARD, + )) + .unwrap() + } + + fn input_png() -> Vec { + crate::testpattern::encode_png_rgb8(&vec![128u8; 8 * 4 * 3], 8, 4).unwrap() + } + + #[test] + fn reports_live_support_and_echoes_the_frame() { + let packet = r#"{"n_people":0,"people":[],"ms":0.0}"#.to_string(); + let mut backend = BodyNativeBackend::with_stub( + "sam3dbody", + Box::new(move |rgb, width, height, bbox| { + assert_eq!((width, height), (3, 2)); + assert_eq!(rgb, &[17u8; 18]); + assert_eq!(bbox, None); + Ok(packet.clone()) + }), + ); + assert!(backend.live_supported()); + let init = RgbImage { + width: 3, + height: 2, + data: vec![17u8; 18], + }; + let config = LiveConfig::default(); + let out = backend + .live_step( + LiveFrameIn { + init: Some(&init), + anchor: None, + frame_index: 0, + config: &config, + }, + &CancelToken::new(), + ) + .unwrap(); + assert_eq!(out.image, init); + assert_eq!( + out.aux_json.as_deref(), + Some(r#"{"n_people":0,"people":[],"ms":0.0}"#) + ); + } + + #[cfg(feature = "body-native")] + #[test] + fn packet_round_trips_through_generate_and_strict_json() { + use makepad_ai_body::packet::{BodyPacket, BodyPerson}; + use makepad_strict_json::Value; + + let mut mhr = [0.0; 204]; + mhr[0] = 1.23456; + let packet = BodyPacket { + people: vec![BodyPerson { + mhr, + global_rot: [0.1, 0.2, 0.3], + cam_t: [1.0, 2.0, 3.0], + shape: [0.0; 45], + expr: [0.0; 72], + focal: 900.12345, + bbox: [0.0, 0.0, 8.0, 4.0], + kp3d: vec![0.0; 70 * 3], + kp2d: vec![0.0; 70 * 2], + joints: None, + rots: None, + }], + ms: 4.56789, + }; + let expected = packet.to_json(); + let mut backend = BodyNativeBackend::with_stub( + "sam3dbody", + Box::new(move |rgb, width, height, bbox| { + assert_eq!((width, height), (8, 4)); + assert_eq!(rgb.len(), 8 * 4 * 3); + assert_eq!(bbox, None); + Ok(expected.clone()) + }), + ); + let request = GenerateRequestJson { + model: "sam3dbody".to_string(), + input_b64: Some(b64(&input_png())), + ..GenerateRequestJson::default() + }; + let mut sink = |_: &str, _: f64| {}; + let artifacts = backend + .generate(¶ms(request), &mut sink, &CancelToken::new()) + .unwrap(); + assert_eq!(artifacts.len(), 1); + assert_eq!(artifacts[0].content_type, "application/json"); + let json = std::str::from_utf8(&artifacts[0].bytes).unwrap(); + let Value::Obj(root) = makepad_strict_json::parse(json.as_bytes()).unwrap() else { + panic!("body packet root is not an object"); + }; + assert_eq!( + root.iter().map(|(key, _)| key.as_str()).collect::>(), + ["n_people", "people", "ms"] + ); + assert_eq!(root[0].1.as_u64(), Some(1)); + let people = root[1].1.as_arr().unwrap(); + let Value::Obj(person) = &people[0] else { + panic!("body person is not an object"); + }; + assert_eq!( + person.iter().map(|(key, _)| key.as_str()).collect::>(), + [ + "mhr", + "global_rot", + "cam_t", + "shape", + "expr", + "focal", + "bbox", + "kp3d", + "kp2d", + ] + ); + assert_eq!(person[0].1.as_arr().unwrap()[0], Value::F64(1.2346)); + } + + #[cfg(feature = "body-native")] + #[test] + fn missing_native_model_artifact_is_a_clean_error() { + use crate::backend::BackendCtx; + use crate::download::Downloader; + use crate::registry::{Domain, FileSpec, ModelSpec}; + + let nonce = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_nanos(); + let cache_dir = std::env::current_dir().unwrap().join(format!( + "target/body-native-missing-test-{}-{nonce}", + std::process::id() + )); + let spec = ModelSpec { + id: "sam3dbody".to_string(), + domain: Domain::Body, + backend: "body-native".to_string(), + available: true, + gated: false, + vram_gb: Some(4.5), + min_vram_gb: None, + min_compute_cap: None, + note: None, + license: None, + files: vec![FileSpec { + role: Some("native-body".to_string()), + repo: String::new(), + path: String::new(), + revision: None, + cache_as: "body/sam3dbody/missing.safetensors".to_string(), + size: None, + sha256: None, + local: true, + optional: true, + converts_to: None, + conversion: None, + }], + }; + let downloader = Downloader::new("http://127.0.0.1:1", None).unwrap(); + let cancel = CancelToken::new(); + let mut download_progress = |_| {}; + let mut progress = |_: &str, _: f64| {}; + let mut ctx = BackendCtx { + spec: &spec, + cache_dir: &cache_dir, + downloader: &downloader, + download_progress: &mut download_progress, + cancel: &cancel, + progress: &mut progress, + }; + let mut backend = BodyNativeBackend::new_native("sam3dbody"); + let err = backend + .ensure_loaded(&mut ctx) + .expect_err("missing body model must fail"); + assert!(matches!(err, AssetAiError::Backend(_)), "{err:?}"); + let _ = std::fs::remove_dir_all(&cache_dir); + } +} diff --git a/libs/ai/hub/src/lib.rs b/libs/ai/hub/src/lib.rs index 03f4a0ce6..c80f84adf 100644 --- a/libs/ai/hub/src/lib.rs +++ b/libs/ai/hub/src/lib.rs @@ -33,6 +33,7 @@ pub mod backend; pub mod body_backend; +pub mod body_native_backend; pub mod chat_wire; pub use makepad_base64; pub mod client; @@ -57,6 +58,10 @@ pub mod lane_advert; pub mod lease; pub mod indextts_backend; pub mod kokoro_backend; +#[cfg(feature = "stt")] +pub mod whisper_backend; +#[cfg(feature = "speech")] +pub mod speech; pub mod llm_backend; #[cfg(feature = "llm")] pub mod local_llm; diff --git a/libs/ai/hub/src/registry.rs b/libs/ai/hub/src/registry.rs index 18ae62cf1..4896cb035 100644 --- a/libs/ai/hub/src/registry.rs +++ b/libs/ai/hub/src/registry.rs @@ -195,6 +195,9 @@ pub enum Domain { Vision, /// Scanned page -> HTML transcription (Chandra 2 on the vision tower). Ocr, + /// Speech audio -> timed transcript (Whisper). The `stt.whisper` pipe; + /// `Speech` stays text-to-speech, so the two never share affinity. + Stt, } impl Domain { @@ -223,6 +226,7 @@ impl Domain { "splat" => Some(Domain::Splat), "vision" => Some(Domain::Vision), "ocr" => Some(Domain::Ocr), + "stt" => Some(Domain::Stt), _ => None, } } @@ -252,6 +256,7 @@ impl Domain { Domain::Splat => "splat", Domain::Vision => "vision", Domain::Ocr => "ocr", + Domain::Stt => "stt", } } } @@ -1492,8 +1497,35 @@ mod tests { // The licensing guard lives in the note: the x.1 refreshes are NC. assert!(depth.note.as_deref().unwrap().contains("Apache-2.0")); - // Body domain: externally provisioned persistent worker, no hub-side - // model artifact download. + // Body domain: pinned native artifact and externally provisioned + // reference worker. + let native_body = registry.find("sam3dbody").unwrap(); + assert_eq!(native_body.domain, Domain::Body); + assert_eq!(native_body.backend, "body-native"); + assert!(native_body.available && !native_body.gated); + assert_eq!(native_body.vram_gb, Some(4.5)); + assert_eq!(native_body.files.len(), 1); + let body_weights = native_body.file_by_role("native-body").unwrap(); + assert_eq!(body_weights.repo, "Comfy-Org/sam-3d-body"); + assert_eq!( + body_weights.path, + "detection/sam_3d_body_dinov3_bf16.safetensors" + ); + assert_eq!( + body_weights.revision.as_deref(), + Some("60476aced0b8de0a0e82a318c79a85061cc97434") + ); + assert_eq!(body_weights.size, Some(2_830_737_652)); + assert_eq!( + body_weights.sha256.as_deref(), + Some("59fa45200c504c5b56625004d7d3385daf48c616613e88099e43bf83b3e249cf") + ); + assert_eq!( + body_weights.cache_as, + "body/sam3dbody/sam_3d_body_dinov3_bf16.safetensors" + ); + assert!(!body_weights.repo.starts_with("facebook/")); + let body = registry.find("sam3dbody-ref").unwrap(); assert_eq!(body.domain, Domain::Body); assert_eq!(body.backend, "body"); diff --git a/libs/ai/models/body/src/lib.rs b/libs/ai/models/body/src/lib.rs index 4342b16c0..1dc90f5cf 100644 --- a/libs/ai/models/body/src/lib.rs +++ b/libs/ai/models/body/src/lib.rs @@ -30,6 +30,8 @@ pub mod decoder; pub mod dino; mod heads; pub mod mhr; +pub mod model; +pub mod packet; pub mod pose; pub mod preprocess; pub mod weights; diff --git a/libs/ai/models/body/src/model.rs b/libs/ai/models/body/src/model.rs new file mode 100644 index 000000000..9248717ca --- /dev/null +++ b/libs/ai/models/body/src/model.rs @@ -0,0 +1,267 @@ +//! The whole model, end to end: one RGB image and a person box in, the pose +//! packet out. Crop -> backbone -> ray-conditioned context -> the six +//! decoder steps, each closing the loop through the pose head, the rig and +//! the camera -> the final rig parameters, keypoints and projection. +//! +//! Body decoder only (the reference's `inference_type = "body"`): the hand +//! parameters come from the body decoder, the hand crops of the reference's +//! "full" mode are a later phase. + +use crate::condition::{dense_pe, ray_features, RayCond}; +use crate::decoder::{Decoder, StepFeedback, StepInput}; +use crate::dino::BodyDino; +use crate::mhr::MhrRig; +use crate::packet::{BodyPacket, BodyPerson}; +use crate::pose::{camera_translation, model_params, project, unpack_pose, PoseHeadParams}; +use crate::preprocess::{ + condition_info, crop_geometry, crop_normalized, full_to_crop, patch_rays, CropGeometry, +}; +use crate::weights::BodyWeights; +use crate::{DiffusionError, ProgressHook, Result, DINO_DIM, MHR_JOINTS, NUM_KEYPOINTS}; +use std::path::Path; +use std::time::Instant; + +pub struct BodyModel { + pub weights: BodyWeights, + dino: BodyDino, + ray_cond: RayCond, + dense_pe: Vec, + no_mask_embed: [f32; DINO_DIM], + decoder: Decoder, + rig: MhrRig, + /// Per-stage wall times of the last `infer`, milliseconds: + /// crop, backbone, context, decoder loop (incl. rig), packet. + pub last_stage_ms: [f32; 5], +} + +/// Everything one refinement step produced; the last one is the answer. +struct StepResult { + pose: PoseHeadParams, + params: [f32; 204], + cam_t: [f32; 3], + kp3d: Vec, + kp2d: Vec, + joints: Vec, +} + +impl BodyModel { + pub fn load(path: &Path) -> Result { + Self::load_with_progress(path, None) + } + + pub fn load_with_progress(path: &Path, progress: Option) -> Result { + let weights = BodyWeights::load(path)?; + let dino = BodyDino::prepare_with_progress(&weights, progress)?; + let ray_cond = RayCond::prepare(&weights)?; + let gaussian = weights.f32_shaped( + "prompt_encoder.pe_layer.positional_encoding_gaussian_matrix", + &[2, DINO_DIM / 2], + )?; + let no_mask = weights.f32_shaped("prompt_encoder.no_mask_embed.weight", &[1, DINO_DIM])?; + let mut no_mask_embed = [0.0f32; DINO_DIM]; + no_mask_embed.copy_from_slice(&no_mask); + let decoder = Decoder::load(&weights)?; + let rig = MhrRig::load(&weights)?; + Ok(Self { + weights, + dino, + ray_cond, + dense_pe: dense_pe(&gaussian), + no_mask_embed, + decoder, + rig, + last_stage_ms: [0.0; 5], + }) + } + + /// `rgb` is `width * height * 3` bytes; `bbox` is the person box in + /// full-image pixels (xyxy), the whole image when `None`. + pub fn infer( + &mut self, + rgb: &[u8], + width: u32, + height: u32, + bbox: Option<[f32; 4]>, + ) -> Result { + let (w, h) = (width as usize, height as usize); + if rgb.len() != w * h * 3 { + return Err(DiffusionError::workflow(format!( + "body infer: {} bytes for {width}x{height} rgb, expected {}", + rgb.len(), + w * h * 3 + ))); + } + let bbox = bbox.unwrap_or([0.0, 0.0, width as f32, height as f32]); + let total = Instant::now(); + let geo = crop_geometry(bbox, w, h, None); + let crop = crop_normalized(rgb, w, h, &geo); + let t_crop = total.elapsed(); + + let embeddings = self.dino.forward_normalized(&crop)?; + let t_backbone = total.elapsed(); + + let feats = ray_features(&patch_rays(&geo)); + let context = self.ray_cond.apply(&embeddings, &self.no_mask_embed, &feats)?; + drop(embeddings); + let t_context = total.elapsed(); + + let tokens = self.decoder.build_tokens(condition_info(&geo)); + let rig = &self.rig; + let mut last: Option = None; + self.decoder + .run(tokens, &context, &self.dense_pe, |step: StepInput| { + let result = close_the_loop(rig, &geo, &step); + let feedback = StepFeedback { + kp2d_cropped: full_to_crop(&result.kp2d, &geo), + depth: depths(&result.kp3d, result.cam_t), + kp3d: result.kp3d.clone(), + }; + last = Some(result); + feedback + })?; + let t_decoder = total.elapsed(); + + let last = last.ok_or_else(|| DiffusionError::model("body decoder ran no steps"))?; + let person = BodyPerson { + mhr: last.params, + global_rot: last.pose.global_rot, + cam_t: last.cam_t, + shape: last.pose.shape, + expr: last.pose.expr, + focal: geo.focal, + bbox, + kp3d: last.kp3d, + kp2d: last.kp2d, + joints: Some(last.joints), + rots: None, + }; + let t_packet = total.elapsed(); + self.last_stage_ms = [ + t_crop.as_secs_f32() * 1000.0, + (t_backbone - t_crop).as_secs_f32() * 1000.0, + (t_context - t_backbone).as_secs_f32() * 1000.0, + (t_decoder - t_context).as_secs_f32() * 1000.0, + (t_packet - t_decoder).as_secs_f32() * 1000.0, + ]; + Ok(BodyPacket { + people: vec![person], + ms: t_packet.as_secs_f32() * 1000.0, + }) + } +} + +/// One refinement step's tail: head output -> rig parameters -> posed rig +/// -> keypoints in camera axes -> camera translation -> projection. +fn close_the_loop(rig: &MhrRig, geo: &CropGeometry, step: &StepInput) -> StepResult { + let pose = unpack_pose(&step.pose_pred_519); + let params = model_params(rig, &pose); + let rigged = rig.forward(&pose.shape, ¶ms, &pose.expr, true); + // Rig output is centimetres in the rig's axes; the camera frame is + // metres with y and z flipped. + let to_camera = |values: &[f32], count: usize| -> Vec { + let mut out = Vec::with_capacity(count * 3); + for point in values[..count * 3].chunks_exact(3) { + out.push(point[0] / 100.0); + out.push(point[1] / -100.0); + out.push(point[2] / -100.0); + } + out + }; + let kp3d = to_camera(&rigged.keypoints308, NUM_KEYPOINTS); + let mut joint_positions = Vec::with_capacity(MHR_JOINTS * 3); + for joint in 0..MHR_JOINTS { + joint_positions.extend_from_slice(&rigged.skel_state[joint * 8..joint * 8 + 3]); + } + let joints = to_camera(&joint_positions, MHR_JOINTS); + let cam = [step.cam_pred_3[0], step.cam_pred_3[1], step.cam_pred_3[2]]; + let cam_t = camera_translation(cam, geo.center, geo.side, geo.focal, geo.principal); + let (kp2d, _) = project(&kp3d, cam_t, geo.focal, geo.principal); + StepResult { + pose, + params, + cam_t, + kp3d, + kp2d, + joints, + } +} + +fn depths(kp3d: &[f32], cam_t: [f32; 3]) -> Vec { + kp3d.chunks_exact(3).map(|point| point[2] + cam_t[2]).collect() +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::backend::gpu_device_available; + use crate::fixture; + + fn max_abs(actual: &[f32], expected: &[f32]) -> (f32, usize) { + assert_eq!(actual.len(), expected.len()); + actual + .iter() + .zip(expected) + .enumerate() + .map(|(index, (a, b))| ((a - b).abs(), index)) + .fold((0.0, 0), |best, (error, index)| if error > best.0 { (error, index) } else { best }) + } + + /// The whole pipeline on the oracle's image against the reference's + /// final outputs. The backbone runs in bf16 on both sides but not in the + /// same order, so the answer differs by a few millimetres, not by zero. + #[test] + fn oracle_end_to_end() { + let Some((shape, image)) = fixture::load("input_rgb_u8") else { + eprintln!("SKIP oracle_end_to_end: fixtures absent"); + return; + }; + let Some(weights_path) = fixture::weights_path() else { + eprintln!("SKIP oracle_end_to_end: weights absent"); + return; + }; + if !gpu_device_available() || !fixture::gpu_required_ops_available() { + eprintln!("SKIP oracle_end_to_end: no GPU"); + return; + } + let (h, w) = (shape[0] as u32, shape[1] as u32); + let rgb: Vec = image.iter().map(|v| *v as u8).collect(); + let load_started = Instant::now(); + let mut model = BodyModel::load(&weights_path).expect("load body model"); + eprintln!("body model load {:?}", load_started.elapsed()); + let packet = model.infer(&rgb, w, h, None).expect("infer"); + // A second run reports the warm timings. + let packet = model.infer(&rgb, w, h, None).unwrap_or(packet); + eprintln!( + "body infer warm {:.1} ms: crop {:.1}, backbone {:.1}, context {:.1}, decoder+rig {:.1}, packet {:.1}", + packet.ms, + model.last_stage_ms[0], + model.last_stage_ms[1], + model.last_stage_ms[2], + model.last_stage_ms[3], + model.last_stage_ms[4] + ); + let person = &packet.people[0]; + let (kp3d_err, kp3d_at) = max_abs(&person.kp3d, &fixture::load("final_pred_keypoints_3d").unwrap().1); + let (kp2d_err, kp2d_at) = max_abs(&person.kp2d, &fixture::load("final_pred_keypoints_2d").unwrap().1); + let (cam_err, _) = max_abs(&person.cam_t, &fixture::load("final_pred_cam_t").unwrap().1); + let (rot_err, _) = max_abs(&person.global_rot, &fixture::load("final_global_rot").unwrap().1); + let (mhr_err, mhr_at) = max_abs(&person.mhr, &fixture::load("final_mhr_model_params").unwrap().1); + let (joint_err, _) = max_abs( + person.joints.as_deref().unwrap(), + &fixture::load("final_pred_joint_coords").unwrap().1, + ); + eprintln!( + "body end-to-end vs reference: kp3d {kp3d_err:.4} m (kp {}), kp2d {kp2d_err:.2} px (kp {}), cam_t {cam_err:.4}, global_rot {rot_err:.4}, rig params {mhr_err:.4} (at {mhr_at}), joints {joint_err:.4} m", + kp3d_at / 3, + kp2d_at / 2 + ); + assert!(kp3d_err < 2.0e-2, "kp3d max abs {kp3d_err} m"); + assert!(kp2d_err < 8.0, "kp2d max abs {kp2d_err} px"); + assert!(cam_err < 5.0e-2, "cam_t max abs {cam_err}"); + assert!(rot_err < 5.0e-2, "global_rot max abs {rot_err}"); + assert!(joint_err < 2.0e-2, "joints max abs {joint_err} m"); + let json = packet.to_json(); + assert!(json.starts_with("{\"n_people\":1,\"people\":[{\"mhr\":[")); + assert!(json.contains("\"kp3d\":[") && json.contains("\"joints\":[")); + } +} diff --git a/libs/ai/models/body/src/packet.rs b/libs/ai/models/body/src/packet.rs new file mode 100644 index 000000000..5dd03a461 --- /dev/null +++ b/libs/ai/models/body/src/packet.rs @@ -0,0 +1,134 @@ +//! JSON packet shared by single-image and live SAM 3D Body inference. + +use std::fmt::Write; + +#[derive(Clone, Debug, PartialEq)] +pub struct BodyPerson { + pub mhr: [f32; 204], + pub global_rot: [f32; 3], + pub cam_t: [f32; 3], + pub shape: [f32; 45], + pub expr: [f32; 72], + pub focal: f32, + pub bbox: [f32; 4], + pub kp3d: Vec, + pub kp2d: Vec, + pub joints: Option>, + pub rots: Option>, +} + +#[derive(Clone, Debug, PartialEq)] +pub struct BodyPacket { + pub people: Vec, + pub ms: f32, +} + +impl BodyPacket { + pub fn to_json(&self) -> String { + let mut out = String::new(); + out.push_str("{\"n_people\":"); + let _ = write!(out, "{}", self.people.len()); + out.push_str(",\"people\":["); + for (index, person) in self.people.iter().enumerate() { + if index != 0 { + out.push(','); + } + push_person(&mut out, person); + } + out.push_str("],\"ms\":"); + push_f32(&mut out, self.ms); + out.push('}'); + out + } +} + +fn push_person(out: &mut String, person: &BodyPerson) { + out.push_str("{\"mhr\":"); + push_f32s(out, &person.mhr); + out.push_str(",\"global_rot\":"); + push_f32s(out, &person.global_rot); + out.push_str(",\"cam_t\":"); + push_f32s(out, &person.cam_t); + out.push_str(",\"shape\":"); + push_f32s(out, &person.shape); + out.push_str(",\"expr\":"); + push_f32s(out, &person.expr); + out.push_str(",\"focal\":"); + push_f32(out, person.focal); + out.push_str(",\"bbox\":"); + push_f32s(out, &person.bbox); + out.push_str(",\"kp3d\":"); + push_f32s(out, &person.kp3d); + out.push_str(",\"kp2d\":"); + push_f32s(out, &person.kp2d); + if let Some(joints) = &person.joints { + out.push_str(",\"joints\":"); + push_f32s(out, joints); + } + if let Some(rots) = &person.rots { + out.push_str(",\"rots\":"); + push_f32s(out, rots); + } + out.push('}'); +} + +fn push_f32s(out: &mut String, values: &[f32]) { + out.push('['); + for (index, &value) in values.iter().enumerate() { + if index != 0 { + out.push(','); + } + push_f32(out, value); + } + out.push(']'); +} + +fn push_f32(out: &mut String, value: f32) { + if !value.is_finite() { + out.push_str("null"); + return; + } + let start = out.len(); + let _ = write!(out, "{value:.4}"); + while out.as_bytes().last() == Some(&b'0') { + out.pop(); + } + if out.as_bytes().last() == Some(&b'.') { + out.push('0'); + } + debug_assert!(out.len() > start); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn json_field_order_optional_fields_and_rounding() { + let mut mhr = [0.0; 204]; + mhr[..4].copy_from_slice(&[1.23456, -2.34567, 3.0, -0.00001]); + let packet = BodyPacket { + people: vec![BodyPerson { + mhr, + global_rot: [0.1, 0.2, 0.3], + cam_t: [1.0, 2.0, 3.0], + shape: [0.0; 45], + expr: [0.0; 72], + focal: 1234.56789, + bbox: [1.0, 2.0, 30.0, 40.0], + kp3d: vec![0.12345; 70 * 3], + kp2d: vec![5.67894; 70 * 2], + joints: Some(vec![0.25; 127 * 3]), + rots: None, + }], + ms: 12.34567, + }; + let json = packet.to_json(); + assert!(json.starts_with( + "{\"n_people\":1,\"people\":[{\"mhr\":[1.2346,-2.3457,3.0,-0.0," + )); + assert!(json.contains("\"joints\":[0.25")); + assert!(!json.contains("\"rots\"")); + assert!(json.ends_with("],\"ms\":12.3457}")); + } +} From a6341981d806175b2945c81ecbf661e9a579d1ab Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 23:03:20 +0200 Subject: [PATCH 021/417] ai-hub: the body-native commit carried a peer's in-flight hub hunks; put them back where they were 66e5e2f11 committed the working tree of the shared hub files and with it another lane's uncommitted edits (a new domain, request fields, a backend arm, manifest lines). This commit restores those files to the previous tree plus only the body-native hunks. The working tree is untouched: the peer's edits stay on disk as their uncommitted work, exactly as before. Co-Authored-By: Claude Fable 5.1 --- apps/ai-hub/Cargo.toml | 3 +-- libs/ai/hub/Cargo.toml | 24 +++-------------- libs/ai/hub/registry.json | 52 ------------------------------------- libs/ai/hub/src/backend.rs | 28 +------------------- libs/ai/hub/src/lib.rs | 5 ---- libs/ai/hub/src/registry.rs | 36 ++----------------------- 6 files changed, 7 insertions(+), 141 deletions(-) diff --git a/apps/ai-hub/Cargo.toml b/apps/ai-hub/Cargo.toml index 264af2b46..0ecb86897 100644 --- a/apps/ai-hub/Cargo.toml +++ b/apps/ai-hub/Cargo.toml @@ -14,7 +14,7 @@ makepad-ai-hub = { path = "../../libs/ai/hub", default-features = false } # Feature passthrough: the headless node exposes exactly the library's # feature set, so box launch scripts keep their --features flags working. [features] -default = ["flux", "paint", "paint-cuda", "llm", "tts", "indextts", "video", "interpolate", "audio", "mesh", "matte-native", "depth-native", "segment-native", "body-native", "upscale-native", "motion-native", "rig-native", "splat-native"] +default = ["flux", "paint", "paint-cuda", "llm", "tts", "indextts", "video", "interpolate", "audio", "mesh", "matte-native", "depth-native", "segment-native", "upscale-native", "motion-native", "rig-native", "splat-native"] python-backends = ["makepad-ai-hub/python-backends"] flux = ["makepad-ai-hub/flux"] paint = ["makepad-ai-hub/paint"] @@ -29,7 +29,6 @@ mesh = ["makepad-ai-hub/mesh"] matte-native = ["makepad-ai-hub/matte-native"] depth-native = ["makepad-ai-hub/depth-native"] segment-native = ["makepad-ai-hub/segment-native"] -body-native = ["makepad-ai-hub/body-native"] upscale-native = ["makepad-ai-hub/upscale-native"] motion-native = ["makepad-ai-hub/motion-native"] splat-native = ["makepad-ai-hub/splat-native"] diff --git a/libs/ai/hub/Cargo.toml b/libs/ai/hub/Cargo.toml index ce9c69072..962ffe022 100644 --- a/libs/ai/hub/Cargo.toml +++ b/libs/ai/hub/Cargo.toml @@ -20,8 +20,6 @@ default = [ "llm", "tts", "indextts", - "speech", - "stt", "video", "interpolate", "audio", @@ -29,7 +27,6 @@ default = [ "matte-native", "depth-native", "segment-native", - "body-native", "upscale-native", "motion-native", "rig-native", @@ -51,15 +48,10 @@ paint = ["dep:makepad-ai-paint", "dep:makepad-gltf", "dep:makepad-remesh", "dep: paint-cuda = ["paint", "makepad-ai-paint/cuda-taps"] # Real LLM prompt expansion via makepad-ai-llm (Qwen3.5/3.6 GGUF). llm = ["dep:makepad-ai-llm"] -# Speech sessions (AiHub::start_stt / start_tts): the OS engines as the -# stt.system / tts.system pipes plus the in-process / machine / LAN ladder. -speech = ["dep:makepad-system-speech"] -# Whisper speech-to-text (stt.whisper), in-process and on the wire. -stt = ["speech", "dep:makepad-ai-speech", "makepad-ai-speech/whisper"] # Real Kokoro speech synthesis via makepad-ai-speech. -tts = ["dep:makepad-ai-speech", "makepad-ai-speech/kokoro"] +tts = ["dep:makepad-ai-speech"] # Real IndexTTS-2.5 character-voice TTS via makepad-ai-speech. -indextts = ["dep:makepad-ai-speech", "makepad-ai-speech/indextts", "dep:makepad-ai-common"] +indextts = ["dep:makepad-ai-speech", "dep:makepad-ai-common"] # Real MiniMax H3 video generation via makepad-ai-h3 plus the hardware # video file encoder (makepad-video). Does NOT pull the UI platform crate. video = ["dep:makepad-ai-h3", "dep:makepad-ai-common", "dep:makepad-video"] @@ -81,8 +73,6 @@ matte-native = ["dep:makepad-ai-vision", "dep:makepad-ai-common"] depth-native = ["dep:makepad-ai-vision", "dep:makepad-ai-common"] # Native SAM 3.1 multiplex segmentation. Independent of `mesh`. segment-native = ["dep:makepad-ai-vision", "dep:makepad-ai-common"] -# Native SAM 3D Body pose estimation. -body-native = ["dep:makepad-ai-body", "dep:makepad-ai-common"] # Native RealESRGAN x4plus general-image upscaling. Independent of `mesh`. upscale-native = ["dep:makepad-ai-vision", "dep:makepad-ai-common"] # Native HY-Motion decode -> rig retarget -> animated GLB. @@ -117,7 +107,6 @@ makepad-ai-flux = { path = "../../ai/models/flux", optional = true } makepad-ai-h3 = { path = "../../ai/models/h3", optional = true } makepad-ai-rife = { path = "../../ai/models/rife", optional = true } makepad-ai-vision = { path = "../../ai/models/vision", optional = true } -makepad-ai-body = { path = "../models/body", optional = true } makepad-ai-rig = { path = "../../ai/models/rig", optional = true } makepad-ai-motion = { path = "../../ai/models/motion", optional = true } makepad-ai-sfx = { path = "../../ai/models/sfx", optional = true } @@ -130,8 +119,7 @@ makepad-gltf = { path = "../../gltf", optional = true } makepad-xatlas = { path = "../../xatlas", optional = true } makepad-render = { path = "../../render", optional = true } makepad-ai-llm = { path = "../../ai/llm", optional = true } -makepad-ai-speech = { path = "../../ai/models/speech", default-features = false, optional = true } -makepad-system-speech = { path = "../../system_speech", optional = true } +makepad-ai-speech = { path = "../../ai/models/speech", optional = true } makepad-video = { path = "../../../platform/video", optional = true } # The `mkfl` motion payload: ONE definition, shared with the VJ's import # converter (which fills the same box from a classical, model-free flow @@ -177,9 +165,3 @@ path = "src/bin/context_ladder.rs" [[bin]] name = "ocr-bench" path = "src/bin/ocr_bench.rs" - -# TTS -> STT through the hub's own speech sessions, scored as word error rate: -# the scoreboard for comparing engines and the end-to-end check of the ladder. -[[bin]] -name = "speech-roundtrip" -path = "src/bin/speech_roundtrip.rs" diff --git a/libs/ai/hub/registry.json b/libs/ai/hub/registry.json index cfe5cccd7..deb1c88d9 100644 --- a/libs/ai/hub/registry.json +++ b/libs/ai/hub/registry.json @@ -623,32 +623,6 @@ } ] }, - { - "id": "whisper-large-v3-turbo", - "domain": "stt", - "backend": "whisper", - "available": true, - "gated": false, - "license": { - "name": "MIT License", - "url": "https://huggingface.co/ggerganov/whisper.cpp", - "summary": "OpenAI Whisper large-v3-turbo weights in ggml format as distributed by ggerganov/whisper.cpp (MIT). Permissive use, including commercial.", - "restriction": "none" - }, - "vram_gb": 2.0, - "note": "Whisper large-v3-turbo speech-to-text via the in-repo pure-Rust port (makepad-ai-speech whisper module; Metal/CUDA/CPU). Request: input_b64 audio/wav (any rate/channels, downmixed + resampled to 16 kHz) + language. Output: one application/json TranscriptJson {text, segments[{start_ms,end_ms,text}]}. The wire side of the stt.whisper pipe; apps reach it through AiHub::start_stt.", - "files": [ - { - "repo": "ggerganov/whisper.cpp", - "path": "ggml-large-v3-turbo.bin", - "revision": "5359861c739e955e79d9a303bcbc70fb988958b1", - "cache_as": "stt/ggml-large-v3-turbo.bin", - "size": 1624555275, - "sha256": "1fc70f774d38eb169993ac391eea357ef47c88757ef72ee5943879b7e8e2bc69", - "local": false - } - ] - }, { "id": "kokoro", "domain": "speech", @@ -1767,32 +1741,6 @@ } ] }, - { - "id": "sam3dbody", - "domain": "body", - "backend": "body-native", - "available": true, - "gated": false, - "license": { - "name": "SAM License", - "url": "https://huggingface.co/Comfy-Org/sam-3d-body", - "summary": "SAM 3D Body is under the SAM License / Meta acceptable-use terms published with the checkpoint. Review the model card before production use. This stack never downloads facebook/* checkpoints.", - "restriction": "community" - }, - "vram_gb": 4.5, - "note": "SAM 3D Body (Comfy-Org/sam-3d-body, SAM License) RGB image -> application/json human pose packet. Native Rust inference; no Python, Torch, subprocess, or silent fallback. facebook/* checkpoints are never fetched. The checkpoint is pinned to an immutable revision, byte size, and SHA-256.", - "files": [ - { - "role": "native-body", - "repo": "Comfy-Org/sam-3d-body", - "path": "detection/sam_3d_body_dinov3_bf16.safetensors", - "revision": "60476aced0b8de0a0e82a318c79a85061cc97434", - "cache_as": "body/sam3dbody/sam_3d_body_dinov3_bf16.safetensors", - "size": 2830737652, - "sha256": "59fa45200c504c5b56625004d7d3385daf48c616613e88099e43bf83b3e249cf" - } - ] - }, { "id": "sam3dbody-ref", "domain": "body", diff --git a/libs/ai/hub/src/backend.rs b/libs/ai/hub/src/backend.rs index 49d1b9fd9..a710c782c 100644 --- a/libs/ai/hub/src/backend.rs +++ b/libs/ai/hub/src/backend.rs @@ -93,8 +93,6 @@ pub struct GenerateParams { pub text: String, pub voice: String, pub speed: f32, - /// Speech language hint (`language` on the wire); "" = model default. - pub language: String, /// 8-slot emotion vector (indextts), validated to length 8 and clamped /// per-slot to [0, 1.2]; `None` = neutral. pub emotion: Option<[f32; 8]>, @@ -345,7 +343,6 @@ impl GenerateParams { text: request.text.clone().unwrap_or_default(), voice: request.voice.clone().unwrap_or_default(), - language: request.language.clone().unwrap_or_default(), speed: if speed.is_finite() && speed > 0.0 { speed.clamp(0.25, 4.0) as f32 } else { @@ -1570,7 +1567,6 @@ pub fn backend_compiled(name: &str) -> bool { "vision" => cfg!(feature = "llm"), "ocr" => cfg!(feature = "llm"), "kokoro" => cfg!(feature = "tts"), - "whisper" => cfg!(feature = "stt"), "indextts" => cfg!(feature = "indextts"), // The `fast` (FastH3) lane rides the H3 pipeline: same feature. "h3" | "fast" => cfg!(feature = "video"), @@ -1583,7 +1579,6 @@ pub fn backend_compiled(name: &str) -> bool { "matte-native" => cfg!(feature = "matte-native"), "depth-native" => cfg!(feature = "depth-native"), "segment-native" => cfg!(feature = "segment-native"), - "body-native" => cfg!(feature = "body-native"), "upscale-native" => cfg!(feature = "upscale-native"), "video-enhance" => { cfg!(feature = "upscale-native") @@ -1640,12 +1635,9 @@ pub fn backend_provisioned(name: &str) -> bool { // on macOS, CUDA on Windows/Linux, probed once and memoised. "vision" => crate::vision_backend::vision_provisioned(), "ocr" => crate::vision_backend::vision_provisioned(), - "body" => { - crate::body_backend::body_provisioned() || cfg!(feature = "body-native") - } + "body" => crate::body_backend::body_provisioned(), "depth-native" => cfg!(feature = "depth-native"), "segment-native" => cfg!(feature = "segment-native"), - "body-native" => cfg!(feature = "body-native"), "upscale-native" => cfg!(feature = "upscale-native"), "video-enhance" => { cfg!(feature = "upscale-native") @@ -1776,15 +1768,6 @@ pub fn create_backend(spec: &ModelSpec) -> Result, Asset &spec.id, ))), "body" => Ok(Box::new(crate::body_backend::BodyBackend::new(&spec.id))), - #[cfg(feature = "body-native")] - "body-native" => Ok(Box::new( - crate::body_native_backend::BodyNativeBackend::new_native(&spec.id), - )), - #[cfg(not(feature = "body-native"))] - "body-native" => Err(AssetAiError::Unavailable(format!( - "model {} needs a build with the 'body-native' cargo feature", - spec.id - ))), #[cfg(feature = "flux")] "flux" => Ok(Box::new(crate::flux_backend::FluxBackend::new(&spec.id))), #[cfg(not(feature = "flux"))] @@ -1834,15 +1817,6 @@ pub fn create_backend(spec: &ModelSpec) -> Result, Asset "model {} needs a build with the 'llm' cargo feature", spec.id ))), - #[cfg(feature = "stt")] - "whisper" => Ok(Box::new(crate::whisper_backend::WhisperBackend::new_whisper( - &spec.id, - ))), - #[cfg(not(feature = "stt"))] - "whisper" => Err(AssetAiError::Unavailable(format!( - "model {} needs a build with the 'stt' cargo feature", - spec.id - ))), #[cfg(feature = "tts")] "kokoro" => Ok(Box::new(crate::kokoro_backend::KokoroBackend::new_kokoro( &spec.id, diff --git a/libs/ai/hub/src/lib.rs b/libs/ai/hub/src/lib.rs index c80f84adf..03f4a0ce6 100644 --- a/libs/ai/hub/src/lib.rs +++ b/libs/ai/hub/src/lib.rs @@ -33,7 +33,6 @@ pub mod backend; pub mod body_backend; -pub mod body_native_backend; pub mod chat_wire; pub use makepad_base64; pub mod client; @@ -58,10 +57,6 @@ pub mod lane_advert; pub mod lease; pub mod indextts_backend; pub mod kokoro_backend; -#[cfg(feature = "stt")] -pub mod whisper_backend; -#[cfg(feature = "speech")] -pub mod speech; pub mod llm_backend; #[cfg(feature = "llm")] pub mod local_llm; diff --git a/libs/ai/hub/src/registry.rs b/libs/ai/hub/src/registry.rs index 4896cb035..18ae62cf1 100644 --- a/libs/ai/hub/src/registry.rs +++ b/libs/ai/hub/src/registry.rs @@ -195,9 +195,6 @@ pub enum Domain { Vision, /// Scanned page -> HTML transcription (Chandra 2 on the vision tower). Ocr, - /// Speech audio -> timed transcript (Whisper). The `stt.whisper` pipe; - /// `Speech` stays text-to-speech, so the two never share affinity. - Stt, } impl Domain { @@ -226,7 +223,6 @@ impl Domain { "splat" => Some(Domain::Splat), "vision" => Some(Domain::Vision), "ocr" => Some(Domain::Ocr), - "stt" => Some(Domain::Stt), _ => None, } } @@ -256,7 +252,6 @@ impl Domain { Domain::Splat => "splat", Domain::Vision => "vision", Domain::Ocr => "ocr", - Domain::Stt => "stt", } } } @@ -1497,35 +1492,8 @@ mod tests { // The licensing guard lives in the note: the x.1 refreshes are NC. assert!(depth.note.as_deref().unwrap().contains("Apache-2.0")); - // Body domain: pinned native artifact and externally provisioned - // reference worker. - let native_body = registry.find("sam3dbody").unwrap(); - assert_eq!(native_body.domain, Domain::Body); - assert_eq!(native_body.backend, "body-native"); - assert!(native_body.available && !native_body.gated); - assert_eq!(native_body.vram_gb, Some(4.5)); - assert_eq!(native_body.files.len(), 1); - let body_weights = native_body.file_by_role("native-body").unwrap(); - assert_eq!(body_weights.repo, "Comfy-Org/sam-3d-body"); - assert_eq!( - body_weights.path, - "detection/sam_3d_body_dinov3_bf16.safetensors" - ); - assert_eq!( - body_weights.revision.as_deref(), - Some("60476aced0b8de0a0e82a318c79a85061cc97434") - ); - assert_eq!(body_weights.size, Some(2_830_737_652)); - assert_eq!( - body_weights.sha256.as_deref(), - Some("59fa45200c504c5b56625004d7d3385daf48c616613e88099e43bf83b3e249cf") - ); - assert_eq!( - body_weights.cache_as, - "body/sam3dbody/sam_3d_body_dinov3_bf16.safetensors" - ); - assert!(!body_weights.repo.starts_with("facebook/")); - + // Body domain: externally provisioned persistent worker, no hub-side + // model artifact download. let body = registry.find("sam3dbody-ref").unwrap(); assert_eq!(body.domain, Domain::Body); assert_eq!(body.backend, "body"); From 9ff44e87a6e81e60148dfa1f97251e8b3204873b Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 23:03:47 +0200 Subject: [PATCH 022/417] ai-hub: the body-native wiring, this time only the lane's hunks The recut in a6341981d applied its patch against the wrong directory and restored the six shared files to the previous tree without the body-native hunks. This commit adds exactly those: the `body-native` feature and optional dependency, the pinned `sam3dbody` registry entry and its test, the backend arms and the module declaration. Working tree untouched. Co-Authored-By: Claude Fable 5.1 --- apps/ai-hub/Cargo.toml | 3 ++- libs/ai/hub/Cargo.toml | 4 ++++ libs/ai/hub/registry.json | 26 ++++++++++++++++++++++++++ libs/ai/hub/src/backend.rs | 15 ++++++++++++++- libs/ai/hub/src/lib.rs | 1 + libs/ai/hub/src/registry.rs | 31 +++++++++++++++++++++++++++++-- 6 files changed, 76 insertions(+), 4 deletions(-) diff --git a/apps/ai-hub/Cargo.toml b/apps/ai-hub/Cargo.toml index 0ecb86897..264af2b46 100644 --- a/apps/ai-hub/Cargo.toml +++ b/apps/ai-hub/Cargo.toml @@ -14,7 +14,7 @@ makepad-ai-hub = { path = "../../libs/ai/hub", default-features = false } # Feature passthrough: the headless node exposes exactly the library's # feature set, so box launch scripts keep their --features flags working. [features] -default = ["flux", "paint", "paint-cuda", "llm", "tts", "indextts", "video", "interpolate", "audio", "mesh", "matte-native", "depth-native", "segment-native", "upscale-native", "motion-native", "rig-native", "splat-native"] +default = ["flux", "paint", "paint-cuda", "llm", "tts", "indextts", "video", "interpolate", "audio", "mesh", "matte-native", "depth-native", "segment-native", "body-native", "upscale-native", "motion-native", "rig-native", "splat-native"] python-backends = ["makepad-ai-hub/python-backends"] flux = ["makepad-ai-hub/flux"] paint = ["makepad-ai-hub/paint"] @@ -29,6 +29,7 @@ mesh = ["makepad-ai-hub/mesh"] matte-native = ["makepad-ai-hub/matte-native"] depth-native = ["makepad-ai-hub/depth-native"] segment-native = ["makepad-ai-hub/segment-native"] +body-native = ["makepad-ai-hub/body-native"] upscale-native = ["makepad-ai-hub/upscale-native"] motion-native = ["makepad-ai-hub/motion-native"] splat-native = ["makepad-ai-hub/splat-native"] diff --git a/libs/ai/hub/Cargo.toml b/libs/ai/hub/Cargo.toml index 962ffe022..2a6919ec2 100644 --- a/libs/ai/hub/Cargo.toml +++ b/libs/ai/hub/Cargo.toml @@ -27,6 +27,7 @@ default = [ "matte-native", "depth-native", "segment-native", + "body-native", "upscale-native", "motion-native", "rig-native", @@ -73,6 +74,8 @@ matte-native = ["dep:makepad-ai-vision", "dep:makepad-ai-common"] depth-native = ["dep:makepad-ai-vision", "dep:makepad-ai-common"] # Native SAM 3.1 multiplex segmentation. Independent of `mesh`. segment-native = ["dep:makepad-ai-vision", "dep:makepad-ai-common"] +# Native SAM 3D Body pose estimation. +body-native = ["dep:makepad-ai-body", "dep:makepad-ai-common"] # Native RealESRGAN x4plus general-image upscaling. Independent of `mesh`. upscale-native = ["dep:makepad-ai-vision", "dep:makepad-ai-common"] # Native HY-Motion decode -> rig retarget -> animated GLB. @@ -107,6 +110,7 @@ makepad-ai-flux = { path = "../../ai/models/flux", optional = true } makepad-ai-h3 = { path = "../../ai/models/h3", optional = true } makepad-ai-rife = { path = "../../ai/models/rife", optional = true } makepad-ai-vision = { path = "../../ai/models/vision", optional = true } +makepad-ai-body = { path = "../models/body", optional = true } makepad-ai-rig = { path = "../../ai/models/rig", optional = true } makepad-ai-motion = { path = "../../ai/models/motion", optional = true } makepad-ai-sfx = { path = "../../ai/models/sfx", optional = true } diff --git a/libs/ai/hub/registry.json b/libs/ai/hub/registry.json index deb1c88d9..3b92a32b7 100644 --- a/libs/ai/hub/registry.json +++ b/libs/ai/hub/registry.json @@ -1741,6 +1741,32 @@ } ] }, + { + "id": "sam3dbody", + "domain": "body", + "backend": "body-native", + "available": true, + "gated": false, + "license": { + "name": "SAM License", + "url": "https://huggingface.co/Comfy-Org/sam-3d-body", + "summary": "SAM 3D Body is under the SAM License / Meta acceptable-use terms published with the checkpoint. Review the model card before production use. This stack never downloads facebook/* checkpoints.", + "restriction": "community" + }, + "vram_gb": 4.5, + "note": "SAM 3D Body (Comfy-Org/sam-3d-body, SAM License) RGB image -> application/json human pose packet. Native Rust inference; no Python, Torch, subprocess, or silent fallback. facebook/* checkpoints are never fetched. The checkpoint is pinned to an immutable revision, byte size, and SHA-256.", + "files": [ + { + "role": "native-body", + "repo": "Comfy-Org/sam-3d-body", + "path": "detection/sam_3d_body_dinov3_bf16.safetensors", + "revision": "60476aced0b8de0a0e82a318c79a85061cc97434", + "cache_as": "body/sam3dbody/sam_3d_body_dinov3_bf16.safetensors", + "size": 2830737652, + "sha256": "59fa45200c504c5b56625004d7d3385daf48c616613e88099e43bf83b3e249cf" + } + ] + }, { "id": "sam3dbody-ref", "domain": "body", diff --git a/libs/ai/hub/src/backend.rs b/libs/ai/hub/src/backend.rs index a710c782c..bc05842ba 100644 --- a/libs/ai/hub/src/backend.rs +++ b/libs/ai/hub/src/backend.rs @@ -1579,6 +1579,7 @@ pub fn backend_compiled(name: &str) -> bool { "matte-native" => cfg!(feature = "matte-native"), "depth-native" => cfg!(feature = "depth-native"), "segment-native" => cfg!(feature = "segment-native"), + "body-native" => cfg!(feature = "body-native"), "upscale-native" => cfg!(feature = "upscale-native"), "video-enhance" => { cfg!(feature = "upscale-native") @@ -1635,9 +1636,12 @@ pub fn backend_provisioned(name: &str) -> bool { // on macOS, CUDA on Windows/Linux, probed once and memoised. "vision" => crate::vision_backend::vision_provisioned(), "ocr" => crate::vision_backend::vision_provisioned(), - "body" => crate::body_backend::body_provisioned(), + "body" => { + crate::body_backend::body_provisioned() || cfg!(feature = "body-native") + } "depth-native" => cfg!(feature = "depth-native"), "segment-native" => cfg!(feature = "segment-native"), + "body-native" => cfg!(feature = "body-native"), "upscale-native" => cfg!(feature = "upscale-native"), "video-enhance" => { cfg!(feature = "upscale-native") @@ -1768,6 +1772,15 @@ pub fn create_backend(spec: &ModelSpec) -> Result, Asset &spec.id, ))), "body" => Ok(Box::new(crate::body_backend::BodyBackend::new(&spec.id))), + #[cfg(feature = "body-native")] + "body-native" => Ok(Box::new( + crate::body_native_backend::BodyNativeBackend::new_native(&spec.id), + )), + #[cfg(not(feature = "body-native"))] + "body-native" => Err(AssetAiError::Unavailable(format!( + "model {} needs a build with the 'body-native' cargo feature", + spec.id + ))), #[cfg(feature = "flux")] "flux" => Ok(Box::new(crate::flux_backend::FluxBackend::new(&spec.id))), #[cfg(not(feature = "flux"))] diff --git a/libs/ai/hub/src/lib.rs b/libs/ai/hub/src/lib.rs index 03f4a0ce6..a1a59dcaf 100644 --- a/libs/ai/hub/src/lib.rs +++ b/libs/ai/hub/src/lib.rs @@ -33,6 +33,7 @@ pub mod backend; pub mod body_backend; +pub mod body_native_backend; pub mod chat_wire; pub use makepad_base64; pub mod client; diff --git a/libs/ai/hub/src/registry.rs b/libs/ai/hub/src/registry.rs index 18ae62cf1..e8a723429 100644 --- a/libs/ai/hub/src/registry.rs +++ b/libs/ai/hub/src/registry.rs @@ -1492,8 +1492,35 @@ mod tests { // The licensing guard lives in the note: the x.1 refreshes are NC. assert!(depth.note.as_deref().unwrap().contains("Apache-2.0")); - // Body domain: externally provisioned persistent worker, no hub-side - // model artifact download. + // Body domain: pinned native artifact and externally provisioned + // reference worker. + let native_body = registry.find("sam3dbody").unwrap(); + assert_eq!(native_body.domain, Domain::Body); + assert_eq!(native_body.backend, "body-native"); + assert!(native_body.available && !native_body.gated); + assert_eq!(native_body.vram_gb, Some(4.5)); + assert_eq!(native_body.files.len(), 1); + let body_weights = native_body.file_by_role("native-body").unwrap(); + assert_eq!(body_weights.repo, "Comfy-Org/sam-3d-body"); + assert_eq!( + body_weights.path, + "detection/sam_3d_body_dinov3_bf16.safetensors" + ); + assert_eq!( + body_weights.revision.as_deref(), + Some("60476aced0b8de0a0e82a318c79a85061cc97434") + ); + assert_eq!(body_weights.size, Some(2_830_737_652)); + assert_eq!( + body_weights.sha256.as_deref(), + Some("59fa45200c504c5b56625004d7d3385daf48c616613e88099e43bf83b3e249cf") + ); + assert_eq!( + body_weights.cache_as, + "body/sam3dbody/sam_3d_body_dinov3_bf16.safetensors" + ); + assert!(!body_weights.repo.starts_with("facebook/")); + let body = registry.find("sam3dbody-ref").unwrap(); assert_eq!(body.domain, Domain::Body); assert_eq!(body.backend, "body"); From 6a1c16b2cb85608b94a573389e743ab3e8255dc2 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 23:05:43 +0200 Subject: [PATCH 023/417] =?UTF-8?q?ai-body:=20third-party=20notices=20?= =?UTF-8?q?=E2=80=94=20what=20the=20port=20is=20implemented=20after,=20and?= =?UTF-8?q?=20what=20it=20is=20not?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- libs/ai/models/body/THIRD_PARTY_NOTICES.md | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 libs/ai/models/body/THIRD_PARTY_NOTICES.md diff --git a/libs/ai/models/body/THIRD_PARTY_NOTICES.md b/libs/ai/models/body/THIRD_PARTY_NOTICES.md new file mode 100644 index 000000000..189a54bf7 --- /dev/null +++ b/libs/ai/models/body/THIRD_PARTY_NOTICES.md @@ -0,0 +1,83 @@ +# Third-party notices — `makepad-ai-body` + +The code in this crate is our own and is licensed MIT, like the rest of the +repository (see the `license` field in `Cargo.toml` and the repository +`LICENSE`). This file records the third-party work our port is *implemented +after*, and the attribution those upstreams ask for. + +Nothing listed here is vendored. No third-party source file is copied into +this crate, and no model weights are redistributed by this repository — +operators pull the checkpoint at runtime under the checkpoint's own license. + +--- + +## SAM 3D Body — `src/model.rs`, `src/decoder.rs`, `src/heads.rs`, `src/pose.rs`, `src/preprocess.rs`, `src/condition.rs` + +**Architecture implemented after the published paper.** SAM 3D Body: Robust +Full-Body Human Mesh Recovery (Meta AI, arXiv:2602.15989, +). The promptable decoder is described +there as a Segment-Anything-style transformer decoder over image tokens +with pose, prompt and keypoint tokens, refined layer by layer through the +rig; the crop, CLIFF-style camera conditioning, ray conditioning and +perspective camera follow the paper's description of the pipeline. + +The reference inference code published with the model +() is released under the +SAM License and is **not** part of this crate: it was not copied, adapted or +vendored. The port was written from an architecture specification (tensor +inventory, operation order, formulas) and validated against reference +intermediate dumps produced by running that reference code on its own, +outside the repository, on a public-domain photograph. + +## DINOv3 ViT-H+/16 — `src/dino.rs` + +**Architecture implemented after: Hugging Face `transformers`, Apache +License 2.0.** + +> The vision backbone in `src/dino.rs` is implemented after the `DINOv3ViT` +> implementation in Hugging Face `transformers`, +> +> (`modeling_dinov3_vit.py`, `configuration_dinov3_vit.py`), the same source +> the TRELLIS conditioner in `makepad-ai-trellis` follows, whose copyright +> header reads: +> +> > Copyright 2025 The Meta AI Authors and The HuggingFace Team. All rights reserved. +> > Licensed under the Apache License, Version 2.0 (the "License"); +> > you may not use this file except in compliance with the License. +> > You may obtain a copy of the License at +> > + +Every architectural constant of the backbone — patch 16, width 1280, depth +32, 20 heads, the SwiGLU feed-forward of width 5120, the four register +tokens, the axial rotate-half rotary embedding with base 100, layer scale on +both residuals, LayerNorm with eps 1e-5 — is present in that Apache-2.0 +source. The checkpoint's tensor names follow the same implementation. + +## Momentum Human Rig (MHR) — `src/mhr.rs` + +**Rig semantics implemented after: facebookresearch/MHR, Apache License 2.0** +(), which describes the rig's +parameterisation (identity and expression blendshapes, the model-parameter +to joint-parameter transform, the joint hierarchy with per-joint translation +offsets, pre-rotations, XYZ euler rotations and log2 scales, the pose +corrective MLP, linear blend skinning against an inverse bind pose) and +whose downloadable rig assets are Apache-2.0. The kinematics follow +Momentum (, MIT). The rig data +this crate loads (`mhr.*`) ships inside the model checkpoint below. + +## Weights — SAM License + +The production checkpoint is the Comfy-Org repack `Comfy-Org/sam-3d-body`, +`detection/sam_3d_body_dinov3_bf16.safetensors`, pinned in the hub registry +by revision, byte size and SHA-256. It is released under the SAM License +(see the model card at ); +operators must review and comply with those terms. This repository never +downloads `facebook/*` checkpoints and never redistributes weights. + +### Reference numerics + +The port reproduces the reference pipeline's numerics for the body decoder +path (`inference_type = "body"`): rig vertices within 1e-4 cm, keypoints +within 1e-6 m from identical rig parameters, and end to end from an image +within 2 mm on 3D keypoints and 0.5 px on 2D keypoints, the residue being +bf16 accumulation-order noise in the backbone. From d78411a63b37264e97439c336ebf11fd49dea651 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 23:12:05 +0200 Subject: [PATCH 024/417] ai-body: the per-step work moves to the GPU On the 4090 the frame was 885 ms of which 840 were host scalar loops in the decoder loop: the three 70-row refinement FFNs (about 240M multiply-adds a step), the two heads, and the rig's 55k x 3000 corrective output layer plus its identity blendshape sum. Those are now GPU-resident linears (heads.rs GpuStepHeads, MhrRig::prepare_gpu), the skinning computes one transform per joint instead of one per influence, and the results are identical (all 29 oracle tests unchanged). The rig still runs entirely on the host when no GPU side was prepared. Co-Authored-By: Claude Fable 5.1 --- libs/ai/models/body/src/decoder.rs | 15 ++-- libs/ai/models/body/src/fixture.rs | 37 +++++----- libs/ai/models/body/src/heads.rs | 108 ++++++++++++++++++++++++++++- libs/ai/models/body/src/mhr.rs | 92 +++++++++++++++++++++--- libs/ai/models/body/src/model.rs | 3 +- libs/ai/models/body/src/pose.rs | 2 +- 6 files changed, 217 insertions(+), 40 deletions(-) diff --git a/libs/ai/models/body/src/decoder.rs b/libs/ai/models/body/src/decoder.rs index e9bbaef8b..980a0cec3 100644 --- a/libs/ai/models/body/src/decoder.rs +++ b/libs/ai/models/body/src/decoder.rs @@ -4,7 +4,7 @@ use crate::backend::{ gpu_add, gpu_attention_packed_cross, gpu_download, gpu_gelu_erf, gpu_layer_norm_mul_add, gpu_linear_f32_resident, gpu_upload, GpuTensor, }; -use crate::heads::{DecoderHeads, HostLinear}; +use crate::heads::{DecoderHeads, GpuStepHeads, HostLinear}; use crate::weights::BodyWeights; use crate::{ DEC_DEPTH, DEC_DIM, DEC_FFN, DEC_HEADS, DEC_INNER, DEC_NORM_EPS, DINO_DIM, NCAM, @@ -294,6 +294,7 @@ pub struct Decoder { layers: Vec, norm_final: NormWeights, heads: DecoderHeads, + step_heads: GpuStepHeads, init_pose: Vec, init_camera: Vec, tokens: TokenWeights, @@ -339,10 +340,12 @@ impl Decoder { for layer in weights.layers { layers.push(DecoderLayer::upload(layer)?); } + let step_heads = GpuStepHeads::upload(&weights.heads)?; Ok(Self { layers, norm_final: weights.norm_final, heads: weights.heads, + step_heads, init_pose: weights.init_pose, init_camera: weights.init_camera, tokens: weights.tokens, @@ -420,9 +423,9 @@ impl Decoder { (**callback)(layer_index, &hidden, &final_normed)?; } let pose_token = &final_normed[..DEC_DIM]; - last_pose = self.heads.pose(pose_token); + last_pose = self.step_heads.pose(pose_token)?; add_in_place(&mut last_pose, &self.init_pose); - last_camera = self.heads.camera(pose_token); + last_camera = self.step_heads.camera(pose_token)?; add_in_place(&mut last_camera, &self.init_camera); let feedback = step(StepInput { layer: layer_index, @@ -486,7 +489,7 @@ impl Decoder { && depth >= 1e-5 }) .collect(); - let posemb = self.heads.keypoint_posemb(&feedback.kp2d_cropped); + let posemb = self.step_heads.keypoint_posemb(&feedback.kp2d_cropped)?; let mut sampled = vec![0.0f32; NUM_KEYPOINTS * DINO_DIM]; for (index, point) in feedback.kp2d_cropped.chunks_exact(2).enumerate() { if valid[index] { @@ -502,7 +505,7 @@ impl Decoder { .copy_from_slice(&value); } } - let features = self.heads.keypoint_features(&sampled); + let features = self.step_heads.keypoint_features(&sampled)?; let hip9 = &feedback.kp3d[9 * 3..10 * 3]; let hip10 = &feedback.kp3d[10 * 3..11 * 3]; @@ -517,7 +520,7 @@ impl Decoder { point[axis] -= pelvis[axis]; } } - let posemb3d = self.heads.keypoint3d_posemb(¢ered); + let posemb3d = self.step_heads.keypoint3d_posemb(¢ered)?; let mut delta = vec![0.0f32; TOKEN_ROWS * DEC_DIM]; for index in 0..NUM_KEYPOINTS { diff --git a/libs/ai/models/body/src/fixture.rs b/libs/ai/models/body/src/fixture.rs index 0f83a3a09..2b86fbfe4 100644 --- a/libs/ai/models/body/src/fixture.rs +++ b/libs/ai/models/body/src/fixture.rs @@ -1,7 +1,6 @@ //! Optional oracle fixture reader used only by tests. use std::path::{Path, PathBuf}; -use std::sync::OnceLock; use crate::mhr::MhrRig; use crate::weights::BodyWeights; @@ -50,26 +49,24 @@ pub fn weights_path() -> Option { path.is_file().then_some(path) } -pub fn rig() -> Option<&'static MhrRig> { - static RIG: OnceLock> = OnceLock::new(); - RIG.get_or_init(|| { - let path = weights_path()?; - let weights = match BodyWeights::load(path) { - Ok(weights) => weights, - Err(err) => { - eprintln!("fixture rig: weights failed to load: {err:?}"); - return None; - } - }; - match MhrRig::load(&weights) { - Ok(rig) => Some(rig), - Err(err) => { - eprintln!("fixture rig: MHR rig failed to load: {err:?}"); - None - } +/// The rig loaded from the weights (a fresh load each call: the rig holds +/// GPU tensors, which cannot sit in a static). +pub fn rig() -> Option { + let path = weights_path()?; + let weights = match BodyWeights::load(path) { + Ok(weights) => weights, + Err(err) => { + eprintln!("fixture rig: weights failed to load: {err:?}"); + return None; } - }) - .as_ref() + }; + match MhrRig::load(&weights) { + Ok(rig) => Some(rig), + Err(err) => { + eprintln!("fixture rig: MHR rig failed to load: {err:?}"); + None + } + } } /// The GPU tests need a device AND the layer-norm op family; a build without diff --git a/libs/ai/models/body/src/heads.rs b/libs/ai/models/body/src/heads.rs index f343f75ec..f5690f8f0 100644 --- a/libs/ai/models/body/src/heads.rs +++ b/libs/ai/models/body/src/heads.rs @@ -1,7 +1,12 @@ -//! Host-side decoder heads and refinement embeddings. +//! Decoder heads and refinement embeddings: host copies (tests, token +//! assembly) and GPU-resident copies for the per-step work, where the +//! 70-row FFNs are the whole cost of a refinement step on the host. +use crate::backend::{ + gpu_birefnet_relu, gpu_download, gpu_linear_f32_resident, gpu_upload, GpuTensor, +}; use crate::weights::BodyWeights; -use crate::{DEC_DIM, DINO_DIM, NCAM, NPOSE, Result}; +use crate::{DiffusionError, DEC_DIM, DINO_DIM, NCAM, NPOSE, Result}; #[derive(Clone)] pub(crate) struct HostLinear { @@ -204,6 +209,105 @@ impl DecoderHeads { } } +/// A linear layer resident on the GPU, applied to host rows. +pub(crate) struct GpuLinearRows { + weight: GpuTensor, + bias: GpuTensor, + input: usize, + output: usize, +} + +impl GpuLinearRows { + pub(crate) fn upload(linear: &HostLinear) -> Result { + Ok(Self { + weight: gpu_upload(&linear.weight, linear.output, linear.input) + .map_err(DiffusionError::model)?, + bias: gpu_upload(&linear.bias, 1, linear.output).map_err(DiffusionError::model)?, + input: linear.input, + output: linear.output, + }) + } + + pub(crate) fn forward(&self, input: &GpuTensor) -> Result { + gpu_linear_f32_resident(input, &self.weight, Some(&self.bias)).map_err(DiffusionError::model) + } + + pub(crate) fn forward_rows(&self, input: &[f32]) -> Result> { + debug_assert_eq!(input.len() % self.input, 0); + let rows = input.len() / self.input; + let x = gpu_upload(input, rows, self.input).map_err(DiffusionError::model)?; + let y = self.forward(&x)?; + debug_assert_eq!(y.cols(), self.output); + gpu_download(&y).map_err(DiffusionError::model) + } +} + +pub(crate) struct GpuReluFfn { + first: GpuLinearRows, + second: GpuLinearRows, +} + +impl GpuReluFfn { + pub(crate) fn upload(ffn: &ReluFfn) -> Result { + Ok(Self { + first: GpuLinearRows::upload(&ffn.first)?, + second: GpuLinearRows::upload(&ffn.second)?, + }) + } + + pub(crate) fn forward_rows(&self, input: &[f32]) -> Result> { + debug_assert_eq!(input.len() % self.first.input, 0); + let rows = input.len() / self.first.input; + let x = gpu_upload(input, rows, self.first.input).map_err(DiffusionError::model)?; + let h = self.first.forward(&x)?; + let h = gpu_birefnet_relu(&h).map_err(DiffusionError::model)?; + let y = self.second.forward(&h)?; + gpu_download(&y).map_err(DiffusionError::model) + } +} + +/// The per-step heads on the GPU: pose and camera on the normalised pose +/// token, and the three refinement embeddings over the 70 keypoint rows. +pub(crate) struct GpuStepHeads { + pose: GpuReluFfn, + camera: GpuReluFfn, + keypoint_posemb: GpuReluFfn, + keypoint3d_posemb: GpuReluFfn, + keypoint_feat: GpuLinearRows, +} + +impl GpuStepHeads { + pub(crate) fn upload(heads: &DecoderHeads) -> Result { + Ok(Self { + pose: GpuReluFfn::upload(&heads.pose)?, + camera: GpuReluFfn::upload(&heads.camera)?, + keypoint_posemb: GpuReluFfn::upload(&heads.keypoint_posemb)?, + keypoint3d_posemb: GpuReluFfn::upload(&heads.keypoint3d_posemb)?, + keypoint_feat: GpuLinearRows::upload(&heads.keypoint_feat)?, + }) + } + + pub(crate) fn pose(&self, input: &[f32]) -> Result> { + self.pose.forward_rows(input) + } + + pub(crate) fn camera(&self, input: &[f32]) -> Result> { + self.camera.forward_rows(input) + } + + pub(crate) fn keypoint_posemb(&self, input: &[f32]) -> Result> { + self.keypoint_posemb.forward_rows(input) + } + + pub(crate) fn keypoint3d_posemb(&self, input: &[f32]) -> Result> { + self.keypoint3d_posemb.forward_rows(input) + } + + pub(crate) fn keypoint_features(&self, input: &[f32]) -> Result> { + self.keypoint_feat.forward_rows(input) + } +} + fn relu_in_place(values: &mut [f32]) { for value in values { *value = value.max(0.0); diff --git a/libs/ai/models/body/src/mhr.rs b/libs/ai/models/body/src/mhr.rs index e242f3a71..d5f303232 100644 --- a/libs/ai/models/body/src/mhr.rs +++ b/libs/ai/models/body/src/mhr.rs @@ -1,5 +1,9 @@ -//! CPU implementation of the Momentum Human Rig forward pass. +//! The Momentum Human Rig forward pass: kinematics, skinning and keypoint +//! regression on the CPU (small), the two dense products — identity +//! blendshapes and the pose-corrective output layer — on the GPU when one is +//! prepared, since they are the whole cost of a rig evaluation. +use crate::backend::{gpu_download, gpu_linear_f32_resident, gpu_upload, GpuTensor}; use crate::weights::BodyWeights; use crate::{ DiffusionError, Result, MHR_JOINTS, MHR_JOINT_PARAMS, MHR_KEYPOINTS_ALL, @@ -47,6 +51,15 @@ pub struct MhrRig { keypoint_row_offsets: Vec, keypoint_columns: Vec, keypoint_values: Vec, + gpu: Option, +} + +/// The rig's two dense matrices, resident on the GPU as linear layers: +/// identity blendshapes as `[55317, 45]` (basis transposed) and the pose +/// corrective output layer as `[55317, 3000]`. +struct MhrGpu { + identity_w: GpuTensor, + corrective_w: GpuTensor, } #[derive(Clone, Debug)] @@ -170,20 +183,62 @@ impl MhrRig { keypoint_row_offsets, keypoint_columns, keypoint_values, + gpu: None, }) } + /// Put the two dense products on the GPU. Without this the rig runs + /// entirely on the host (tests, tools); the results are the same. + pub fn prepare_gpu(&mut self) -> Result<()> { + let vertex_values = MHR_VERTS * XYZ; + let mut identity_t = vec![0.0f32; vertex_values * NUM_SHAPE]; + for basis in 0..NUM_SHAPE { + let source = &self.identity_basis[basis * vertex_values..(basis + 1) * vertex_values]; + for (row, &value) in source.iter().enumerate() { + identity_t[row * NUM_SHAPE + basis] = value; + } + } + let identity_w = gpu_upload(&identity_t, vertex_values, NUM_SHAPE).map_err(DiffusionError::model)?; + let corrective_w = gpu_upload(&self.pose_corr_weight, vertex_values, POSE_HIDDEN) + .map_err(DiffusionError::model)?; + self.gpu = Some(MhrGpu { + identity_w, + corrective_w, + }); + Ok(()) + } + + pub fn gpu_prepared(&self) -> bool { + self.gpu.is_some() + } + /// Build unposed vertices in rig-space centimetres. pub fn rest_vertices(&self, identity: &[f32; 45], expr: &[f32; 72]) -> Vec { let vertex_values = MHR_VERTS * XYZ; let mut output = self.base_shape.clone(); - for (basis, &coefficient) in identity.iter().enumerate() { - if coefficient == 0.0 { - continue; + let mut identity_done = false; + if let Some(gpu) = &self.gpu { + if let Ok(delta) = gpu_upload(identity, 1, NUM_SHAPE) + .and_then(|coeffs| gpu_linear_f32_resident(&coeffs, &gpu.identity_w, None)) + .and_then(|delta| gpu_download(&delta)) + { + if delta.len() == vertex_values { + for (target, value) in output.iter_mut().zip(delta) { + *target += value; + } + identity_done = true; + } } - let source = &self.identity_basis[basis * vertex_values..(basis + 1) * vertex_values]; - for (target, &value) in output.iter_mut().zip(source) { - *target += coefficient * value; + } + if !identity_done { + for (basis, &coefficient) in identity.iter().enumerate() { + if coefficient == 0.0 { + continue; + } + let source = &self.identity_basis[basis * vertex_values..(basis + 1) * vertex_values]; + for (target, &value) in output.iter_mut().zip(source) { + *target += coefficient * value; + } } } for (basis, &coefficient) in expr.iter().enumerate() { @@ -284,6 +339,16 @@ impl MhrRig { *value = value.max(0.0); } + if let Some(gpu) = &self.gpu { + if let Ok(output) = gpu_upload(&hidden, 1, POSE_HIDDEN) + .and_then(|h| gpu_linear_f32_resident(&h, &gpu.corrective_w, None)) + .and_then(|out| gpu_download(&out)) + { + if output.len() == MHR_VERTS * XYZ { + return output; + } + } + } let mut output = vec![0.0; MHR_VERTS * XYZ]; for (row, target) in output.iter_mut().enumerate() { let weights = &self.pose_corr_weight[row * POSE_HIDDEN..(row + 1) * POSE_HIDDEN]; @@ -296,14 +361,21 @@ impl MhrRig { pub fn skin(&self, skel_state: &[f32], rest: &[f32]) -> Vec { assert_eq!(skel_state.len(), MHR_JOINTS * STATE_WIDTH); assert_eq!(rest.len(), MHR_VERTS * XYZ); + // One skinning transform per joint, not per influence. + let transforms: Vec = (0..MHR_JOINTS) + .map(|joint| { + compose( + read_transform(skel_state, joint), + read_transform(&self.lbs_inverse_bind_pose, joint), + ) + }) + .collect(); let mut output = vec![0.0; MHR_VERTS * XYZ]; let mut touched = vec![false; MHR_VERTS]; for entry in 0..LBS_ENTRIES { let vertex = self.lbs_vert_indices[entry] as usize; let joint = self.lbs_skin_indices[entry] as usize; - let global = read_transform(skel_state, joint); - let inverse_bind = read_transform(&self.lbs_inverse_bind_pose, joint); - let transform = compose(global, inverse_bind); + let transform = transforms[joint]; let point = [rest[vertex * 3], rest[vertex * 3 + 1], rest[vertex * 3 + 2]]; let posed = apply(transform, point); let weight = self.lbs_skin_weights[entry]; diff --git a/libs/ai/models/body/src/model.rs b/libs/ai/models/body/src/model.rs index 9248717ca..09b30d226 100644 --- a/libs/ai/models/body/src/model.rs +++ b/libs/ai/models/body/src/model.rs @@ -61,7 +61,8 @@ impl BodyModel { let mut no_mask_embed = [0.0f32; DINO_DIM]; no_mask_embed.copy_from_slice(&no_mask); let decoder = Decoder::load(&weights)?; - let rig = MhrRig::load(&weights)?; + let mut rig = MhrRig::load(&weights)?; + rig.prepare_gpu()?; Ok(Self { weights, dino, diff --git a/libs/ai/models/body/src/pose.rs b/libs/ai/models/body/src/pose.rs index f0663453e..dc17f50d2 100644 --- a/libs/ai/models/body/src/pose.rs +++ b/libs/ai/models/body/src/pose.rs @@ -465,7 +465,7 @@ mod tests { assert!(max_abs(&pose.hands, &expected_hands) <= 1.0e-4); let rig = fixture::rig().expect("oracle rig must load after weights check"); - let model = model_params(rig, &pose); + let model = model_params(&rig, &pose); let model_error = max_abs(&model, &expected_params); eprintln!("pose oracle MHR parameter max abs error {model_error:.7}"); assert!(model_error <= 1.0e-4); From b22259b5429b2376dbb7b40a8e831306f39e9bbb Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 23:13:46 +0200 Subject: [PATCH 025/417] ai-body: the context stays on the GPU; only the pose token leaves the loop The ray-conditioning conv used to download the 1024 x 1280 embedding, concatenate the 99 ray features on the host and upload the result; it is now two resident linears over the two column blocks with the no-mask term folded into the bias, plus an add (32 ms -> a few on the 4090). The decoder loop downloaded the whole normalised token block every layer for its one pose row; it now slices that row and fetches the block once at the end (or per layer under a trace). Same numbers. Co-Authored-By: Claude Fable 5.1 --- libs/ai/models/body/src/condition.rs | 53 +++++++++++++++++----------- libs/ai/models/body/src/decoder.rs | 16 +++++++-- 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/libs/ai/models/body/src/condition.rs b/libs/ai/models/body/src/condition.rs index ede5af6aa..26418dc18 100644 --- a/libs/ai/models/body/src/condition.rs +++ b/libs/ai/models/body/src/condition.rs @@ -1,7 +1,7 @@ //! Dense image positional encoding and ray-conditioned decoder context. use crate::backend::{ - gpu_download, gpu_layer_norm_mul_add, gpu_linear_f32_resident, gpu_upload, GpuTensor, + gpu_add, gpu_layer_norm_mul_add, gpu_linear_f32_resident, gpu_upload, GpuTensor, }; use crate::weights::BodyWeights; use crate::{DiffusionError, Result, DEC_NORM_EPS, DINO_DIM, NUM_PATCHES, PATCHES_SIDE}; @@ -47,8 +47,15 @@ pub fn ray_features(rays: &[f32]) -> Vec { output } +/// The 1x1 conv over `[E + no_mask | ray features]` split into its two +/// column blocks, `W_e` (1280 wide) and `W_f` (99 wide), so the context is +/// `W_e E + (W_f feats + W_e no_mask)`: two resident linears and an add, +/// no host round trip of the 1024 x 1280 embedding. The `W_e no_mask` term +/// is a constant and lives in the second linear's bias. pub struct RayCond { - pub conv_w: GpuTensor, + image_w: GpuTensor, + ray_w: GpuTensor, + image_w_host: Vec, pub norm_w: Vec, pub norm_b: Vec, } @@ -59,9 +66,19 @@ impl RayCond { "ray_cond_emb.conv.weight", &[DINO_DIM, DINO_DIM + RAY_FEATURES, 1, 1], )?; + let cols = DINO_DIM + RAY_FEATURES; + let mut image_w = vec![0.0f32; DINO_DIM * DINO_DIM]; + let mut ray_w = vec![0.0f32; DINO_DIM * RAY_FEATURES]; + for out in 0..DINO_DIM { + image_w[out * DINO_DIM..(out + 1) * DINO_DIM] + .copy_from_slice(&conv[out * cols..out * cols + DINO_DIM]); + ray_w[out * RAY_FEATURES..(out + 1) * RAY_FEATURES] + .copy_from_slice(&conv[out * cols + DINO_DIM..(out + 1) * cols]); + } Ok(Self { - conv_w: gpu_upload(&conv, DINO_DIM, DINO_DIM + RAY_FEATURES) - .map_err(DiffusionError::model)?, + image_w: gpu_upload(&image_w, DINO_DIM, DINO_DIM).map_err(DiffusionError::model)?, + ray_w: gpu_upload(&ray_w, DINO_DIM, RAY_FEATURES).map_err(DiffusionError::model)?, + image_w_host: image_w, norm_w: weights.f32_shaped("ray_cond_emb.norm.weight", &[DINO_DIM])?, norm_b: weights.f32_shaped("ray_cond_emb.norm.bias", &[DINO_DIM])?, }) @@ -87,24 +104,18 @@ impl RayCond { NUM_PATCHES * RAY_FEATURES ))); } - - // Host assembly avoids requiring a device-specific broadcast/concat - // path; the convolution and normalization remain device-resident. - let image = gpu_download(e).map_err(DiffusionError::model)?; - let cols = DINO_DIM + RAY_FEATURES; - let mut joined = vec![0.0f32; NUM_PATCHES * cols]; - for row in 0..NUM_PATCHES { - let dst = &mut joined[row * cols..(row + 1) * cols]; - for c in 0..DINO_DIM { - dst[c] = image[row * DINO_DIM + c] + no_mask_embed[c]; - } - dst[DINO_DIM..].copy_from_slice( - &feats[row * RAY_FEATURES..(row + 1) * RAY_FEATURES], - ); + // W_e no_mask: 1.6M multiply-adds on the host, once per frame. + let mut bias = vec![0.0f32; DINO_DIM]; + for (out, value) in bias.iter_mut().enumerate() { + let row = &self.image_w_host[out * DINO_DIM..(out + 1) * DINO_DIM]; + *value = row.iter().zip(no_mask_embed).map(|(w, m)| w * m).sum(); } - let joined = gpu_upload(&joined, NUM_PATCHES, cols).map_err(DiffusionError::model)?; - let projected = gpu_linear_f32_resident(&joined, &self.conv_w, None) - .map_err(DiffusionError::model)?; + let bias = gpu_upload(&bias, 1, DINO_DIM).map_err(DiffusionError::model)?; + let feats = gpu_upload(feats, NUM_PATCHES, RAY_FEATURES).map_err(DiffusionError::model)?; + let from_image = gpu_linear_f32_resident(e, &self.image_w, None).map_err(DiffusionError::model)?; + let from_rays = + gpu_linear_f32_resident(&feats, &self.ray_w, Some(&bias)).map_err(DiffusionError::model)?; + let projected = gpu_add(&from_image, &from_rays).map_err(DiffusionError::model)?; gpu_layer_norm_mul_add(&projected, &self.norm_w, &self.norm_b, DEC_NORM_EPS) .map_err(DiffusionError::model) } diff --git a/libs/ai/models/body/src/decoder.rs b/libs/ai/models/body/src/decoder.rs index 980a0cec3..e498df284 100644 --- a/libs/ai/models/body/src/decoder.rs +++ b/libs/ai/models/body/src/decoder.rs @@ -2,7 +2,7 @@ use crate::backend::{ gpu_add, gpu_attention_packed_cross, gpu_download, gpu_gelu_erf, - gpu_layer_norm_mul_add, gpu_linear_f32_resident, gpu_upload, GpuTensor, + gpu_layer_norm_mul_add, gpu_linear_f32_resident, gpu_slice_rows, gpu_upload, GpuTensor, }; use crate::heads::{DecoderHeads, GpuStepHeads, HostLinear}; use crate::weights::BodyWeights; @@ -418,11 +418,21 @@ impl Decoder { hidden = gpu_add(&hidden, &ffn).map_err(DiffusionError::model)?; let normed = layer_norm_gpu(&hidden, &self.norm_final)?; - final_normed = gpu_download(&normed).map_err(DiffusionError::model)?; + // Only the pose token leaves the GPU mid-loop; the whole block + // is downloaded once at the end (the hand-box rows and the + // output) or when a trace wants every layer. + let last_layer = layer_index + 1 == DEC_DEPTH; + let pose_row = if last_layer || trace.is_some() { + final_normed = gpu_download(&normed).map_err(DiffusionError::model)?; + final_normed[..DEC_DIM].to_vec() + } else { + let row = gpu_slice_rows(&normed, 0, 1).map_err(DiffusionError::model)?; + gpu_download(&row).map_err(DiffusionError::model)? + }; if let Some(callback) = &mut trace { (**callback)(layer_index, &hidden, &final_normed)?; } - let pose_token = &final_normed[..DEC_DIM]; + let pose_token = &pose_row[..DEC_DIM]; last_pose = self.step_heads.pose(pose_token)?; add_in_place(&mut last_pose, &self.init_pose); last_camera = self.step_heads.camera(pose_token)?; From 346f31f8c45676d4406cf43b25447c66be737b3f Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 23:15:56 +0200 Subject: [PATCH 026/417] ai-body: flash attention for the head-dim-64 blocks The backbone (20 heads) and the decoder (8 heads) both have 64-wide heads, which the stack's FA2 kernel covers: f16 operands with f32 softmax and accumulation, the reference's own precision class, instead of the composite path that materialises the 1029 x 1029 scores per head. The composite path stays as the fallback where a backend lacks the kernel. Oracle parity unchanged. Co-Authored-By: Claude Fable 5.1 --- libs/ai/models/body/src/decoder.rs | 12 ++---------- libs/ai/models/body/src/dino.rs | 21 ++++++++++++++++++--- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/libs/ai/models/body/src/decoder.rs b/libs/ai/models/body/src/decoder.rs index e498df284..64b149d0e 100644 --- a/libs/ai/models/body/src/decoder.rs +++ b/libs/ai/models/body/src/decoder.rs @@ -1,7 +1,7 @@ //! Promptable body-pose decoder and its six-step refinement loop. use crate::backend::{ - gpu_add, gpu_attention_packed_cross, gpu_download, gpu_gelu_erf, + gpu_add, gpu_download, gpu_gelu_erf, gpu_layer_norm_mul_add, gpu_linear_f32_resident, gpu_slice_rows, gpu_upload, GpuTensor, }; use crate::heads::{DecoderHeads, GpuStepHeads, HostLinear}; @@ -14,7 +14,6 @@ use crate::{ pub const TOKEN_ROWS: usize = 5 + 2 * NUM_KEYPOINTS; const KEYPOINT_ROW: usize = 5; const KEYPOINT3D_ROW: usize = KEYPOINT_ROW + NUM_KEYPOINTS; -const ATTN_SCALE: f32 = 0.125; #[derive(Clone)] struct NormWeights { @@ -248,14 +247,7 @@ impl GpuAttention { let query = self.q.forward(query)?; let key = self.k.forward(key)?; let value = self.v.forward(value)?; - let attended = gpu_attention_packed_cross( - &query, - &key, - &value, - DEC_HEADS, - ATTN_SCALE, - ) - .map_err(DiffusionError::model)?; + let attended = crate::dino::attention_d64(&query, &key, &value, DEC_HEADS)?; self.out.forward(&attended) } } diff --git a/libs/ai/models/body/src/dino.rs b/libs/ai/models/body/src/dino.rs index 495072324..104db077f 100644 --- a/libs/ai/models/body/src/dino.rs +++ b/libs/ai/models/body/src/dino.rs @@ -5,7 +5,8 @@ //! LayerScale is folded into the output projection rows and biases at load. use crate::backend::{ - gpu_add, gpu_attention_packed_cross, gpu_concat_rows_many, gpu_download, + gpu_add, gpu_attention_packed_cross, gpu_attention_packed_flash2_d64, gpu_concat_rows_many, + gpu_download, gpu_layer_norm_mul_add, gpu_linear_nt_cached_bf16_f32acc, gpu_mul, gpu_rope_half, gpu_silu, gpu_slice_rows, gpu_upload, GpuLinearPart, GpuTensor, }; @@ -163,6 +164,21 @@ fn f32_to_bf16_bytes(values: &[f32]) -> Vec { bytes } +/// Head-dim-64 attention: the FA2 flash kernel (f16 operands, f32 softmax +/// and accumulation — the reference's own precision class) where the +/// backend has it, else the composite f32 path. +pub(crate) fn attention_d64( + q: &GpuTensor, + k: &GpuTensor, + v: &GpuTensor, + heads: usize, +) -> Result { + match gpu_attention_packed_flash2_d64(q, k, v, heads, 0.125) { + Ok(out) => Ok(out), + Err(_) => gpu_attention_packed_cross(q, k, v, heads, 0.125).map_err(DiffusionError::model), + } +} + impl BodyDino { pub fn prepare(weights: &BodyWeights) -> Result { Self::prepare_with_progress(weights, None) @@ -336,8 +352,7 @@ impl BodyDino { .map_err(DiffusionError::model)?; let k = gpu_rope_half(&k, DINO_HEADS, ROPE_HALF, &cos, &sin) .map_err(DiffusionError::model)?; - let attention = gpu_attention_packed_cross(&q, &k, &v, DINO_HEADS, 0.125) - .map_err(DiffusionError::model)?; + let attention = attention_d64(&q, &k, &v, DINO_HEADS)?; let attention = layer.out.forward(&attention)?; hidden = gpu_add(&hidden, &attention).map_err(DiffusionError::model)?; From 0fd356dbf06aeb928100cc27a53439f62a72d5ae Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 23:32:35 +0200 Subject: [PATCH 027/417] windows: the vendored bindings are generated from a checked-in filter libs/windows/windows-rs/src/Windows/mod.rs was a hand-pruned snapshot with no recipe behind it; adding a WinRT namespace meant hand-copying vtables. Now tools/windows_bindgen (standalone, windows-bindgen 0.62.1) regenerates it from filter.txt: package mode with the COM `_Impl` traits, Win32 imports linked through windows_core, upstream's 800-column rustfmt (the repo-root rustfmt.toml disables formatting and has to be overridden), the filter closed over every dependency the generator would otherwise skip a member for, the namespace tree folded into one file with every feature gate kept, and the two spots where the published 0.62.1 generator predates the vendored core 0.62.2 normalized (Error::from_thread, imp::array_proxy). The filter is the old file's item list plus Windows.Globalization.Language, Windows.Media.SpeechRecognition and Windows.Media.SpeechSynthesis for the OS speech engines. The generated `deprecated` gate is declared as a feature. Checked on x86_64-pc-windows-msvc: platform, video, network, mpterm, system-speech. Co-Authored-By: Claude Fable 5.1 --- libs/windows/windows-rs/Cargo.toml | 3 + libs/windows/windows-rs/src/Windows/mod.rs | 92789 ++++++++++++++++++- tools/windows_bindgen/Cargo.toml | 13 + tools/windows_bindgen/filter.txt | 2213 + tools/windows_bindgen/src/main.rs | 240 + 5 files changed, 94256 insertions(+), 1002 deletions(-) create mode 100644 tools/windows_bindgen/Cargo.toml create mode 100644 tools/windows_bindgen/filter.txt create mode 100644 tools/windows_bindgen/src/main.rs diff --git a/libs/windows/windows-rs/Cargo.toml b/libs/windows/windows-rs/Cargo.toml index a3dec6a9c..0da6d5ff7 100644 --- a/libs/windows/windows-rs/Cargo.toml +++ b/libs/windows/windows-rs/Cargo.toml @@ -709,6 +709,9 @@ Win32_UI_Wpf = ["Win32_UI"] Win32_Web = ["Win32"] Win32_Web_InternetExplorer = ["Win32_Web"] default = ["std"] +# Deprecated Win32/WinRT members are generated behind this gate (windows-bindgen +# emits `#[cfg(feature = "deprecated")]` on them); nothing in the repo turns it on. +deprecated = [] docs = [] std = [ "windows-core/std", diff --git a/libs/windows/windows-rs/src/Windows/mod.rs b/libs/windows/windows-rs/src/Windows/mod.rs index 9d975d4e9..cd140a65b 100644 --- a/libs/windows/windows-rs/src/Windows/mod.rs +++ b/libs/windows/windows-rs/src/Windows/mod.rs @@ -1,4 +1,6 @@ +#[cfg(feature = "ApplicationModel")] pub mod ApplicationModel{ +#[cfg(feature = "ApplicationModel_Background")] pub mod Background{ #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] @@ -6,6 +8,36 @@ pub struct ActivitySensorTrigger(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(ActivitySensorTrigger, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(ActivitySensorTrigger, IBackgroundTrigger); impl ActivitySensorTrigger { + #[cfg(feature = "Devices_Sensors")] + pub fn SubscribedActivities(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SubscribedActivities)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Devices_Sensors")] + pub fn SupportedActivities(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedActivities)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MinimumReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinimumReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Create(reportintervalinmilliseconds: u32) -> windows_core::Result { Self::IActivitySensorTriggerFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -35,6 +67,26 @@ pub struct AppBroadcastTrigger(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(AppBroadcastTrigger, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(AppBroadcastTrigger, IBackgroundTrigger); impl AppBroadcastTrigger { + pub fn SetProviderInfo(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetProviderInfo)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn ProviderInfo(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProviderInfo)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateAppBroadcastTrigger(providerkey: &windows_core::HSTRING) -> windows_core::Result { + Self::IAppBroadcastTriggerFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateAppBroadcastTrigger)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(providerkey), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IAppBroadcastTriggerFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -56,6 +108,74 @@ unsafe impl Sync for AppBroadcastTrigger {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct AppBroadcastTriggerProviderInfo(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(AppBroadcastTriggerProviderInfo, windows_core::IUnknown, windows_core::IInspectable); +impl AppBroadcastTriggerProviderInfo { + pub fn SetDisplayNameResource(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDisplayNameResource)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn DisplayNameResource(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayNameResource)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetLogoResource(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetLogoResource)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn LogoResource(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LogoResource)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetVideoKeyFrameInterval(&self, value: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetVideoKeyFrameInterval)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn VideoKeyFrameInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).VideoKeyFrameInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetMaxVideoBitrate(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMaxVideoBitrate)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn MaxVideoBitrate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxVideoBitrate)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetMaxVideoWidth(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMaxVideoWidth)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn MaxVideoWidth(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxVideoWidth)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetMaxVideoHeight(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMaxVideoHeight)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn MaxVideoHeight(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxVideoHeight)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for AppBroadcastTriggerProviderInfo { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -81,7 +201,25 @@ impl ApplicationTrigger { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn RequestAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + #[cfg(feature = "Foundation_Collections")] + pub fn RequestAsyncWithArguments(&self, arguments: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestAsyncWithArguments)(windows_core::Interface::as_raw(this), arguments.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for ApplicationTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -148,7 +286,62 @@ impl BluetoothLEAdvertisementPublisherTrigger { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + #[cfg(feature = "Devices_Bluetooth_Advertisement")] + pub fn Advertisement(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Advertisement)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn PreferredTransmitPowerLevelInDBm(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PreferredTransmitPowerLevelInDBm)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetPreferredTransmitPowerLevelInDBm(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetPreferredTransmitPowerLevelInDBm)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn UseExtendedFormat(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UseExtendedFormat)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetUseExtendedFormat(&self, value: bool) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetUseExtendedFormat)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn IsAnonymous(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsAnonymous)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetIsAnonymous(&self, value: bool) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetIsAnonymous)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn IncludeTransmitPowerLevel(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IncludeTransmitPowerLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetIncludeTransmitPowerLevel(&self, value: bool) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetIncludeTransmitPowerLevel)(windows_core::Interface::as_raw(this), value).ok() } + } +} impl windows_core::RuntimeType for BluetoothLEAdvertisementPublisherTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -174,7 +367,78 @@ impl BluetoothLEAdvertisementWatcherTrigger { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn MinSamplingInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinSamplingInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } + pub fn MaxSamplingInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxSamplingInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MinOutOfRangeTimeout(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinOutOfRangeTimeout)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaxOutOfRangeTimeout(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxOutOfRangeTimeout)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Devices_Bluetooth")] + pub fn SignalStrengthFilter(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SignalStrengthFilter)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Devices_Bluetooth")] + pub fn SetSignalStrengthFilter(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSignalStrengthFilter)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + #[cfg(feature = "Devices_Bluetooth_Advertisement")] + pub fn AdvertisementFilter(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AdvertisementFilter)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Devices_Bluetooth_Advertisement")] + pub fn SetAdvertisementFilter(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAdvertisementFilter)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn AllowExtendedAdvertisements(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AllowExtendedAdvertisements)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAllowExtendedAdvertisements(&self, value: bool) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAllowExtendedAdvertisements)(windows_core::Interface::as_raw(this), value).ok() } + } +} impl windows_core::RuntimeType for BluetoothLEAdvertisementWatcherTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -330,6 +594,13 @@ impl ContentPrefetchTrigger { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn WaitInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WaitInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Create(waitinterval: super::super::Foundation::TimeSpan) -> windows_core::Result { Self::IContentPrefetchTriggerFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -380,6 +651,20 @@ pub struct CustomSystemEventTrigger(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(CustomSystemEventTrigger, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(CustomSystemEventTrigger, IBackgroundTrigger); impl CustomSystemEventTrigger { + pub fn TriggerId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TriggerId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Recurrence(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Recurrence)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Create(triggerid: &windows_core::HSTRING, recurrence: CustomSystemEventTriggerRecurrence) -> windows_core::Result { Self::ICustomSystemEventTriggerFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -420,6 +705,31 @@ pub struct DeviceConnectionChangeTrigger(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(DeviceConnectionChangeTrigger, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(DeviceConnectionChangeTrigger, IBackgroundTrigger); impl DeviceConnectionChangeTrigger { + pub fn DeviceId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn CanMaintainConnection(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanMaintainConnection)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaintainConnection(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaintainConnection)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetMaintainConnection(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMaintainConnection)(windows_core::Interface::as_raw(this), value).ok() } + } pub fn FromIdAsync(deviceid: &windows_core::HSTRING) -> windows_core::Result> { Self::IDeviceConnectionChangeTriggerStatics(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -443,12 +753,30 @@ impl windows_core::RuntimeName for DeviceConnectionChangeTrigger { } unsafe impl Send for DeviceConnectionChangeTrigger {} unsafe impl Sync for DeviceConnectionChangeTrigger {} +#[cfg(feature = "deprecated")] #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] pub struct DeviceManufacturerNotificationTrigger(windows_core::IUnknown); +#[cfg(feature = "deprecated")] windows_core::imp::interface_hierarchy!(DeviceManufacturerNotificationTrigger, windows_core::IUnknown, windows_core::IInspectable); +#[cfg(feature = "deprecated")] windows_core::imp::required_hierarchy!(DeviceManufacturerNotificationTrigger, IBackgroundTrigger); +#[cfg(feature = "deprecated")] impl DeviceManufacturerNotificationTrigger { + pub fn TriggerQualifier(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TriggerQualifier)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn OneShot(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OneShot)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Create(triggerqualifier: &windows_core::HSTRING, oneshot: bool) -> windows_core::Result { Self::IDeviceManufacturerNotificationTriggerFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -460,13 +788,16 @@ impl DeviceManufacturerNotificationTrigger { SHARED.call(callback) } } +#[cfg(feature = "deprecated")] impl windows_core::RuntimeType for DeviceManufacturerNotificationTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } +#[cfg(feature = "deprecated")] unsafe impl windows_core::Interface for DeviceManufacturerNotificationTrigger { type Vtable = ::Vtable; const IID: windows_core::GUID = ::IID; } +#[cfg(feature = "deprecated")] impl windows_core::RuntimeName for DeviceManufacturerNotificationTrigger { const NAME: &'static str = "Windows.ApplicationModel.Background.DeviceManufacturerNotificationTrigger"; } @@ -483,7 +814,21 @@ impl DeviceServicingTrigger { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn RequestAsyncSimple(&self, deviceid: &windows_core::HSTRING, expectedduration: super::super::Foundation::TimeSpan) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestAsyncSimple)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), expectedduration, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn RequestAsyncWithArguments(&self, deviceid: &windows_core::HSTRING, expectedduration: super::super::Foundation::TimeSpan, arguments: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestAsyncWithArguments)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), expectedduration, core::mem::transmute_copy(arguments), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for DeviceServicingTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -524,7 +869,21 @@ impl DeviceUseTrigger { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn RequestAsyncSimple(&self, deviceid: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestAsyncSimple)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn RequestAsyncWithArguments(&self, deviceid: &windows_core::HSTRING, arguments: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestAsyncWithArguments)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), core::mem::transmute_copy(arguments), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for DeviceUseTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -585,6 +944,22 @@ pub struct GattCharacteristicNotificationTrigger(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattCharacteristicNotificationTrigger, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(GattCharacteristicNotificationTrigger, IBackgroundTrigger); impl GattCharacteristicNotificationTrigger { + #[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] + pub fn Characteristic(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Characteristic)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Devices_Bluetooth_Background")] + pub fn EventTriggeringMode(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).EventTriggeringMode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] pub fn Create(characteristic: P0) -> windows_core::Result where @@ -595,6 +970,16 @@ impl GattCharacteristicNotificationTrigger { (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), characteristic.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + #[cfg(all(feature = "Devices_Bluetooth_Background", feature = "Devices_Bluetooth_GenericAttributeProfile"))] + pub fn CreateWithEventTriggeringMode(characteristic: P0, eventtriggeringmode: super::super::Devices::Bluetooth::Background::BluetoothEventTriggeringMode) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IGattCharacteristicNotificationTriggerFactory2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWithEventTriggeringMode)(windows_core::Interface::as_raw(this), characteristic.param().abi(), eventtriggeringmode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IGattCharacteristicNotificationTriggerFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -622,6 +1007,43 @@ pub struct GattServiceProviderTrigger(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattServiceProviderTrigger, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(GattServiceProviderTrigger, IBackgroundTrigger); impl GattServiceProviderTrigger { + pub fn TriggerId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TriggerId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] + pub fn Service(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Service)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] + pub fn SetAdvertisingParameters(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAdvertisingParameters)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + #[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] + pub fn AdvertisingParameters(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AdvertisingParameters)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateAsync(triggerid: &windows_core::HSTRING, serviceuuid: windows_core::GUID) -> windows_core::Result> { + Self::IGattServiceProviderTriggerStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(triggerid), serviceuuid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IGattServiceProviderTriggerStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -644,6 +1066,13 @@ unsafe impl Sync for GattServiceProviderTrigger {} pub struct GattServiceProviderTriggerResult(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattServiceProviderTriggerResult, windows_core::IUnknown, windows_core::IInspectable); impl GattServiceProviderTriggerResult { + pub fn Trigger(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Trigger)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } #[cfg(feature = "Devices_Bluetooth")] pub fn Error(&self) -> windows_core::Result { let this = self; @@ -678,7 +1107,20 @@ impl GeovisitTrigger { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + #[cfg(feature = "Devices_Geolocation")] + pub fn MonitoringScope(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MonitoringScope)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } + #[cfg(feature = "Devices_Geolocation")] + pub fn SetMonitoringScope(&self, value: super::super::Devices::Geolocation::VisitMonitoringScope) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMonitoringScope)(windows_core::Interface::as_raw(this), value).ok() } + } +} impl windows_core::RuntimeType for GeovisitTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -695,6 +1137,82 @@ windows_core::imp::define_interface!(IActivitySensorTrigger, IActivitySensorTrig impl windows_core::RuntimeType for IActivitySensorTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Sensors")] +impl windows_core::RuntimeName for IActivitySensorTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IActivitySensorTrigger"; +} +#[cfg(feature = "Devices_Sensors")] +pub trait IActivitySensorTrigger_Impl: IBackgroundTrigger_Impl { + fn SubscribedActivities(&self) -> windows_core::Result>; + fn ReportInterval(&self) -> windows_core::Result; + fn SupportedActivities(&self) -> windows_core::Result>; + fn MinimumReportInterval(&self) -> windows_core::Result; +} +#[cfg(feature = "Devices_Sensors")] +impl IActivitySensorTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SubscribedActivities(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensorTrigger_Impl::SubscribedActivities(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensorTrigger_Impl::ReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedActivities(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensorTrigger_Impl::SupportedActivities(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MinimumReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensorTrigger_Impl::MinimumReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SubscribedActivities: SubscribedActivities::, + ReportInterval: ReportInterval::, + SupportedActivities: SupportedActivities::, + MinimumReportInterval: MinimumReportInterval::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IActivitySensorTrigger_Vtbl { @@ -714,6 +1232,33 @@ windows_core::imp::define_interface!(IActivitySensorTriggerFactory, IActivitySen impl windows_core::RuntimeType for IActivitySensorTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IActivitySensorTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.IActivitySensorTriggerFactory"; +} +pub trait IActivitySensorTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, reportIntervalInMilliseconds: u32) -> windows_core::Result; +} +impl IActivitySensorTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, reportintervalinmilliseconds: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensorTriggerFactory_Impl::Create(this, reportintervalinmilliseconds) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IActivitySensorTriggerFactory_Vtbl { @@ -724,6 +1269,44 @@ windows_core::imp::define_interface!(IAppBroadcastTrigger, IAppBroadcastTrigger_ impl windows_core::RuntimeType for IAppBroadcastTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAppBroadcastTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IAppBroadcastTrigger"; +} +pub trait IAppBroadcastTrigger_Impl: IBackgroundTrigger_Impl { + fn SetProviderInfo(&self, value: windows_core::Ref<'_, AppBroadcastTriggerProviderInfo>) -> windows_core::Result<()>; + fn ProviderInfo(&self) -> windows_core::Result; +} +impl IAppBroadcastTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetProviderInfo(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAppBroadcastTrigger_Impl::SetProviderInfo(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn ProviderInfo(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAppBroadcastTrigger_Impl::ProviderInfo(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetProviderInfo: SetProviderInfo::, + ProviderInfo: ProviderInfo::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAppBroadcastTrigger_Vtbl { @@ -735,6 +1318,36 @@ windows_core::imp::define_interface!(IAppBroadcastTriggerFactory, IAppBroadcastT impl windows_core::RuntimeType for IAppBroadcastTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAppBroadcastTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.IAppBroadcastTriggerFactory"; +} +pub trait IAppBroadcastTriggerFactory_Impl: windows_core::IUnknownImpl { + fn CreateAppBroadcastTrigger(&self, providerKey: &windows_core::HSTRING) -> windows_core::Result; +} +impl IAppBroadcastTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateAppBroadcastTrigger(this: *mut core::ffi::c_void, providerkey: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAppBroadcastTriggerFactory_Impl::CreateAppBroadcastTrigger(this, core::mem::transmute(&providerkey)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateAppBroadcastTrigger: CreateAppBroadcastTrigger::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAppBroadcastTriggerFactory_Vtbl { @@ -745,6 +1358,155 @@ windows_core::imp::define_interface!(IAppBroadcastTriggerProviderInfo, IAppBroad impl windows_core::RuntimeType for IAppBroadcastTriggerProviderInfo { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAppBroadcastTriggerProviderInfo { + const NAME: &'static str = "Windows.ApplicationModel.Background.IAppBroadcastTriggerProviderInfo"; +} +pub trait IAppBroadcastTriggerProviderInfo_Impl: windows_core::IUnknownImpl { + fn SetDisplayNameResource(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn DisplayNameResource(&self) -> windows_core::Result; + fn SetLogoResource(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn LogoResource(&self) -> windows_core::Result; + fn SetVideoKeyFrameInterval(&self, value: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; + fn VideoKeyFrameInterval(&self) -> windows_core::Result; + fn SetMaxVideoBitrate(&self, value: u32) -> windows_core::Result<()>; + fn MaxVideoBitrate(&self) -> windows_core::Result; + fn SetMaxVideoWidth(&self, value: u32) -> windows_core::Result<()>; + fn MaxVideoWidth(&self) -> windows_core::Result; + fn SetMaxVideoHeight(&self, value: u32) -> windows_core::Result<()>; + fn MaxVideoHeight(&self) -> windows_core::Result; +} +impl IAppBroadcastTriggerProviderInfo_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetDisplayNameResource(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAppBroadcastTriggerProviderInfo_Impl::SetDisplayNameResource(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn DisplayNameResource(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAppBroadcastTriggerProviderInfo_Impl::DisplayNameResource(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetLogoResource(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAppBroadcastTriggerProviderInfo_Impl::SetLogoResource(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn LogoResource(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAppBroadcastTriggerProviderInfo_Impl::LogoResource(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetVideoKeyFrameInterval(this: *mut core::ffi::c_void, value: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAppBroadcastTriggerProviderInfo_Impl::SetVideoKeyFrameInterval(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn VideoKeyFrameInterval(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAppBroadcastTriggerProviderInfo_Impl::VideoKeyFrameInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMaxVideoBitrate(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAppBroadcastTriggerProviderInfo_Impl::SetMaxVideoBitrate(this, value).into() + } + } + unsafe extern "system" fn MaxVideoBitrate(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAppBroadcastTriggerProviderInfo_Impl::MaxVideoBitrate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMaxVideoWidth(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAppBroadcastTriggerProviderInfo_Impl::SetMaxVideoWidth(this, value).into() + } + } + unsafe extern "system" fn MaxVideoWidth(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAppBroadcastTriggerProviderInfo_Impl::MaxVideoWidth(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMaxVideoHeight(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAppBroadcastTriggerProviderInfo_Impl::SetMaxVideoHeight(this, value).into() + } + } + unsafe extern "system" fn MaxVideoHeight(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAppBroadcastTriggerProviderInfo_Impl::MaxVideoHeight(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetDisplayNameResource: SetDisplayNameResource::, + DisplayNameResource: DisplayNameResource::, + SetLogoResource: SetLogoResource::, + LogoResource: LogoResource::, + SetVideoKeyFrameInterval: SetVideoKeyFrameInterval::, + VideoKeyFrameInterval: VideoKeyFrameInterval::, + SetMaxVideoBitrate: SetMaxVideoBitrate::, + MaxVideoBitrate: MaxVideoBitrate::, + SetMaxVideoWidth: SetMaxVideoWidth::, + MaxVideoWidth: MaxVideoWidth::, + SetMaxVideoHeight: SetMaxVideoHeight::, + MaxVideoHeight: MaxVideoHeight::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAppBroadcastTriggerProviderInfo_Vtbl { @@ -766,6 +1528,54 @@ windows_core::imp::define_interface!(IApplicationTrigger, IApplicationTrigger_Vt impl windows_core::RuntimeType for IApplicationTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Foundation_Collections")] +impl windows_core::RuntimeName for IApplicationTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IApplicationTrigger"; +} +#[cfg(feature = "Foundation_Collections")] +pub trait IApplicationTrigger_Impl: IBackgroundTrigger_Impl { + fn RequestAsync(&self) -> windows_core::Result>; + fn RequestAsyncWithArguments(&self, arguments: windows_core::Ref<'_, super::super::Foundation::Collections::ValueSet>) -> windows_core::Result>; +} +#[cfg(feature = "Foundation_Collections")] +impl IApplicationTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn RequestAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IApplicationTrigger_Impl::RequestAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RequestAsyncWithArguments(this: *mut core::ffi::c_void, arguments: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IApplicationTrigger_Impl::RequestAsyncWithArguments(this, core::mem::transmute_copy(&arguments)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + RequestAsync: RequestAsync::, + RequestAsyncWithArguments: RequestAsyncWithArguments::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IApplicationTrigger_Vtbl { @@ -780,6 +1590,18 @@ windows_core::imp::define_interface!(IAppointmentStoreNotificationTrigger, IAppo impl windows_core::RuntimeType for IAppointmentStoreNotificationTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAppointmentStoreNotificationTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IAppointmentStoreNotificationTrigger"; +} +pub trait IAppointmentStoreNotificationTrigger_Impl: IBackgroundTrigger_Impl {} +impl IAppointmentStoreNotificationTrigger_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAppointmentStoreNotificationTrigger_Vtbl { @@ -811,6 +1633,39 @@ windows_core::imp::define_interface!(IBluetoothLEAdvertisementPublisherTrigger, impl windows_core::RuntimeType for IBluetoothLEAdvertisementPublisherTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Bluetooth_Advertisement")] +impl windows_core::RuntimeName for IBluetoothLEAdvertisementPublisherTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IBluetoothLEAdvertisementPublisherTrigger"; +} +#[cfg(feature = "Devices_Bluetooth_Advertisement")] +pub trait IBluetoothLEAdvertisementPublisherTrigger_Impl: IBackgroundTrigger_Impl { + fn Advertisement(&self) -> windows_core::Result; +} +#[cfg(feature = "Devices_Bluetooth_Advertisement")] +impl IBluetoothLEAdvertisementPublisherTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Advertisement(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementPublisherTrigger_Impl::Advertisement(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Advertisement: Advertisement::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEAdvertisementPublisherTrigger_Vtbl { @@ -824,6 +1679,110 @@ windows_core::imp::define_interface!(IBluetoothLEAdvertisementPublisherTrigger2, impl windows_core::RuntimeType for IBluetoothLEAdvertisementPublisherTrigger2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEAdvertisementPublisherTrigger2 { + const NAME: &'static str = "Windows.ApplicationModel.Background.IBluetoothLEAdvertisementPublisherTrigger2"; +} +pub trait IBluetoothLEAdvertisementPublisherTrigger2_Impl: windows_core::IUnknownImpl { + fn PreferredTransmitPowerLevelInDBm(&self) -> windows_core::Result>; + fn SetPreferredTransmitPowerLevelInDBm(&self, value: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn UseExtendedFormat(&self) -> windows_core::Result; + fn SetUseExtendedFormat(&self, value: bool) -> windows_core::Result<()>; + fn IsAnonymous(&self) -> windows_core::Result; + fn SetIsAnonymous(&self, value: bool) -> windows_core::Result<()>; + fn IncludeTransmitPowerLevel(&self) -> windows_core::Result; + fn SetIncludeTransmitPowerLevel(&self, value: bool) -> windows_core::Result<()>; +} +impl IBluetoothLEAdvertisementPublisherTrigger2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn PreferredTransmitPowerLevelInDBm(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementPublisherTrigger2_Impl::PreferredTransmitPowerLevelInDBm(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPreferredTransmitPowerLevelInDBm(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEAdvertisementPublisherTrigger2_Impl::SetPreferredTransmitPowerLevelInDBm(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn UseExtendedFormat(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementPublisherTrigger2_Impl::UseExtendedFormat(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetUseExtendedFormat(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEAdvertisementPublisherTrigger2_Impl::SetUseExtendedFormat(this, value).into() + } + } + unsafe extern "system" fn IsAnonymous(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementPublisherTrigger2_Impl::IsAnonymous(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetIsAnonymous(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEAdvertisementPublisherTrigger2_Impl::SetIsAnonymous(this, value).into() + } + } + unsafe extern "system" fn IncludeTransmitPowerLevel(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementPublisherTrigger2_Impl::IncludeTransmitPowerLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetIncludeTransmitPowerLevel(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEAdvertisementPublisherTrigger2_Impl::SetIncludeTransmitPowerLevel(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + PreferredTransmitPowerLevelInDBm: PreferredTransmitPowerLevelInDBm::, + SetPreferredTransmitPowerLevelInDBm: SetPreferredTransmitPowerLevelInDBm::, + UseExtendedFormat: UseExtendedFormat::, + SetUseExtendedFormat: SetUseExtendedFormat::, + IsAnonymous: IsAnonymous::, + SetIsAnonymous: SetIsAnonymous::, + IncludeTransmitPowerLevel: IncludeTransmitPowerLevel::, + SetIncludeTransmitPowerLevel: SetIncludeTransmitPowerLevel::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEAdvertisementPublisherTrigger2_Vtbl { @@ -837,35 +1796,130 @@ pub struct IBluetoothLEAdvertisementPublisherTrigger2_Vtbl { pub IncludeTransmitPowerLevel: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, pub SetIncludeTransmitPowerLevel: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, } -windows_core::imp::define_interface!(IBluetoothLEAdvertisementPublisherTrigger3, IBluetoothLEAdvertisementPublisherTrigger3_Vtbl, 0x64419d03_d604_5bdc_b7d2_a7fe25c55460); -impl windows_core::RuntimeType for IBluetoothLEAdvertisementPublisherTrigger3 { - const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); -} -#[repr(C)] -#[doc(hidden)] -pub struct IBluetoothLEAdvertisementPublisherTrigger3_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - #[cfg(feature = "Devices_Bluetooth_Advertisement")] - pub PrimaryPhy: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Devices::Bluetooth::Advertisement::BluetoothLEAdvertisementPhyType) -> windows_core::HRESULT, - #[cfg(not(feature = "Devices_Bluetooth_Advertisement"))] - PrimaryPhy: usize, - #[cfg(feature = "Devices_Bluetooth_Advertisement")] - pub SetPrimaryPhy: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Devices::Bluetooth::Advertisement::BluetoothLEAdvertisementPhyType) -> windows_core::HRESULT, - #[cfg(not(feature = "Devices_Bluetooth_Advertisement"))] - SetPrimaryPhy: usize, - #[cfg(feature = "Devices_Bluetooth_Advertisement")] - pub SecondaryPhy: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Devices::Bluetooth::Advertisement::BluetoothLEAdvertisementPhyType) -> windows_core::HRESULT, - #[cfg(not(feature = "Devices_Bluetooth_Advertisement"))] - SecondaryPhy: usize, - #[cfg(feature = "Devices_Bluetooth_Advertisement")] - pub SetSecondaryPhy: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Devices::Bluetooth::Advertisement::BluetoothLEAdvertisementPhyType) -> windows_core::HRESULT, - #[cfg(not(feature = "Devices_Bluetooth_Advertisement"))] - SetSecondaryPhy: usize, -} windows_core::imp::define_interface!(IBluetoothLEAdvertisementWatcherTrigger, IBluetoothLEAdvertisementWatcherTrigger_Vtbl, 0x1aab1819_bce1_48eb_a827_59fb7cee52a6); impl windows_core::RuntimeType for IBluetoothLEAdvertisementWatcherTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Bluetooth_Advertisement")] +impl windows_core::RuntimeName for IBluetoothLEAdvertisementWatcherTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IBluetoothLEAdvertisementWatcherTrigger"; +} +#[cfg(feature = "Devices_Bluetooth_Advertisement")] +pub trait IBluetoothLEAdvertisementWatcherTrigger_Impl: IBackgroundTrigger_Impl { + fn MinSamplingInterval(&self) -> windows_core::Result; + fn MaxSamplingInterval(&self) -> windows_core::Result; + fn MinOutOfRangeTimeout(&self) -> windows_core::Result; + fn MaxOutOfRangeTimeout(&self) -> windows_core::Result; + fn SignalStrengthFilter(&self) -> windows_core::Result; + fn SetSignalStrengthFilter(&self, value: windows_core::Ref<'_, super::super::Devices::Bluetooth::BluetoothSignalStrengthFilter>) -> windows_core::Result<()>; + fn AdvertisementFilter(&self) -> windows_core::Result; + fn SetAdvertisementFilter(&self, value: windows_core::Ref<'_, super::super::Devices::Bluetooth::Advertisement::BluetoothLEAdvertisementFilter>) -> windows_core::Result<()>; +} +#[cfg(feature = "Devices_Bluetooth_Advertisement")] +impl IBluetoothLEAdvertisementWatcherTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn MinSamplingInterval(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementWatcherTrigger_Impl::MinSamplingInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxSamplingInterval(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementWatcherTrigger_Impl::MaxSamplingInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MinOutOfRangeTimeout(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementWatcherTrigger_Impl::MinOutOfRangeTimeout(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxOutOfRangeTimeout(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementWatcherTrigger_Impl::MaxOutOfRangeTimeout(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SignalStrengthFilter(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementWatcherTrigger_Impl::SignalStrengthFilter(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetSignalStrengthFilter(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEAdvertisementWatcherTrigger_Impl::SetSignalStrengthFilter(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn AdvertisementFilter(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementWatcherTrigger_Impl::AdvertisementFilter(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAdvertisementFilter(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEAdvertisementWatcherTrigger_Impl::SetAdvertisementFilter(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + MinSamplingInterval: MinSamplingInterval::, + MaxSamplingInterval: MaxSamplingInterval::, + MinOutOfRangeTimeout: MinOutOfRangeTimeout::, + MaxOutOfRangeTimeout: MaxOutOfRangeTimeout::, + SignalStrengthFilter: SignalStrengthFilter::, + SetSignalStrengthFilter: SetSignalStrengthFilter::, + AdvertisementFilter: AdvertisementFilter::, + SetAdvertisementFilter: SetAdvertisementFilter::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEAdvertisementWatcherTrigger_Vtbl { @@ -895,6 +1949,43 @@ windows_core::imp::define_interface!(IBluetoothLEAdvertisementWatcherTrigger2, I impl windows_core::RuntimeType for IBluetoothLEAdvertisementWatcherTrigger2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEAdvertisementWatcherTrigger2 { + const NAME: &'static str = "Windows.ApplicationModel.Background.IBluetoothLEAdvertisementWatcherTrigger2"; +} +pub trait IBluetoothLEAdvertisementWatcherTrigger2_Impl: windows_core::IUnknownImpl { + fn AllowExtendedAdvertisements(&self) -> windows_core::Result; + fn SetAllowExtendedAdvertisements(&self, value: bool) -> windows_core::Result<()>; +} +impl IBluetoothLEAdvertisementWatcherTrigger2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AllowExtendedAdvertisements(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementWatcherTrigger2_Impl::AllowExtendedAdvertisements(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAllowExtendedAdvertisements(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEAdvertisementWatcherTrigger2_Impl::SetAllowExtendedAdvertisements(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AllowExtendedAdvertisements: AllowExtendedAdvertisements::, + SetAllowExtendedAdvertisements: SetAllowExtendedAdvertisements::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEAdvertisementWatcherTrigger2_Vtbl { @@ -902,31 +1993,22 @@ pub struct IBluetoothLEAdvertisementWatcherTrigger2_Vtbl { pub AllowExtendedAdvertisements: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, pub SetAllowExtendedAdvertisements: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, } -windows_core::imp::define_interface!(IBluetoothLEAdvertisementWatcherTrigger3, IBluetoothLEAdvertisementWatcherTrigger3_Vtbl, 0xda50011a_8261_56a0_ac7b_a8de1624088b); -impl windows_core::RuntimeType for IBluetoothLEAdvertisementWatcherTrigger3 { - const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); -} -#[repr(C)] -#[doc(hidden)] -pub struct IBluetoothLEAdvertisementWatcherTrigger3_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub UseUncoded1MPhy: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, - pub SetUseUncoded1MPhy: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, - pub UseCodedPhy: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, - pub SetUseCodedPhy: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, - #[cfg(feature = "Devices_Bluetooth_Advertisement")] - pub ScanParameters: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, - #[cfg(not(feature = "Devices_Bluetooth_Advertisement"))] - ScanParameters: usize, - #[cfg(feature = "Devices_Bluetooth_Advertisement")] - pub SetScanParameters: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, - #[cfg(not(feature = "Devices_Bluetooth_Advertisement"))] - SetScanParameters: usize, -} windows_core::imp::define_interface!(ICachedFileUpdaterTrigger, ICachedFileUpdaterTrigger_Vtbl, 0xe21caeeb_32f2_4d31_b553_b9e01bde37e0); impl windows_core::RuntimeType for ICachedFileUpdaterTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICachedFileUpdaterTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.ICachedFileUpdaterTrigger"; +} +pub trait ICachedFileUpdaterTrigger_Impl: IBackgroundTrigger_Impl {} +impl ICachedFileUpdaterTrigger_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICachedFileUpdaterTrigger_Vtbl { @@ -936,6 +2018,18 @@ windows_core::imp::define_interface!(IChatMessageNotificationTrigger, IChatMessa impl windows_core::RuntimeType for IChatMessageNotificationTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IChatMessageNotificationTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IChatMessageNotificationTrigger"; +} +pub trait IChatMessageNotificationTrigger_Impl: IBackgroundTrigger_Impl {} +impl IChatMessageNotificationTrigger_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IChatMessageNotificationTrigger_Vtbl { @@ -945,6 +2039,18 @@ windows_core::imp::define_interface!(IChatMessageReceivedNotificationTrigger, IC impl windows_core::RuntimeType for IChatMessageReceivedNotificationTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IChatMessageReceivedNotificationTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IChatMessageReceivedNotificationTrigger"; +} +pub trait IChatMessageReceivedNotificationTrigger_Impl: IBackgroundTrigger_Impl {} +impl IChatMessageReceivedNotificationTrigger_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IChatMessageReceivedNotificationTrigger_Vtbl { @@ -954,6 +2060,18 @@ windows_core::imp::define_interface!(ICommunicationBlockingAppSetAsActiveTrigger impl windows_core::RuntimeType for ICommunicationBlockingAppSetAsActiveTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICommunicationBlockingAppSetAsActiveTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.ICommunicationBlockingAppSetAsActiveTrigger"; +} +pub trait ICommunicationBlockingAppSetAsActiveTrigger_Impl: IBackgroundTrigger_Impl {} +impl ICommunicationBlockingAppSetAsActiveTrigger_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICommunicationBlockingAppSetAsActiveTrigger_Vtbl { @@ -963,6 +2081,18 @@ windows_core::imp::define_interface!(IContactStoreNotificationTrigger, IContactS impl windows_core::RuntimeType for IContactStoreNotificationTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IContactStoreNotificationTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IContactStoreNotificationTrigger"; +} +pub trait IContactStoreNotificationTrigger_Impl: IBackgroundTrigger_Impl {} +impl IContactStoreNotificationTrigger_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IContactStoreNotificationTrigger_Vtbl { @@ -972,6 +2102,32 @@ windows_core::imp::define_interface!(IContentPrefetchTrigger, IContentPrefetchTr impl windows_core::RuntimeType for IContentPrefetchTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IContentPrefetchTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IContentPrefetchTrigger"; +} +pub trait IContentPrefetchTrigger_Impl: IBackgroundTrigger_Impl { + fn WaitInterval(&self) -> windows_core::Result; +} +impl IContentPrefetchTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn WaitInterval(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IContentPrefetchTrigger_Impl::WaitInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), WaitInterval: WaitInterval:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IContentPrefetchTrigger_Vtbl { @@ -982,6 +2138,33 @@ windows_core::imp::define_interface!(IContentPrefetchTriggerFactory, IContentPre impl windows_core::RuntimeType for IContentPrefetchTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IContentPrefetchTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.IContentPrefetchTriggerFactory"; +} +pub trait IContentPrefetchTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, waitInterval: &super::super::Foundation::TimeSpan) -> windows_core::Result; +} +impl IContentPrefetchTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, waitinterval: super::super::Foundation::TimeSpan, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IContentPrefetchTriggerFactory_Impl::Create(this, core::mem::transmute(&waitinterval)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IContentPrefetchTriggerFactory_Vtbl { @@ -992,6 +2175,50 @@ windows_core::imp::define_interface!(ICustomSystemEventTrigger, ICustomSystemEve impl windows_core::RuntimeType for ICustomSystemEventTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICustomSystemEventTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.ICustomSystemEventTrigger"; +} +pub trait ICustomSystemEventTrigger_Impl: windows_core::IUnknownImpl { + fn TriggerId(&self) -> windows_core::Result; + fn Recurrence(&self) -> windows_core::Result; +} +impl ICustomSystemEventTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TriggerId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICustomSystemEventTrigger_Impl::TriggerId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Recurrence(this: *mut core::ffi::c_void, result__: *mut CustomSystemEventTriggerRecurrence) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICustomSystemEventTrigger_Impl::Recurrence(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + TriggerId: TriggerId::, + Recurrence: Recurrence::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICustomSystemEventTrigger_Vtbl { @@ -1003,6 +2230,33 @@ windows_core::imp::define_interface!(ICustomSystemEventTriggerFactory, ICustomSy impl windows_core::RuntimeType for ICustomSystemEventTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICustomSystemEventTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.ICustomSystemEventTriggerFactory"; +} +pub trait ICustomSystemEventTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, triggerId: &windows_core::HSTRING, recurrence: CustomSystemEventTriggerRecurrence) -> windows_core::Result; +} +impl ICustomSystemEventTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, triggerid: *mut core::ffi::c_void, recurrence: CustomSystemEventTriggerRecurrence, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICustomSystemEventTriggerFactory_Impl::Create(this, core::mem::transmute(&triggerid), recurrence) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICustomSystemEventTriggerFactory_Vtbl { @@ -1013,6 +2267,72 @@ windows_core::imp::define_interface!(IDeviceConnectionChangeTrigger, IDeviceConn impl windows_core::RuntimeType for IDeviceConnectionChangeTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceConnectionChangeTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IDeviceConnectionChangeTrigger"; +} +pub trait IDeviceConnectionChangeTrigger_Impl: IBackgroundTrigger_Impl { + fn DeviceId(&self) -> windows_core::Result; + fn CanMaintainConnection(&self) -> windows_core::Result; + fn MaintainConnection(&self) -> windows_core::Result; + fn SetMaintainConnection(&self, value: bool) -> windows_core::Result<()>; +} +impl IDeviceConnectionChangeTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceConnectionChangeTrigger_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CanMaintainConnection(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceConnectionChangeTrigger_Impl::CanMaintainConnection(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaintainConnection(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceConnectionChangeTrigger_Impl::MaintainConnection(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMaintainConnection(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDeviceConnectionChangeTrigger_Impl::SetMaintainConnection(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DeviceId: DeviceId::, + CanMaintainConnection: CanMaintainConnection::, + MaintainConnection: MaintainConnection::, + SetMaintainConnection: SetMaintainConnection::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceConnectionChangeTrigger_Vtbl { @@ -1026,16 +2346,96 @@ windows_core::imp::define_interface!(IDeviceConnectionChangeTriggerStatics, IDev impl windows_core::RuntimeType for IDeviceConnectionChangeTriggerStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceConnectionChangeTriggerStatics { + const NAME: &'static str = "Windows.ApplicationModel.Background.IDeviceConnectionChangeTriggerStatics"; +} +pub trait IDeviceConnectionChangeTriggerStatics_Impl: windows_core::IUnknownImpl { + fn FromIdAsync(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; +} +impl IDeviceConnectionChangeTriggerStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FromIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceConnectionChangeTriggerStatics_Impl::FromIdAsync(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FromIdAsync: FromIdAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceConnectionChangeTriggerStatics_Vtbl { pub base__: windows_core::IInspectable_Vtbl, pub FromIdAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, } +#[cfg(feature = "deprecated")] windows_core::imp::define_interface!(IDeviceManufacturerNotificationTrigger, IDeviceManufacturerNotificationTrigger_Vtbl, 0x81278ab5_41ab_16da_86c2_7f7bf0912f5b); +#[cfg(feature = "deprecated")] impl windows_core::RuntimeType for IDeviceManufacturerNotificationTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "deprecated")] +impl windows_core::RuntimeName for IDeviceManufacturerNotificationTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IDeviceManufacturerNotificationTrigger"; +} +#[cfg(feature = "deprecated")] +pub trait IDeviceManufacturerNotificationTrigger_Impl: IBackgroundTrigger_Impl { + fn TriggerQualifier(&self) -> windows_core::Result; + fn OneShot(&self) -> windows_core::Result; +} +#[cfg(feature = "deprecated")] +impl IDeviceManufacturerNotificationTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TriggerQualifier(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceManufacturerNotificationTrigger_Impl::TriggerQualifier(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OneShot(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceManufacturerNotificationTrigger_Impl::OneShot(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + TriggerQualifier: TriggerQualifier::, + OneShot: OneShot::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[cfg(feature = "deprecated")] #[repr(C)] #[doc(hidden)] pub struct IDeviceManufacturerNotificationTrigger_Vtbl { @@ -1043,10 +2443,46 @@ pub struct IDeviceManufacturerNotificationTrigger_Vtbl { pub TriggerQualifier: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, pub OneShot: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, } +#[cfg(feature = "deprecated")] windows_core::imp::define_interface!(IDeviceManufacturerNotificationTriggerFactory, IDeviceManufacturerNotificationTriggerFactory_Vtbl, 0x7955de75_25bb_4153_a1a2_3029fcabb652); +#[cfg(feature = "deprecated")] impl windows_core::RuntimeType for IDeviceManufacturerNotificationTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "deprecated")] +impl windows_core::RuntimeName for IDeviceManufacturerNotificationTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.IDeviceManufacturerNotificationTriggerFactory"; +} +#[cfg(feature = "deprecated")] +pub trait IDeviceManufacturerNotificationTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, triggerQualifier: &windows_core::HSTRING, oneShot: bool) -> windows_core::Result; +} +#[cfg(feature = "deprecated")] +impl IDeviceManufacturerNotificationTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, triggerqualifier: *mut core::ffi::c_void, oneshot: bool, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceManufacturerNotificationTriggerFactory_Impl::Create(this, core::mem::transmute(&triggerqualifier), oneshot) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Create: Create::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[cfg(feature = "deprecated")] #[repr(C)] #[doc(hidden)] pub struct IDeviceManufacturerNotificationTriggerFactory_Vtbl { @@ -1057,6 +2493,51 @@ windows_core::imp::define_interface!(IDeviceServicingTrigger, IDeviceServicingTr impl windows_core::RuntimeType for IDeviceServicingTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceServicingTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IDeviceServicingTrigger"; +} +pub trait IDeviceServicingTrigger_Impl: IBackgroundTrigger_Impl { + fn RequestAsyncSimple(&self, deviceId: &windows_core::HSTRING, expectedDuration: &super::super::Foundation::TimeSpan) -> windows_core::Result>; + fn RequestAsyncWithArguments(&self, deviceId: &windows_core::HSTRING, expectedDuration: &super::super::Foundation::TimeSpan, arguments: &windows_core::HSTRING) -> windows_core::Result>; +} +impl IDeviceServicingTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn RequestAsyncSimple(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, expectedduration: super::super::Foundation::TimeSpan, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceServicingTrigger_Impl::RequestAsyncSimple(this, core::mem::transmute(&deviceid), core::mem::transmute(&expectedduration)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RequestAsyncWithArguments(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, expectedduration: super::super::Foundation::TimeSpan, arguments: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceServicingTrigger_Impl::RequestAsyncWithArguments(this, core::mem::transmute(&deviceid), core::mem::transmute(&expectedduration), core::mem::transmute(&arguments)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + RequestAsyncSimple: RequestAsyncSimple::, + RequestAsyncWithArguments: RequestAsyncWithArguments::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceServicingTrigger_Vtbl { @@ -1068,6 +2549,51 @@ windows_core::imp::define_interface!(IDeviceUseTrigger, IDeviceUseTrigger_Vtbl, impl windows_core::RuntimeType for IDeviceUseTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceUseTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IDeviceUseTrigger"; +} +pub trait IDeviceUseTrigger_Impl: IBackgroundTrigger_Impl { + fn RequestAsyncSimple(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; + fn RequestAsyncWithArguments(&self, deviceId: &windows_core::HSTRING, arguments: &windows_core::HSTRING) -> windows_core::Result>; +} +impl IDeviceUseTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn RequestAsyncSimple(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceUseTrigger_Impl::RequestAsyncSimple(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RequestAsyncWithArguments(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, arguments: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceUseTrigger_Impl::RequestAsyncWithArguments(this, core::mem::transmute(&deviceid), core::mem::transmute(&arguments)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + RequestAsyncSimple: RequestAsyncSimple::, + RequestAsyncWithArguments: RequestAsyncWithArguments::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceUseTrigger_Vtbl { @@ -1079,6 +2605,18 @@ windows_core::imp::define_interface!(IDeviceWatcherTrigger, IDeviceWatcherTrigge impl windows_core::RuntimeType for IDeviceWatcherTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceWatcherTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IDeviceWatcherTrigger"; +} +pub trait IDeviceWatcherTrigger_Impl: IBackgroundTrigger_Impl {} +impl IDeviceWatcherTrigger_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceWatcherTrigger_Vtbl { @@ -1088,6 +2626,18 @@ windows_core::imp::define_interface!(IEmailStoreNotificationTrigger, IEmailStore impl windows_core::RuntimeType for IEmailStoreNotificationTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IEmailStoreNotificationTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IEmailStoreNotificationTrigger"; +} +pub trait IEmailStoreNotificationTrigger_Impl: IBackgroundTrigger_Impl {} +impl IEmailStoreNotificationTrigger_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IEmailStoreNotificationTrigger_Vtbl { @@ -1097,6 +2647,39 @@ windows_core::imp::define_interface!(IGattCharacteristicNotificationTrigger, IGa impl windows_core::RuntimeType for IGattCharacteristicNotificationTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] +impl windows_core::RuntimeName for IGattCharacteristicNotificationTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IGattCharacteristicNotificationTrigger"; +} +#[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] +pub trait IGattCharacteristicNotificationTrigger_Impl: IBackgroundTrigger_Impl { + fn Characteristic(&self) -> windows_core::Result; +} +#[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] +impl IGattCharacteristicNotificationTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Characteristic(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristicNotificationTrigger_Impl::Characteristic(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Characteristic: Characteristic::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattCharacteristicNotificationTrigger_Vtbl { @@ -1110,6 +2693,38 @@ windows_core::imp::define_interface!(IGattCharacteristicNotificationTrigger2, IG impl windows_core::RuntimeType for IGattCharacteristicNotificationTrigger2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Bluetooth_Background")] +impl windows_core::RuntimeName for IGattCharacteristicNotificationTrigger2 { + const NAME: &'static str = "Windows.ApplicationModel.Background.IGattCharacteristicNotificationTrigger2"; +} +#[cfg(feature = "Devices_Bluetooth_Background")] +pub trait IGattCharacteristicNotificationTrigger2_Impl: windows_core::IUnknownImpl { + fn EventTriggeringMode(&self) -> windows_core::Result; +} +#[cfg(feature = "Devices_Bluetooth_Background")] +impl IGattCharacteristicNotificationTrigger2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn EventTriggeringMode(this: *mut core::ffi::c_void, result__: *mut super::super::Devices::Bluetooth::Background::BluetoothEventTriggeringMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristicNotificationTrigger2_Impl::EventTriggeringMode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + EventTriggeringMode: EventTriggeringMode::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattCharacteristicNotificationTrigger2_Vtbl { @@ -1123,6 +2738,39 @@ windows_core::imp::define_interface!(IGattCharacteristicNotificationTriggerFacto impl windows_core::RuntimeType for IGattCharacteristicNotificationTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] +impl windows_core::RuntimeName for IGattCharacteristicNotificationTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.IGattCharacteristicNotificationTriggerFactory"; +} +#[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] +pub trait IGattCharacteristicNotificationTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, characteristic: windows_core::Ref<'_, super::super::Devices::Bluetooth::GenericAttributeProfile::GattCharacteristic>) -> windows_core::Result; +} +#[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] +impl IGattCharacteristicNotificationTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, characteristic: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristicNotificationTriggerFactory_Impl::Create(this, core::mem::transmute_copy(&characteristic)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Create: Create::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattCharacteristicNotificationTriggerFactory_Vtbl { @@ -1136,6 +2784,39 @@ windows_core::imp::define_interface!(IGattCharacteristicNotificationTriggerFacto impl windows_core::RuntimeType for IGattCharacteristicNotificationTriggerFactory2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(all(feature = "Devices_Bluetooth_Background", feature = "Devices_Bluetooth_GenericAttributeProfile"))] +impl windows_core::RuntimeName for IGattCharacteristicNotificationTriggerFactory2 { + const NAME: &'static str = "Windows.ApplicationModel.Background.IGattCharacteristicNotificationTriggerFactory2"; +} +#[cfg(all(feature = "Devices_Bluetooth_Background", feature = "Devices_Bluetooth_GenericAttributeProfile"))] +pub trait IGattCharacteristicNotificationTriggerFactory2_Impl: windows_core::IUnknownImpl { + fn CreateWithEventTriggeringMode(&self, characteristic: windows_core::Ref<'_, super::super::Devices::Bluetooth::GenericAttributeProfile::GattCharacteristic>, eventTriggeringMode: super::super::Devices::Bluetooth::Background::BluetoothEventTriggeringMode) -> windows_core::Result; +} +#[cfg(all(feature = "Devices_Bluetooth_Background", feature = "Devices_Bluetooth_GenericAttributeProfile"))] +impl IGattCharacteristicNotificationTriggerFactory2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateWithEventTriggeringMode(this: *mut core::ffi::c_void, characteristic: *mut core::ffi::c_void, eventtriggeringmode: super::super::Devices::Bluetooth::Background::BluetoothEventTriggeringMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristicNotificationTriggerFactory2_Impl::CreateWithEventTriggeringMode(this, core::mem::transmute_copy(&characteristic), eventtriggeringmode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateWithEventTriggeringMode: CreateWithEventTriggeringMode::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattCharacteristicNotificationTriggerFactory2_Vtbl { @@ -1149,6 +2830,77 @@ windows_core::imp::define_interface!(IGattServiceProviderTrigger, IGattServicePr impl windows_core::RuntimeType for IGattServiceProviderTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] +impl windows_core::RuntimeName for IGattServiceProviderTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IGattServiceProviderTrigger"; +} +#[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] +pub trait IGattServiceProviderTrigger_Impl: windows_core::IUnknownImpl { + fn TriggerId(&self) -> windows_core::Result; + fn Service(&self) -> windows_core::Result; + fn SetAdvertisingParameters(&self, value: windows_core::Ref<'_, super::super::Devices::Bluetooth::GenericAttributeProfile::GattServiceProviderAdvertisingParameters>) -> windows_core::Result<()>; + fn AdvertisingParameters(&self) -> windows_core::Result; +} +#[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] +impl IGattServiceProviderTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TriggerId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattServiceProviderTrigger_Impl::TriggerId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Service(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattServiceProviderTrigger_Impl::Service(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAdvertisingParameters(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattServiceProviderTrigger_Impl::SetAdvertisingParameters(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn AdvertisingParameters(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattServiceProviderTrigger_Impl::AdvertisingParameters(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + TriggerId: TriggerId::, + Service: Service::, + SetAdvertisingParameters: SetAdvertisingParameters::, + AdvertisingParameters: AdvertisingParameters::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattServiceProviderTrigger_Vtbl { @@ -1171,6 +2923,53 @@ windows_core::imp::define_interface!(IGattServiceProviderTriggerResult, IGattSer impl windows_core::RuntimeType for IGattServiceProviderTriggerResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Bluetooth")] +impl windows_core::RuntimeName for IGattServiceProviderTriggerResult { + const NAME: &'static str = "Windows.ApplicationModel.Background.IGattServiceProviderTriggerResult"; +} +#[cfg(feature = "Devices_Bluetooth")] +pub trait IGattServiceProviderTriggerResult_Impl: windows_core::IUnknownImpl { + fn Trigger(&self) -> windows_core::Result; + fn Error(&self) -> windows_core::Result; +} +#[cfg(feature = "Devices_Bluetooth")] +impl IGattServiceProviderTriggerResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Trigger(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattServiceProviderTriggerResult_Impl::Trigger(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Error(this: *mut core::ffi::c_void, result__: *mut super::super::Devices::Bluetooth::BluetoothError) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattServiceProviderTriggerResult_Impl::Error(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Trigger: Trigger::, + Error: Error::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattServiceProviderTriggerResult_Vtbl { @@ -1185,6 +2984,36 @@ windows_core::imp::define_interface!(IGattServiceProviderTriggerStatics, IGattSe impl windows_core::RuntimeType for IGattServiceProviderTriggerStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattServiceProviderTriggerStatics { + const NAME: &'static str = "Windows.ApplicationModel.Background.IGattServiceProviderTriggerStatics"; +} +pub trait IGattServiceProviderTriggerStatics_Impl: windows_core::IUnknownImpl { + fn CreateAsync(&self, triggerId: &windows_core::HSTRING, serviceUuid: &windows_core::GUID) -> windows_core::Result>; +} +impl IGattServiceProviderTriggerStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateAsync(this: *mut core::ffi::c_void, triggerid: *mut core::ffi::c_void, serviceuuid: windows_core::GUID, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattServiceProviderTriggerStatics_Impl::CreateAsync(this, core::mem::transmute(&triggerid), core::mem::transmute(&serviceuuid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateAsync: CreateAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattServiceProviderTriggerStatics_Vtbl { @@ -1195,6 +3024,46 @@ windows_core::imp::define_interface!(IGeovisitTrigger, IGeovisitTrigger_Vtbl, 0x impl windows_core::RuntimeType for IGeovisitTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Geolocation")] +impl windows_core::RuntimeName for IGeovisitTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IGeovisitTrigger"; +} +#[cfg(feature = "Devices_Geolocation")] +pub trait IGeovisitTrigger_Impl: IBackgroundTrigger_Impl { + fn MonitoringScope(&self) -> windows_core::Result; + fn SetMonitoringScope(&self, value: super::super::Devices::Geolocation::VisitMonitoringScope) -> windows_core::Result<()>; +} +#[cfg(feature = "Devices_Geolocation")] +impl IGeovisitTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn MonitoringScope(this: *mut core::ffi::c_void, result__: *mut super::super::Devices::Geolocation::VisitMonitoringScope) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGeovisitTrigger_Impl::MonitoringScope(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMonitoringScope(this: *mut core::ffi::c_void, value: super::super::Devices::Geolocation::VisitMonitoringScope) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGeovisitTrigger_Impl::SetMonitoringScope(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + MonitoringScope: MonitoringScope::, + SetMonitoringScope: SetMonitoringScope::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGeovisitTrigger_Vtbl { @@ -1212,6 +3081,32 @@ windows_core::imp::define_interface!(ILocationTrigger, ILocationTrigger_Vtbl, 0x impl windows_core::RuntimeType for ILocationTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ILocationTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.ILocationTrigger"; +} +pub trait ILocationTrigger_Impl: IBackgroundTrigger_Impl { + fn TriggerType(&self) -> windows_core::Result; +} +impl ILocationTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TriggerType(this: *mut core::ffi::c_void, result__: *mut LocationTriggerType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILocationTrigger_Impl::TriggerType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), TriggerType: TriggerType:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ILocationTrigger_Vtbl { @@ -1222,6 +3117,33 @@ windows_core::imp::define_interface!(ILocationTriggerFactory, ILocationTriggerFa impl windows_core::RuntimeType for ILocationTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ILocationTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.ILocationTriggerFactory"; +} +pub trait ILocationTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, triggerType: LocationTriggerType) -> windows_core::Result; +} +impl ILocationTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, triggertype: LocationTriggerType, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILocationTriggerFactory_Impl::Create(this, triggertype) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ILocationTriggerFactory_Vtbl { @@ -1232,6 +3154,49 @@ windows_core::imp::define_interface!(IMaintenanceTrigger, IMaintenanceTrigger_Vt impl windows_core::RuntimeType for IMaintenanceTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMaintenanceTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IMaintenanceTrigger"; +} +pub trait IMaintenanceTrigger_Impl: IBackgroundTrigger_Impl { + fn FreshnessTime(&self) -> windows_core::Result; + fn OneShot(&self) -> windows_core::Result; +} +impl IMaintenanceTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FreshnessTime(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMaintenanceTrigger_Impl::FreshnessTime(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OneShot(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMaintenanceTrigger_Impl::OneShot(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FreshnessTime: FreshnessTime::, + OneShot: OneShot::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMaintenanceTrigger_Vtbl { @@ -1243,6 +3208,33 @@ windows_core::imp::define_interface!(IMaintenanceTriggerFactory, IMaintenanceTri impl windows_core::RuntimeType for IMaintenanceTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMaintenanceTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.IMaintenanceTriggerFactory"; +} +pub trait IMaintenanceTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, freshnessTime: u32, oneShot: bool) -> windows_core::Result; +} +impl IMaintenanceTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, freshnesstime: u32, oneshot: bool, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMaintenanceTriggerFactory_Impl::Create(this, freshnesstime, oneshot) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMaintenanceTriggerFactory_Vtbl { @@ -1253,6 +3245,54 @@ windows_core::imp::define_interface!(IMediaProcessingTrigger, IMediaProcessingTr impl windows_core::RuntimeType for IMediaProcessingTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Foundation_Collections")] +impl windows_core::RuntimeName for IMediaProcessingTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IMediaProcessingTrigger"; +} +#[cfg(feature = "Foundation_Collections")] +pub trait IMediaProcessingTrigger_Impl: IBackgroundTrigger_Impl { + fn RequestAsync(&self) -> windows_core::Result>; + fn RequestAsyncWithArguments(&self, arguments: windows_core::Ref<'_, super::super::Foundation::Collections::ValueSet>) -> windows_core::Result>; +} +#[cfg(feature = "Foundation_Collections")] +impl IMediaProcessingTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn RequestAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaProcessingTrigger_Impl::RequestAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RequestAsyncWithArguments(this: *mut core::ffi::c_void, arguments: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaProcessingTrigger_Impl::RequestAsyncWithArguments(this, core::mem::transmute_copy(&arguments)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + RequestAsync: RequestAsync::, + RequestAsyncWithArguments: RequestAsyncWithArguments::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMediaProcessingTrigger_Vtbl { @@ -1267,6 +3307,18 @@ windows_core::imp::define_interface!(INetworkOperatorHotspotAuthenticationTrigge impl windows_core::RuntimeType for INetworkOperatorHotspotAuthenticationTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for INetworkOperatorHotspotAuthenticationTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.INetworkOperatorHotspotAuthenticationTrigger"; +} +pub trait INetworkOperatorHotspotAuthenticationTrigger_Impl: IBackgroundTrigger_Impl {} +impl INetworkOperatorHotspotAuthenticationTrigger_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct INetworkOperatorHotspotAuthenticationTrigger_Vtbl { @@ -1276,6 +3328,36 @@ windows_core::imp::define_interface!(INetworkOperatorNotificationTrigger, INetwo impl windows_core::RuntimeType for INetworkOperatorNotificationTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for INetworkOperatorNotificationTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.INetworkOperatorNotificationTrigger"; +} +pub trait INetworkOperatorNotificationTrigger_Impl: IBackgroundTrigger_Impl { + fn NetworkAccountId(&self) -> windows_core::Result; +} +impl INetworkOperatorNotificationTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn NetworkAccountId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match INetworkOperatorNotificationTrigger_Impl::NetworkAccountId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + NetworkAccountId: NetworkAccountId::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct INetworkOperatorNotificationTrigger_Vtbl { @@ -1286,6 +3368,36 @@ windows_core::imp::define_interface!(INetworkOperatorNotificationTriggerFactory, impl windows_core::RuntimeType for INetworkOperatorNotificationTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for INetworkOperatorNotificationTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.INetworkOperatorNotificationTriggerFactory"; +} +pub trait INetworkOperatorNotificationTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, networkAccountId: &windows_core::HSTRING) -> windows_core::Result; +} +impl INetworkOperatorNotificationTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, networkaccountid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match INetworkOperatorNotificationTriggerFactory_Impl::Create(this, core::mem::transmute(&networkaccountid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Create: Create::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct INetworkOperatorNotificationTriggerFactory_Vtbl { @@ -1296,6 +3408,52 @@ windows_core::imp::define_interface!(IPhoneTrigger, IPhoneTrigger_Vtbl, 0x8dcfe9 impl windows_core::RuntimeType for IPhoneTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "ApplicationModel_Calls_Background")] +impl windows_core::RuntimeName for IPhoneTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IPhoneTrigger"; +} +#[cfg(feature = "ApplicationModel_Calls_Background")] +pub trait IPhoneTrigger_Impl: IBackgroundTrigger_Impl { + fn OneShot(&self) -> windows_core::Result; + fn TriggerType(&self) -> windows_core::Result; +} +#[cfg(feature = "ApplicationModel_Calls_Background")] +impl IPhoneTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn OneShot(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPhoneTrigger_Impl::OneShot(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TriggerType(this: *mut core::ffi::c_void, result__: *mut super::Calls::Background::PhoneTriggerType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPhoneTrigger_Impl::TriggerType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + OneShot: OneShot::, + TriggerType: TriggerType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IPhoneTrigger_Vtbl { @@ -1310,6 +3468,36 @@ windows_core::imp::define_interface!(IPhoneTriggerFactory, IPhoneTriggerFactory_ impl windows_core::RuntimeType for IPhoneTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "ApplicationModel_Calls_Background")] +impl windows_core::RuntimeName for IPhoneTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.IPhoneTriggerFactory"; +} +#[cfg(feature = "ApplicationModel_Calls_Background")] +pub trait IPhoneTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, r#type: super::Calls::Background::PhoneTriggerType, oneShot: bool) -> windows_core::Result; +} +#[cfg(feature = "ApplicationModel_Calls_Background")] +impl IPhoneTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, r#type: super::Calls::Background::PhoneTriggerType, oneshot: bool, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPhoneTriggerFactory_Impl::Create(this, r#type, oneshot) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IPhoneTriggerFactory_Vtbl { @@ -1323,6 +3511,33 @@ windows_core::imp::define_interface!(IPushNotificationTriggerFactory, IPushNotif impl windows_core::RuntimeType for IPushNotificationTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IPushNotificationTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.IPushNotificationTriggerFactory"; +} +pub trait IPushNotificationTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, applicationId: &windows_core::HSTRING) -> windows_core::Result; +} +impl IPushNotificationTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, applicationid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPushNotificationTriggerFactory_Impl::Create(this, core::mem::transmute(&applicationid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IPushNotificationTriggerFactory_Vtbl { @@ -1333,6 +3548,18 @@ windows_core::imp::define_interface!(IRcsEndUserMessageAvailableTrigger, IRcsEnd impl windows_core::RuntimeType for IRcsEndUserMessageAvailableTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IRcsEndUserMessageAvailableTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IRcsEndUserMessageAvailableTrigger"; +} +pub trait IRcsEndUserMessageAvailableTrigger_Impl: IBackgroundTrigger_Impl {} +impl IRcsEndUserMessageAvailableTrigger_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IRcsEndUserMessageAvailableTrigger_Vtbl { @@ -1342,6 +3569,121 @@ windows_core::imp::define_interface!(IRfcommConnectionTrigger, IRfcommConnection impl windows_core::RuntimeType for IRfcommConnectionTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(all(feature = "Devices_Bluetooth_Background", feature = "Networking_Sockets"))] +impl windows_core::RuntimeName for IRfcommConnectionTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IRfcommConnectionTrigger"; +} +#[cfg(all(feature = "Devices_Bluetooth_Background", feature = "Networking_Sockets"))] +pub trait IRfcommConnectionTrigger_Impl: IBackgroundTrigger_Impl { + fn InboundConnection(&self) -> windows_core::Result; + fn OutboundConnection(&self) -> windows_core::Result; + fn AllowMultipleConnections(&self) -> windows_core::Result; + fn SetAllowMultipleConnections(&self, value: bool) -> windows_core::Result<()>; + fn ProtectionLevel(&self) -> windows_core::Result; + fn SetProtectionLevel(&self, value: super::super::Networking::Sockets::SocketProtectionLevel) -> windows_core::Result<()>; + fn RemoteHostName(&self) -> windows_core::Result; + fn SetRemoteHostName(&self, value: windows_core::Ref<'_, super::super::Networking::HostName>) -> windows_core::Result<()>; +} +#[cfg(all(feature = "Devices_Bluetooth_Background", feature = "Networking_Sockets"))] +impl IRfcommConnectionTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn InboundConnection(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommConnectionTrigger_Impl::InboundConnection(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OutboundConnection(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommConnectionTrigger_Impl::OutboundConnection(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AllowMultipleConnections(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommConnectionTrigger_Impl::AllowMultipleConnections(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAllowMultipleConnections(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IRfcommConnectionTrigger_Impl::SetAllowMultipleConnections(this, value).into() + } + } + unsafe extern "system" fn ProtectionLevel(this: *mut core::ffi::c_void, result__: *mut super::super::Networking::Sockets::SocketProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommConnectionTrigger_Impl::ProtectionLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetProtectionLevel(this: *mut core::ffi::c_void, value: super::super::Networking::Sockets::SocketProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IRfcommConnectionTrigger_Impl::SetProtectionLevel(this, value).into() + } + } + unsafe extern "system" fn RemoteHostName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommConnectionTrigger_Impl::RemoteHostName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRemoteHostName(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IRfcommConnectionTrigger_Impl::SetRemoteHostName(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + InboundConnection: InboundConnection::, + OutboundConnection: OutboundConnection::, + AllowMultipleConnections: AllowMultipleConnections::, + SetAllowMultipleConnections: SetAllowMultipleConnections::, + ProtectionLevel: ProtectionLevel::, + SetProtectionLevel: SetProtectionLevel::, + RemoteHostName: RemoteHostName::, + SetRemoteHostName: SetRemoteHostName::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IRfcommConnectionTrigger_Vtbl { @@ -1373,10 +3715,28 @@ pub struct IRfcommConnectionTrigger_Vtbl { #[cfg(not(feature = "Networking"))] SetRemoteHostName: usize, } +#[cfg(feature = "deprecated")] windows_core::imp::define_interface!(ISecondaryAuthenticationFactorAuthenticationTrigger, ISecondaryAuthenticationFactorAuthenticationTrigger_Vtbl, 0xf237f327_5181_4f24_96a7_700a4e5fac62); +#[cfg(feature = "deprecated")] impl windows_core::RuntimeType for ISecondaryAuthenticationFactorAuthenticationTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "deprecated")] +impl windows_core::RuntimeName for ISecondaryAuthenticationFactorAuthenticationTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.ISecondaryAuthenticationFactorAuthenticationTrigger"; +} +#[cfg(feature = "deprecated")] +pub trait ISecondaryAuthenticationFactorAuthenticationTrigger_Impl: IBackgroundTrigger_Impl {} +#[cfg(feature = "deprecated")] +impl ISecondaryAuthenticationFactorAuthenticationTrigger_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[cfg(feature = "deprecated")] #[repr(C)] #[doc(hidden)] pub struct ISecondaryAuthenticationFactorAuthenticationTrigger_Vtbl { @@ -1386,6 +3746,18 @@ windows_core::imp::define_interface!(ISensorDataThresholdTrigger, ISensorDataThr impl windows_core::RuntimeType for ISensorDataThresholdTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISensorDataThresholdTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.ISensorDataThresholdTrigger"; +} +pub trait ISensorDataThresholdTrigger_Impl: IBackgroundTrigger_Impl {} +impl ISensorDataThresholdTrigger_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISensorDataThresholdTrigger_Vtbl { @@ -1395,6 +3767,36 @@ windows_core::imp::define_interface!(ISensorDataThresholdTriggerFactory, ISensor impl windows_core::RuntimeType for ISensorDataThresholdTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Sensors")] +impl windows_core::RuntimeName for ISensorDataThresholdTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.ISensorDataThresholdTriggerFactory"; +} +#[cfg(feature = "Devices_Sensors")] +pub trait ISensorDataThresholdTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, threshold: windows_core::Ref<'_, super::super::Devices::Sensors::ISensorDataThreshold>) -> windows_core::Result; +} +#[cfg(feature = "Devices_Sensors")] +impl ISensorDataThresholdTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, threshold: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorDataThresholdTriggerFactory_Impl::Create(this, core::mem::transmute_copy(&threshold)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISensorDataThresholdTriggerFactory_Vtbl { @@ -1408,6 +3810,35 @@ windows_core::imp::define_interface!(ISmartCardTrigger, ISmartCardTrigger_Vtbl, impl windows_core::RuntimeType for ISmartCardTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_SmartCards")] +impl windows_core::RuntimeName for ISmartCardTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.ISmartCardTrigger"; +} +#[cfg(feature = "Devices_SmartCards")] +pub trait ISmartCardTrigger_Impl: IBackgroundTrigger_Impl { + fn TriggerType(&self) -> windows_core::Result; +} +#[cfg(feature = "Devices_SmartCards")] +impl ISmartCardTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TriggerType(this: *mut core::ffi::c_void, result__: *mut super::super::Devices::SmartCards::SmartCardTriggerType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmartCardTrigger_Impl::TriggerType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), TriggerType: TriggerType:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISmartCardTrigger_Vtbl { @@ -1421,6 +3852,36 @@ windows_core::imp::define_interface!(ISmartCardTriggerFactory, ISmartCardTrigger impl windows_core::RuntimeType for ISmartCardTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_SmartCards")] +impl windows_core::RuntimeName for ISmartCardTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.ISmartCardTriggerFactory"; +} +#[cfg(feature = "Devices_SmartCards")] +pub trait ISmartCardTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, triggerType: super::super::Devices::SmartCards::SmartCardTriggerType) -> windows_core::Result; +} +#[cfg(feature = "Devices_SmartCards")] +impl ISmartCardTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, triggertype: super::super::Devices::SmartCards::SmartCardTriggerType, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmartCardTriggerFactory_Impl::Create(this, triggertype) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISmartCardTriggerFactory_Vtbl { @@ -1434,6 +3895,36 @@ windows_core::imp::define_interface!(ISmsMessageReceivedTriggerFactory, ISmsMess impl windows_core::RuntimeType for ISmsMessageReceivedTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Sms")] +impl windows_core::RuntimeName for ISmsMessageReceivedTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.ISmsMessageReceivedTriggerFactory"; +} +#[cfg(feature = "Devices_Sms")] +pub trait ISmsMessageReceivedTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, filterRules: windows_core::Ref<'_, super::super::Devices::Sms::SmsFilterRules>) -> windows_core::Result; +} +#[cfg(feature = "Devices_Sms")] +impl ISmsMessageReceivedTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, filterrules: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsMessageReceivedTriggerFactory_Impl::Create(this, core::mem::transmute_copy(&filterrules)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISmsMessageReceivedTriggerFactory_Vtbl { @@ -1447,6 +3938,35 @@ windows_core::imp::define_interface!(ISocketActivityTrigger, ISocketActivityTrig impl windows_core::RuntimeType for ISocketActivityTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISocketActivityTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.ISocketActivityTrigger"; +} +pub trait ISocketActivityTrigger_Impl: windows_core::IUnknownImpl { + fn IsWakeFromLowPowerSupported(&self) -> windows_core::Result; +} +impl ISocketActivityTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsWakeFromLowPowerSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISocketActivityTrigger_Impl::IsWakeFromLowPowerSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsWakeFromLowPowerSupported: IsWakeFromLowPowerSupported::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISocketActivityTrigger_Vtbl { @@ -1457,6 +3977,39 @@ windows_core::imp::define_interface!(IStorageLibraryChangeTrackerTriggerFactory, impl windows_core::RuntimeType for IStorageLibraryChangeTrackerTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage")] +impl windows_core::RuntimeName for IStorageLibraryChangeTrackerTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.IStorageLibraryChangeTrackerTriggerFactory"; +} +#[cfg(feature = "Storage")] +pub trait IStorageLibraryChangeTrackerTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, tracker: windows_core::Ref<'_, super::super::Storage::StorageLibraryChangeTracker>) -> windows_core::Result; +} +#[cfg(feature = "Storage")] +impl IStorageLibraryChangeTrackerTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, tracker: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibraryChangeTrackerTriggerFactory_Impl::Create(this, core::mem::transmute_copy(&tracker)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Create: Create::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageLibraryChangeTrackerTriggerFactory_Vtbl { @@ -1470,6 +4023,18 @@ windows_core::imp::define_interface!(IStorageLibraryContentChangedTrigger, IStor impl windows_core::RuntimeType for IStorageLibraryContentChangedTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStorageLibraryContentChangedTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.IStorageLibraryContentChangedTrigger"; +} +pub trait IStorageLibraryContentChangedTrigger_Impl: IBackgroundTrigger_Impl {} +impl IStorageLibraryContentChangedTrigger_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageLibraryContentChangedTrigger_Vtbl { @@ -1479,6 +4044,54 @@ windows_core::imp::define_interface!(IStorageLibraryContentChangedTriggerStatics impl windows_core::RuntimeType for IStorageLibraryContentChangedTriggerStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage")] +impl windows_core::RuntimeName for IStorageLibraryContentChangedTriggerStatics { + const NAME: &'static str = "Windows.ApplicationModel.Background.IStorageLibraryContentChangedTriggerStatics"; +} +#[cfg(feature = "Storage")] +pub trait IStorageLibraryContentChangedTriggerStatics_Impl: windows_core::IUnknownImpl { + fn Create(&self, storageLibrary: windows_core::Ref<'_, super::super::Storage::StorageLibrary>) -> windows_core::Result; + fn CreateFromLibraries(&self, storageLibraries: windows_core::Ref<'_, windows_collections::IIterable>) -> windows_core::Result; +} +#[cfg(feature = "Storage")] +impl IStorageLibraryContentChangedTriggerStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, storagelibrary: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibraryContentChangedTriggerStatics_Impl::Create(this, core::mem::transmute_copy(&storagelibrary)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromLibraries(this: *mut core::ffi::c_void, storagelibraries: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibraryContentChangedTriggerStatics_Impl::CreateFromLibraries(this, core::mem::transmute_copy(&storagelibraries)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Create: Create::, + CreateFromLibraries: CreateFromLibraries::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageLibraryContentChangedTriggerStatics_Vtbl { @@ -1496,6 +4109,49 @@ windows_core::imp::define_interface!(ISystemTrigger, ISystemTrigger_Vtbl, 0x1d80 impl windows_core::RuntimeType for ISystemTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISystemTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.ISystemTrigger"; +} +pub trait ISystemTrigger_Impl: IBackgroundTrigger_Impl { + fn OneShot(&self) -> windows_core::Result; + fn TriggerType(&self) -> windows_core::Result; +} +impl ISystemTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn OneShot(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISystemTrigger_Impl::OneShot(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TriggerType(this: *mut core::ffi::c_void, result__: *mut SystemTriggerType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISystemTrigger_Impl::TriggerType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + OneShot: OneShot::, + TriggerType: TriggerType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISystemTrigger_Vtbl { @@ -1507,6 +4163,33 @@ windows_core::imp::define_interface!(ISystemTriggerFactory, ISystemTriggerFactor impl windows_core::RuntimeType for ISystemTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISystemTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.ISystemTriggerFactory"; +} +pub trait ISystemTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, triggerType: SystemTriggerType, oneShot: bool) -> windows_core::Result; +} +impl ISystemTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, triggertype: SystemTriggerType, oneshot: bool, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISystemTriggerFactory_Impl::Create(this, triggertype, oneshot) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISystemTriggerFactory_Vtbl { @@ -1517,6 +4200,49 @@ windows_core::imp::define_interface!(ITimeTrigger, ITimeTrigger_Vtbl, 0x656e5556 impl windows_core::RuntimeType for ITimeTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ITimeTrigger { + const NAME: &'static str = "Windows.ApplicationModel.Background.ITimeTrigger"; +} +pub trait ITimeTrigger_Impl: IBackgroundTrigger_Impl { + fn FreshnessTime(&self) -> windows_core::Result; + fn OneShot(&self) -> windows_core::Result; +} +impl ITimeTrigger_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FreshnessTime(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimeTrigger_Impl::FreshnessTime(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OneShot(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimeTrigger_Impl::OneShot(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FreshnessTime: FreshnessTime::, + OneShot: OneShot::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ITimeTrigger_Vtbl { @@ -1528,6 +4254,33 @@ windows_core::imp::define_interface!(ITimeTriggerFactory, ITimeTriggerFactory_Vt impl windows_core::RuntimeType for ITimeTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ITimeTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.ITimeTriggerFactory"; +} +pub trait ITimeTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, freshnessTime: u32, oneShot: bool) -> windows_core::Result; +} +impl ITimeTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, freshnesstime: u32, oneshot: bool, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimeTriggerFactory_Impl::Create(this, freshnesstime, oneshot) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ITimeTriggerFactory_Vtbl { @@ -1538,6 +4291,33 @@ windows_core::imp::define_interface!(IToastNotificationActionTriggerFactory, ITo impl windows_core::RuntimeType for IToastNotificationActionTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IToastNotificationActionTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.IToastNotificationActionTriggerFactory"; +} +pub trait IToastNotificationActionTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, applicationId: &windows_core::HSTRING) -> windows_core::Result; +} +impl IToastNotificationActionTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, applicationid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IToastNotificationActionTriggerFactory_Impl::Create(this, core::mem::transmute(&applicationid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IToastNotificationActionTriggerFactory_Vtbl { @@ -1548,6 +4328,36 @@ windows_core::imp::define_interface!(IToastNotificationHistoryChangedTriggerFact impl windows_core::RuntimeType for IToastNotificationHistoryChangedTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IToastNotificationHistoryChangedTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.IToastNotificationHistoryChangedTriggerFactory"; +} +pub trait IToastNotificationHistoryChangedTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, applicationId: &windows_core::HSTRING) -> windows_core::Result; +} +impl IToastNotificationHistoryChangedTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, applicationid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IToastNotificationHistoryChangedTriggerFactory_Impl::Create(this, core::mem::transmute(&applicationid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Create: Create::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IToastNotificationHistoryChangedTriggerFactory_Vtbl { @@ -1558,6 +4368,36 @@ windows_core::imp::define_interface!(IUserNotificationChangedTriggerFactory, IUs impl windows_core::RuntimeType for IUserNotificationChangedTriggerFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "UI_Notifications")] +impl windows_core::RuntimeName for IUserNotificationChangedTriggerFactory { + const NAME: &'static str = "Windows.ApplicationModel.Background.IUserNotificationChangedTriggerFactory"; +} +#[cfg(feature = "UI_Notifications")] +pub trait IUserNotificationChangedTriggerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, notificationKinds: super::super::UI::Notifications::NotificationKinds) -> windows_core::Result; +} +#[cfg(feature = "UI_Notifications")] +impl IUserNotificationChangedTriggerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, notificationkinds: super::super::UI::Notifications::NotificationKinds, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserNotificationChangedTriggerFactory_Impl::Create(this, notificationkinds) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IUserNotificationChangedTriggerFactory_Vtbl { @@ -1573,6 +4413,13 @@ pub struct LocationTrigger(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(LocationTrigger, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(LocationTrigger, IBackgroundTrigger); impl LocationTrigger { + pub fn TriggerType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TriggerType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Create(triggertype: LocationTriggerType) -> windows_core::Result { Self::ILocationTriggerFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -1614,6 +4461,20 @@ pub struct MaintenanceTrigger(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(MaintenanceTrigger, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(MaintenanceTrigger, IBackgroundTrigger); impl MaintenanceTrigger { + pub fn FreshnessTime(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FreshnessTime)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn OneShot(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OneShot)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Create(freshnesstime: u32, oneshot: bool) -> windows_core::Result { Self::IMaintenanceTriggerFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -1648,7 +4509,25 @@ impl MediaProcessingTrigger { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn RequestAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + #[cfg(feature = "Foundation_Collections")] + pub fn RequestAsyncWithArguments(&self, arguments: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestAsyncWithArguments)(windows_core::Interface::as_raw(this), arguments.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for MediaProcessingTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -1854,6 +4733,13 @@ pub struct NetworkOperatorNotificationTrigger(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(NetworkOperatorNotificationTrigger, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(NetworkOperatorNotificationTrigger, IBackgroundTrigger); impl NetworkOperatorNotificationTrigger { + pub fn NetworkAccountId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NetworkAccountId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } pub fn Create(networkaccountid: &windows_core::HSTRING) -> windows_core::Result { Self::INetworkOperatorNotificationTriggerFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -1906,6 +4792,21 @@ pub struct PhoneTrigger(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(PhoneTrigger, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(PhoneTrigger, IBackgroundTrigger); impl PhoneTrigger { + pub fn OneShot(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OneShot)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "ApplicationModel_Calls_Background")] + pub fn TriggerType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TriggerType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "ApplicationModel_Calls_Background")] pub fn Create(r#type: super::Calls::Background::PhoneTriggerType, oneshot: bool) -> windows_core::Result { Self::IPhoneTriggerFactory(|this| unsafe { @@ -2004,7 +4905,63 @@ impl RfcommConnectionTrigger { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + #[cfg(feature = "Devices_Bluetooth_Background")] + pub fn InboundConnection(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InboundConnection)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + #[cfg(feature = "Devices_Bluetooth_Background")] + pub fn OutboundConnection(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OutboundConnection)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn AllowMultipleConnections(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AllowMultipleConnections)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAllowMultipleConnections(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAllowMultipleConnections)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Networking_Sockets")] + pub fn ProtectionLevel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProtectionLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Networking_Sockets")] + pub fn SetProtectionLevel(&self, value: super::super::Networking::Sockets::SocketProtectionLevel) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetProtectionLevel)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Networking")] + pub fn RemoteHostName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RemoteHostName)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Networking")] + pub fn SetRemoteHostName(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetRemoteHostName)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } +} impl windows_core::RuntimeType for RfcommConnectionTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -2017,11 +4974,15 @@ impl windows_core::RuntimeName for RfcommConnectionTrigger { } unsafe impl Send for RfcommConnectionTrigger {} unsafe impl Sync for RfcommConnectionTrigger {} +#[cfg(feature = "deprecated")] #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] pub struct SecondaryAuthenticationFactorAuthenticationTrigger(windows_core::IUnknown); +#[cfg(feature = "deprecated")] windows_core::imp::interface_hierarchy!(SecondaryAuthenticationFactorAuthenticationTrigger, windows_core::IUnknown, windows_core::IInspectable); +#[cfg(feature = "deprecated")] windows_core::imp::required_hierarchy!(SecondaryAuthenticationFactorAuthenticationTrigger, IBackgroundTrigger); +#[cfg(feature = "deprecated")] impl SecondaryAuthenticationFactorAuthenticationTrigger { pub fn new() -> windows_core::Result { Self::IActivationFactory(|f| f.ActivateInstance::()) @@ -2031,13 +4992,16 @@ impl SecondaryAuthenticationFactorAuthenticationTrigger { SHARED.call(callback) } } +#[cfg(feature = "deprecated")] impl windows_core::RuntimeType for SecondaryAuthenticationFactorAuthenticationTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } +#[cfg(feature = "deprecated")] unsafe impl windows_core::Interface for SecondaryAuthenticationFactorAuthenticationTrigger { type Vtable = ::Vtable; const IID: windows_core::GUID = ::IID; } +#[cfg(feature = "deprecated")] impl windows_core::RuntimeName for SecondaryAuthenticationFactorAuthenticationTrigger { const NAME: &'static str = "Windows.ApplicationModel.Background.SecondaryAuthenticationFactorAuthenticationTrigger"; } @@ -2080,6 +5044,14 @@ pub struct SmartCardTrigger(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(SmartCardTrigger, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(SmartCardTrigger, IBackgroundTrigger); impl SmartCardTrigger { + #[cfg(feature = "Devices_SmartCards")] + pub fn TriggerType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TriggerType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Devices_SmartCards")] pub fn Create(triggertype: super::super::Devices::SmartCards::SmartCardTriggerType) -> windows_core::Result { Self::ISmartCardTriggerFactory(|this| unsafe { @@ -2146,7 +5118,14 @@ impl SocketActivityTrigger { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn IsWakeFromLowPowerSupported(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsWakeFromLowPowerSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } +} impl windows_core::RuntimeType for SocketActivityTrigger { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -2207,6 +5186,16 @@ impl StorageLibraryContentChangedTrigger { (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), storagelibrary.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + #[cfg(feature = "Storage")] + pub fn CreateFromLibraries(storagelibraries: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + Self::IStorageLibraryContentChangedTriggerStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromLibraries)(windows_core::Interface::as_raw(this), storagelibraries.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IStorageLibraryContentChangedTriggerStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -2228,6 +5217,20 @@ pub struct SystemTrigger(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(SystemTrigger, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(SystemTrigger, IBackgroundTrigger); impl SystemTrigger { + pub fn OneShot(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OneShot)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn TriggerType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TriggerType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Create(triggertype: SystemTriggerType, oneshot: bool) -> windows_core::Result { Self::ISystemTriggerFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -2307,6 +5310,20 @@ pub struct TimeTrigger(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(TimeTrigger, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(TimeTrigger, IBackgroundTrigger); impl TimeTrigger { + pub fn FreshnessTime(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FreshnessTime)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn OneShot(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OneShot)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Create(freshnesstime: u32, oneshot: bool) -> windows_core::Result { Self::ITimeTriggerFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -2478,7 +5495,9 @@ impl windows_core::RuntimeName for WiFiOnDemandHotspotUpdateMetadataTrigger { unsafe impl Send for WiFiOnDemandHotspotUpdateMetadataTrigger {} unsafe impl Sync for WiFiOnDemandHotspotUpdateMetadataTrigger {} } +#[cfg(feature = "ApplicationModel_Calls")] pub mod Calls{ +#[cfg(feature = "ApplicationModel_Calls_Background")] pub mod Background{ #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -2502,7 +5521,27 @@ impl windows_core::RuntimeType for PhoneTriggerType { } } } +#[cfg(feature = "Data")] +pub mod Data{ +#[cfg(feature = "Data_Text")] +pub mod Text{ +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct TextSegment { + pub StartPosition: u32, + pub Length: u32, +} +impl windows_core::TypeKind for TextSegment { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for TextSegment { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"struct(Windows.Data.Text.TextSegment;u4;u4)"); +} +} +} +#[cfg(feature = "Devices")] pub mod Devices{ +#[cfg(feature = "Devices_Bluetooth")] pub mod Bluetooth{ #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -2556,6 +5595,26 @@ impl BluetoothDeviceId { (windows_core::Interface::vtable(this).Id)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn IsClassicDevice(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsClassicDevice)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsLowEnergyDevice(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsLowEnergyDevice)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn FromId(deviceid: &windows_core::HSTRING) -> windows_core::Result { + Self::IBluetoothDeviceIdStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FromId)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IBluetoothDeviceIdStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -2599,6 +5658,39 @@ impl windows_core::RuntimeType for BluetoothError { pub struct BluetoothLEAppearance(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(BluetoothLEAppearance, windows_core::IUnknown, windows_core::IInspectable); impl BluetoothLEAppearance { + pub fn RawValue(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RawValue)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Category(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Category)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SubCategory(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SubCategory)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn FromRawValue(rawvalue: u16) -> windows_core::Result { + Self::IBluetoothLEAppearanceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FromRawValue)(windows_core::Interface::as_raw(this), rawvalue, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn FromParts(appearancecategory: u16, appearancesubcategory: u16) -> windows_core::Result { + Self::IBluetoothLEAppearanceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FromParts)(windows_core::Interface::as_raw(this), appearancecategory, appearancesubcategory, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IBluetoothLEAppearanceStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -2620,6 +5712,29 @@ unsafe impl Sync for BluetoothLEAppearance {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct BluetoothLEConnectionParameters(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(BluetoothLEConnectionParameters, windows_core::IUnknown, windows_core::IInspectable); +impl BluetoothLEConnectionParameters { + pub fn LinkTimeout(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LinkTimeout)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ConnectionLatency(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ConnectionLatency)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ConnectionInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ConnectionInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for BluetoothLEConnectionParameters { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -2636,6 +5751,22 @@ unsafe impl Sync for BluetoothLEConnectionParameters {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct BluetoothLEConnectionPhy(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(BluetoothLEConnectionPhy, windows_core::IUnknown, windows_core::IInspectable); +impl BluetoothLEConnectionPhy { + pub fn TransmitInfo(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TransmitInfo)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ReceiveInfo(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReceiveInfo)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for BluetoothLEConnectionPhy { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -2652,6 +5783,29 @@ unsafe impl Sync for BluetoothLEConnectionPhy {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct BluetoothLEConnectionPhyInfo(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(BluetoothLEConnectionPhyInfo, windows_core::IUnknown, windows_core::IInspectable); +impl BluetoothLEConnectionPhyInfo { + pub fn IsUncoded1MPhy(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsUncoded1MPhy)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsUncoded2MPhy(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsUncoded2MPhy)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsCodedPhy(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsCodedPhy)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for BluetoothLEConnectionPhyInfo { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -2670,6 +5824,13 @@ pub struct BluetoothLEDevice(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(BluetoothLEDevice, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(BluetoothLEDevice, super::super::Foundation::IClosable); impl BluetoothLEDevice { + pub fn DeviceId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } pub fn Name(&self) -> windows_core::Result { let this = self; unsafe { @@ -2677,18 +5838,277 @@ impl BluetoothLEDevice { (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + #[cfg(all(feature = "Devices_Bluetooth_GenericAttributeProfile", feature = "deprecated"))] + pub fn GattServices(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GattServices)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ConnectionStatus(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ConnectionStatus)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn BluetoothAddress(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BluetoothAddress)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(all(feature = "Devices_Bluetooth_GenericAttributeProfile", feature = "deprecated"))] + pub fn GetGattService(&self, serviceuuid: windows_core::GUID) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetGattService)(windows_core::Interface::as_raw(this), serviceuuid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn NameChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NameChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveNameChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveNameChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn GattServicesChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GattServicesChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveGattServicesChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveGattServicesChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn ConnectionStatusChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ConnectionStatusChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveConnectionStatusChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveConnectionStatusChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Devices_Enumeration")] + pub fn DeviceInformation(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceInformation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Appearance(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Appearance)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn BluetoothAddressType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BluetoothAddressType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Devices_Enumeration")] + pub fn DeviceAccessInformation(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceAccessInformation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Devices_Enumeration")] + pub fn RequestAccessAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestAccessAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] + pub fn GetGattServicesAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetGattServicesAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] + pub fn GetGattServicesWithCacheModeAsync(&self, cachemode: BluetoothCacheMode) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetGattServicesWithCacheModeAsync)(windows_core::Interface::as_raw(this), cachemode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] + pub fn GetGattServicesForUuidAsync(&self, serviceuuid: windows_core::GUID) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetGattServicesForUuidAsync)(windows_core::Interface::as_raw(this), serviceuuid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] + pub fn GetGattServicesForUuidWithCacheModeAsync(&self, serviceuuid: windows_core::GUID, cachemode: BluetoothCacheMode) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetGattServicesForUuidWithCacheModeAsync)(windows_core::Interface::as_raw(this), serviceuuid, cachemode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn BluetoothDeviceId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BluetoothDeviceId)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn WasSecureConnectionUsedForPairing(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WasSecureConnectionUsedForPairing)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetConnectionParameters(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetConnectionParameters)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetConnectionPhy(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetConnectionPhy)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RequestPreferredConnectionParameters(&self, preferredconnectionparameters: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestPreferredConnectionParameters)(windows_core::Interface::as_raw(this), preferredconnectionparameters.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ConnectionParametersChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ConnectionParametersChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveConnectionParametersChanged(&self, token: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveConnectionParametersChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn ConnectionPhyChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ConnectionPhyChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveConnectionPhyChanged(&self, token: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveConnectionPhyChanged)(windows_core::Interface::as_raw(this), token).ok() } + } pub fn FromIdAsync(deviceid: &windows_core::HSTRING) -> windows_core::Result> { Self::IBluetoothLEDeviceStatics(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).FromIdAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn FromBluetoothAddressAsync(bluetoothaddress: u64) -> windows_core::Result> { + Self::IBluetoothLEDeviceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FromBluetoothAddressAsync)(windows_core::Interface::as_raw(this), bluetoothaddress, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn GetDeviceSelector() -> windows_core::Result { Self::IBluetoothLEDeviceStatics(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).GetDeviceSelector)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) }) } + pub fn GetDeviceSelectorFromPairingState(pairingstate: bool) -> windows_core::Result { + Self::IBluetoothLEDeviceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeviceSelectorFromPairingState)(windows_core::Interface::as_raw(this), pairingstate, &mut result__).map(|| core::mem::transmute(result__)) + }) + } + pub fn GetDeviceSelectorFromConnectionStatus(connectionstatus: BluetoothConnectionStatus) -> windows_core::Result { + Self::IBluetoothLEDeviceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeviceSelectorFromConnectionStatus)(windows_core::Interface::as_raw(this), connectionstatus, &mut result__).map(|| core::mem::transmute(result__)) + }) + } + pub fn GetDeviceSelectorFromDeviceName(devicename: &windows_core::HSTRING) -> windows_core::Result { + Self::IBluetoothLEDeviceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeviceSelectorFromDeviceName)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(devicename), &mut result__).map(|| core::mem::transmute(result__)) + }) + } + pub fn GetDeviceSelectorFromBluetoothAddress(bluetoothaddress: u64) -> windows_core::Result { + Self::IBluetoothLEDeviceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeviceSelectorFromBluetoothAddress)(windows_core::Interface::as_raw(this), bluetoothaddress, &mut result__).map(|| core::mem::transmute(result__)) + }) + } + pub fn GetDeviceSelectorFromBluetoothAddressWithBluetoothAddressType(bluetoothaddress: u64, bluetoothaddresstype: BluetoothAddressType) -> windows_core::Result { + Self::IBluetoothLEDeviceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeviceSelectorFromBluetoothAddressWithBluetoothAddressType)(windows_core::Interface::as_raw(this), bluetoothaddress, bluetoothaddresstype, &mut result__).map(|| core::mem::transmute(result__)) + }) + } + pub fn GetDeviceSelectorFromAppearance(appearance: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IBluetoothLEDeviceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeviceSelectorFromAppearance)(windows_core::Interface::as_raw(this), appearance.param().abi(), &mut result__).map(|| core::mem::transmute(result__)) + }) + } + pub fn FromBluetoothAddressWithBluetoothAddressTypeAsync(bluetoothaddress: u64, bluetoothaddresstype: BluetoothAddressType) -> windows_core::Result> { + Self::IBluetoothLEDeviceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FromBluetoothAddressWithBluetoothAddressTypeAsync)(windows_core::Interface::as_raw(this), bluetoothaddress, bluetoothaddresstype, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn Close(&self) -> windows_core::Result<()> { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } @@ -2719,6 +6139,52 @@ unsafe impl Sync for BluetoothLEDevice {} pub struct BluetoothLEPreferredConnectionParameters(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(BluetoothLEPreferredConnectionParameters, windows_core::IUnknown, windows_core::IInspectable); impl BluetoothLEPreferredConnectionParameters { + pub fn LinkTimeout(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LinkTimeout)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ConnectionLatency(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ConnectionLatency)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MinConnectionInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinConnectionInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaxConnectionInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxConnectionInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Balanced() -> windows_core::Result { + Self::IBluetoothLEPreferredConnectionParametersStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Balanced)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn ThroughputOptimized() -> windows_core::Result { + Self::IBluetoothLEPreferredConnectionParametersStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ThroughputOptimized)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn PowerOptimized() -> windows_core::Result { + Self::IBluetoothLEPreferredConnectionParametersStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PowerOptimized)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IBluetoothLEPreferredConnectionParametersStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -2742,6 +6208,13 @@ pub struct BluetoothLEPreferredConnectionParametersRequest(windows_core::IUnknow windows_core::imp::interface_hierarchy!(BluetoothLEPreferredConnectionParametersRequest, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(BluetoothLEPreferredConnectionParametersRequest, super::super::Foundation::IClosable); impl BluetoothLEPreferredConnectionParametersRequest { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Close(&self) -> windows_core::Result<()> { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } @@ -2840,7 +6313,63 @@ impl BluetoothSignalStrengthFilter { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn InRangeThresholdInDBm(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InRangeThresholdInDBm)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn SetInRangeThresholdInDBm(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetInRangeThresholdInDBm)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn OutOfRangeThresholdInDBm(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OutOfRangeThresholdInDBm)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetOutOfRangeThresholdInDBm(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetOutOfRangeThresholdInDBm)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn OutOfRangeTimeout(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OutOfRangeTimeout)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetOutOfRangeTimeout(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetOutOfRangeTimeout)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn SamplingInterval(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SamplingInterval)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetSamplingInterval(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSamplingInterval)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } +} impl windows_core::RuntimeType for BluetoothSignalStrengthFilter { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -2857,6 +6386,64 @@ windows_core::imp::define_interface!(IBluetoothDeviceId, IBluetoothDeviceId_Vtbl impl windows_core::RuntimeType for IBluetoothDeviceId { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothDeviceId { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothDeviceId"; +} +pub trait IBluetoothDeviceId_Impl: windows_core::IUnknownImpl { + fn Id(&self) -> windows_core::Result; + fn IsClassicDevice(&self) -> windows_core::Result; + fn IsLowEnergyDevice(&self) -> windows_core::Result; +} +impl IBluetoothDeviceId_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Id(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothDeviceId_Impl::Id(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsClassicDevice(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothDeviceId_Impl::IsClassicDevice(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsLowEnergyDevice(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothDeviceId_Impl::IsLowEnergyDevice(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Id: Id::, + IsClassicDevice: IsClassicDevice::, + IsLowEnergyDevice: IsLowEnergyDevice::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothDeviceId_Vtbl { @@ -2869,6 +6456,33 @@ windows_core::imp::define_interface!(IBluetoothDeviceIdStatics, IBluetoothDevice impl windows_core::RuntimeType for IBluetoothDeviceIdStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothDeviceIdStatics { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothDeviceIdStatics"; +} +pub trait IBluetoothDeviceIdStatics_Impl: windows_core::IUnknownImpl { + fn FromId(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result; +} +impl IBluetoothDeviceIdStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FromId(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothDeviceIdStatics_Impl::FromId(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), FromId: FromId:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothDeviceIdStatics_Vtbl { @@ -2879,6 +6493,63 @@ windows_core::imp::define_interface!(IBluetoothLEAppearance, IBluetoothLEAppeara impl windows_core::RuntimeType for IBluetoothLEAppearance { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEAppearance { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEAppearance"; +} +pub trait IBluetoothLEAppearance_Impl: windows_core::IUnknownImpl { + fn RawValue(&self) -> windows_core::Result; + fn Category(&self) -> windows_core::Result; + fn SubCategory(&self) -> windows_core::Result; +} +impl IBluetoothLEAppearance_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn RawValue(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAppearance_Impl::RawValue(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Category(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAppearance_Impl::Category(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SubCategory(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAppearance_Impl::SubCategory(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + RawValue: RawValue::, + Category: Category::, + SubCategory: SubCategory::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEAppearance_Vtbl { @@ -2891,6 +6562,51 @@ windows_core::imp::define_interface!(IBluetoothLEAppearanceStatics, IBluetoothLE impl windows_core::RuntimeType for IBluetoothLEAppearanceStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEAppearanceStatics { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEAppearanceStatics"; +} +pub trait IBluetoothLEAppearanceStatics_Impl: windows_core::IUnknownImpl { + fn FromRawValue(&self, rawValue: u16) -> windows_core::Result; + fn FromParts(&self, appearanceCategory: u16, appearanceSubCategory: u16) -> windows_core::Result; +} +impl IBluetoothLEAppearanceStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FromRawValue(this: *mut core::ffi::c_void, rawvalue: u16, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAppearanceStatics_Impl::FromRawValue(this, rawvalue) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FromParts(this: *mut core::ffi::c_void, appearancecategory: u16, appearancesubcategory: u16, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAppearanceStatics_Impl::FromParts(this, appearancecategory, appearancesubcategory) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FromRawValue: FromRawValue::, + FromParts: FromParts::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEAppearanceStatics_Vtbl { @@ -2902,6 +6618,63 @@ windows_core::imp::define_interface!(IBluetoothLEConnectionParameters, IBluetoot impl windows_core::RuntimeType for IBluetoothLEConnectionParameters { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEConnectionParameters { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEConnectionParameters"; +} +pub trait IBluetoothLEConnectionParameters_Impl: windows_core::IUnknownImpl { + fn LinkTimeout(&self) -> windows_core::Result; + fn ConnectionLatency(&self) -> windows_core::Result; + fn ConnectionInterval(&self) -> windows_core::Result; +} +impl IBluetoothLEConnectionParameters_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn LinkTimeout(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEConnectionParameters_Impl::LinkTimeout(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ConnectionLatency(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEConnectionParameters_Impl::ConnectionLatency(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ConnectionInterval(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEConnectionParameters_Impl::ConnectionInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + LinkTimeout: LinkTimeout::, + ConnectionLatency: ConnectionLatency::, + ConnectionInterval: ConnectionInterval::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEConnectionParameters_Vtbl { @@ -2914,6 +6687,51 @@ windows_core::imp::define_interface!(IBluetoothLEConnectionPhy, IBluetoothLEConn impl windows_core::RuntimeType for IBluetoothLEConnectionPhy { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEConnectionPhy { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEConnectionPhy"; +} +pub trait IBluetoothLEConnectionPhy_Impl: windows_core::IUnknownImpl { + fn TransmitInfo(&self) -> windows_core::Result; + fn ReceiveInfo(&self) -> windows_core::Result; +} +impl IBluetoothLEConnectionPhy_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TransmitInfo(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEConnectionPhy_Impl::TransmitInfo(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReceiveInfo(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEConnectionPhy_Impl::ReceiveInfo(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + TransmitInfo: TransmitInfo::, + ReceiveInfo: ReceiveInfo::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEConnectionPhy_Vtbl { @@ -2925,6 +6743,63 @@ windows_core::imp::define_interface!(IBluetoothLEConnectionPhyInfo, IBluetoothLE impl windows_core::RuntimeType for IBluetoothLEConnectionPhyInfo { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEConnectionPhyInfo { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEConnectionPhyInfo"; +} +pub trait IBluetoothLEConnectionPhyInfo_Impl: windows_core::IUnknownImpl { + fn IsUncoded1MPhy(&self) -> windows_core::Result; + fn IsUncoded2MPhy(&self) -> windows_core::Result; + fn IsCodedPhy(&self) -> windows_core::Result; +} +impl IBluetoothLEConnectionPhyInfo_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsUncoded1MPhy(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEConnectionPhyInfo_Impl::IsUncoded1MPhy(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsUncoded2MPhy(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEConnectionPhyInfo_Impl::IsUncoded2MPhy(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsCodedPhy(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEConnectionPhyInfo_Impl::IsCodedPhy(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsUncoded1MPhy: IsUncoded1MPhy::, + IsUncoded2MPhy: IsUncoded2MPhy::, + IsCodedPhy: IsCodedPhy::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEConnectionPhyInfo_Vtbl { @@ -2937,21 +6812,193 @@ windows_core::imp::define_interface!(IBluetoothLEDevice, IBluetoothLEDevice_Vtbl impl windows_core::RuntimeType for IBluetoothLEDevice { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] +impl windows_core::RuntimeName for IBluetoothLEDevice { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEDevice"; +} +#[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] +pub trait IBluetoothLEDevice_Impl: windows_core::IUnknownImpl { + fn DeviceId(&self) -> windows_core::Result; + fn Name(&self) -> windows_core::Result; + fn GattServices(&self) -> windows_core::Result>; + fn ConnectionStatus(&self) -> windows_core::Result; + fn BluetoothAddress(&self) -> windows_core::Result; + fn GetGattService(&self, serviceUuid: &windows_core::GUID) -> windows_core::Result; + fn NameChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveNameChanged(&self, token: i64) -> windows_core::Result<()>; + fn GattServicesChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveGattServicesChanged(&self, token: i64) -> windows_core::Result<()>; + fn ConnectionStatusChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveConnectionStatusChanged(&self, token: i64) -> windows_core::Result<()>; +} +#[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] +impl IBluetoothLEDevice_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Name(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice_Impl::Name(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GattServices(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice_Impl::GattServices(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ConnectionStatus(this: *mut core::ffi::c_void, result__: *mut BluetoothConnectionStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice_Impl::ConnectionStatus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn BluetoothAddress(this: *mut core::ffi::c_void, result__: *mut u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice_Impl::BluetoothAddress(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetGattService(this: *mut core::ffi::c_void, serviceuuid: windows_core::GUID, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice_Impl::GetGattService(this, core::mem::transmute(&serviceuuid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NameChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice_Impl::NameChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveNameChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEDevice_Impl::RemoveNameChanged(this, token).into() + } + } + unsafe extern "system" fn GattServicesChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice_Impl::GattServicesChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveGattServicesChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEDevice_Impl::RemoveGattServicesChanged(this, token).into() + } + } + unsafe extern "system" fn ConnectionStatusChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice_Impl::ConnectionStatusChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveConnectionStatusChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEDevice_Impl::RemoveConnectionStatusChanged(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DeviceId: DeviceId::, + Name: Name::, + GattServices: GattServices::, + ConnectionStatus: ConnectionStatus::, + BluetoothAddress: BluetoothAddress::, + GetGattService: GetGattService::, + NameChanged: NameChanged::, + RemoveNameChanged: RemoveNameChanged::, + GattServicesChanged: GattServicesChanged::, + RemoveGattServicesChanged: RemoveGattServicesChanged::, + ConnectionStatusChanged: ConnectionStatusChanged::, + RemoveConnectionStatusChanged: RemoveConnectionStatusChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEDevice_Vtbl { pub base__: windows_core::IInspectable_Vtbl, pub DeviceId: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, pub Name: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, - #[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] + #[cfg(all(feature = "Devices_Bluetooth_GenericAttributeProfile", feature = "deprecated"))] pub GattServices: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, - #[cfg(not(feature = "Devices_Bluetooth_GenericAttributeProfile"))] + #[cfg(not(all(feature = "Devices_Bluetooth_GenericAttributeProfile", feature = "deprecated")))] GattServices: usize, pub ConnectionStatus: unsafe extern "system" fn(*mut core::ffi::c_void, *mut BluetoothConnectionStatus) -> windows_core::HRESULT, pub BluetoothAddress: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u64) -> windows_core::HRESULT, - #[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] + #[cfg(all(feature = "Devices_Bluetooth_GenericAttributeProfile", feature = "deprecated"))] pub GetGattService: unsafe extern "system" fn(*mut core::ffi::c_void, windows_core::GUID, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, - #[cfg(not(feature = "Devices_Bluetooth_GenericAttributeProfile"))] + #[cfg(not(all(feature = "Devices_Bluetooth_GenericAttributeProfile", feature = "deprecated")))] GetGattService: usize, pub NameChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, pub RemoveNameChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, @@ -2964,6 +7011,68 @@ windows_core::imp::define_interface!(IBluetoothLEDevice2, IBluetoothLEDevice2_Vt impl windows_core::RuntimeType for IBluetoothLEDevice2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Enumeration")] +impl windows_core::RuntimeName for IBluetoothLEDevice2 { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEDevice2"; +} +#[cfg(feature = "Devices_Enumeration")] +pub trait IBluetoothLEDevice2_Impl: windows_core::IUnknownImpl { + fn DeviceInformation(&self) -> windows_core::Result; + fn Appearance(&self) -> windows_core::Result; + fn BluetoothAddressType(&self) -> windows_core::Result; +} +#[cfg(feature = "Devices_Enumeration")] +impl IBluetoothLEDevice2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceInformation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice2_Impl::DeviceInformation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Appearance(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice2_Impl::Appearance(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn BluetoothAddressType(this: *mut core::ffi::c_void, result__: *mut BluetoothAddressType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice2_Impl::BluetoothAddressType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DeviceInformation: DeviceInformation::, + Appearance: Appearance::, + BluetoothAddressType: BluetoothAddressType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEDevice2_Vtbl { @@ -2979,6 +7088,114 @@ windows_core::imp::define_interface!(IBluetoothLEDevice3, IBluetoothLEDevice3_Vt impl windows_core::RuntimeType for IBluetoothLEDevice3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(all(feature = "Devices_Bluetooth_GenericAttributeProfile", feature = "Devices_Enumeration"))] +impl windows_core::RuntimeName for IBluetoothLEDevice3 { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEDevice3"; +} +#[cfg(all(feature = "Devices_Bluetooth_GenericAttributeProfile", feature = "Devices_Enumeration"))] +pub trait IBluetoothLEDevice3_Impl: windows_core::IUnknownImpl { + fn DeviceAccessInformation(&self) -> windows_core::Result; + fn RequestAccessAsync(&self) -> windows_core::Result>; + fn GetGattServicesAsync(&self) -> windows_core::Result>; + fn GetGattServicesWithCacheModeAsync(&self, cacheMode: BluetoothCacheMode) -> windows_core::Result>; + fn GetGattServicesForUuidAsync(&self, serviceUuid: &windows_core::GUID) -> windows_core::Result>; + fn GetGattServicesForUuidWithCacheModeAsync(&self, serviceUuid: &windows_core::GUID, cacheMode: BluetoothCacheMode) -> windows_core::Result>; +} +#[cfg(all(feature = "Devices_Bluetooth_GenericAttributeProfile", feature = "Devices_Enumeration"))] +impl IBluetoothLEDevice3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceAccessInformation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice3_Impl::DeviceAccessInformation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RequestAccessAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice3_Impl::RequestAccessAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetGattServicesAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice3_Impl::GetGattServicesAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetGattServicesWithCacheModeAsync(this: *mut core::ffi::c_void, cachemode: BluetoothCacheMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice3_Impl::GetGattServicesWithCacheModeAsync(this, cachemode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetGattServicesForUuidAsync(this: *mut core::ffi::c_void, serviceuuid: windows_core::GUID, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice3_Impl::GetGattServicesForUuidAsync(this, core::mem::transmute(&serviceuuid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetGattServicesForUuidWithCacheModeAsync(this: *mut core::ffi::c_void, serviceuuid: windows_core::GUID, cachemode: BluetoothCacheMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice3_Impl::GetGattServicesForUuidWithCacheModeAsync(this, core::mem::transmute(&serviceuuid), cachemode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DeviceAccessInformation: DeviceAccessInformation::, + RequestAccessAsync: RequestAccessAsync::, + GetGattServicesAsync: GetGattServicesAsync::, + GetGattServicesWithCacheModeAsync: GetGattServicesWithCacheModeAsync::, + GetGattServicesForUuidAsync: GetGattServicesForUuidAsync::, + GetGattServicesForUuidWithCacheModeAsync: GetGattServicesForUuidWithCacheModeAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEDevice3_Vtbl { @@ -3012,6 +7229,36 @@ windows_core::imp::define_interface!(IBluetoothLEDevice4, IBluetoothLEDevice4_Vt impl windows_core::RuntimeType for IBluetoothLEDevice4 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEDevice4 { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEDevice4"; +} +pub trait IBluetoothLEDevice4_Impl: windows_core::IUnknownImpl { + fn BluetoothDeviceId(&self) -> windows_core::Result; +} +impl IBluetoothLEDevice4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn BluetoothDeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice4_Impl::BluetoothDeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + BluetoothDeviceId: BluetoothDeviceId::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEDevice4_Vtbl { @@ -3022,6 +7269,35 @@ windows_core::imp::define_interface!(IBluetoothLEDevice5, IBluetoothLEDevice5_Vt impl windows_core::RuntimeType for IBluetoothLEDevice5 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEDevice5 { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEDevice5"; +} +pub trait IBluetoothLEDevice5_Impl: windows_core::IUnknownImpl { + fn WasSecureConnectionUsedForPairing(&self) -> windows_core::Result; +} +impl IBluetoothLEDevice5_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn WasSecureConnectionUsedForPairing(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice5_Impl::WasSecureConnectionUsedForPairing(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + WasSecureConnectionUsedForPairing: WasSecureConnectionUsedForPairing::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEDevice5_Vtbl { @@ -3032,6 +7308,110 @@ windows_core::imp::define_interface!(IBluetoothLEDevice6, IBluetoothLEDevice6_Vt impl windows_core::RuntimeType for IBluetoothLEDevice6 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEDevice6 { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEDevice6"; +} +pub trait IBluetoothLEDevice6_Impl: windows_core::IUnknownImpl { + fn GetConnectionParameters(&self) -> windows_core::Result; + fn GetConnectionPhy(&self) -> windows_core::Result; + fn RequestPreferredConnectionParameters(&self, preferredConnectionParameters: windows_core::Ref<'_, BluetoothLEPreferredConnectionParameters>) -> windows_core::Result; + fn ConnectionParametersChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveConnectionParametersChanged(&self, token: i64) -> windows_core::Result<()>; + fn ConnectionPhyChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveConnectionPhyChanged(&self, token: i64) -> windows_core::Result<()>; +} +impl IBluetoothLEDevice6_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetConnectionParameters(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice6_Impl::GetConnectionParameters(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetConnectionPhy(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice6_Impl::GetConnectionPhy(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RequestPreferredConnectionParameters(this: *mut core::ffi::c_void, preferredconnectionparameters: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice6_Impl::RequestPreferredConnectionParameters(this, core::mem::transmute_copy(&preferredconnectionparameters)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ConnectionParametersChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice6_Impl::ConnectionParametersChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveConnectionParametersChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEDevice6_Impl::RemoveConnectionParametersChanged(this, token).into() + } + } + unsafe extern "system" fn ConnectionPhyChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDevice6_Impl::ConnectionPhyChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveConnectionPhyChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEDevice6_Impl::RemoveConnectionPhyChanged(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetConnectionParameters: GetConnectionParameters::, + GetConnectionPhy: GetConnectionPhy::, + RequestPreferredConnectionParameters: RequestPreferredConnectionParameters::, + ConnectionParametersChanged: ConnectionParametersChanged::, + RemoveConnectionParametersChanged: RemoveConnectionParametersChanged::, + ConnectionPhyChanged: ConnectionPhyChanged::, + RemoveConnectionPhyChanged: RemoveConnectionPhyChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEDevice6_Vtbl { @@ -3048,6 +7428,66 @@ windows_core::imp::define_interface!(IBluetoothLEDeviceStatics, IBluetoothLEDevi impl windows_core::RuntimeType for IBluetoothLEDeviceStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEDeviceStatics { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEDeviceStatics"; +} +pub trait IBluetoothLEDeviceStatics_Impl: windows_core::IUnknownImpl { + fn FromIdAsync(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; + fn FromBluetoothAddressAsync(&self, bluetoothAddress: u64) -> windows_core::Result>; + fn GetDeviceSelector(&self) -> windows_core::Result; +} +impl IBluetoothLEDeviceStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FromIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDeviceStatics_Impl::FromIdAsync(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FromBluetoothAddressAsync(this: *mut core::ffi::c_void, bluetoothaddress: u64, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDeviceStatics_Impl::FromBluetoothAddressAsync(this, bluetoothaddress) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelector(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDeviceStatics_Impl::GetDeviceSelector(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FromIdAsync: FromIdAsync::, + FromBluetoothAddressAsync: FromBluetoothAddressAsync::, + GetDeviceSelector: GetDeviceSelector::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEDeviceStatics_Vtbl { @@ -3060,6 +7500,126 @@ windows_core::imp::define_interface!(IBluetoothLEDeviceStatics2, IBluetoothLEDev impl windows_core::RuntimeType for IBluetoothLEDeviceStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEDeviceStatics2 { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEDeviceStatics2"; +} +pub trait IBluetoothLEDeviceStatics2_Impl: windows_core::IUnknownImpl { + fn GetDeviceSelectorFromPairingState(&self, pairingState: bool) -> windows_core::Result; + fn GetDeviceSelectorFromConnectionStatus(&self, connectionStatus: BluetoothConnectionStatus) -> windows_core::Result; + fn GetDeviceSelectorFromDeviceName(&self, deviceName: &windows_core::HSTRING) -> windows_core::Result; + fn GetDeviceSelectorFromBluetoothAddress(&self, bluetoothAddress: u64) -> windows_core::Result; + fn GetDeviceSelectorFromBluetoothAddressWithBluetoothAddressType(&self, bluetoothAddress: u64, bluetoothAddressType: BluetoothAddressType) -> windows_core::Result; + fn GetDeviceSelectorFromAppearance(&self, appearance: windows_core::Ref<'_, BluetoothLEAppearance>) -> windows_core::Result; + fn FromBluetoothAddressWithBluetoothAddressTypeAsync(&self, bluetoothAddress: u64, bluetoothAddressType: BluetoothAddressType) -> windows_core::Result>; +} +impl IBluetoothLEDeviceStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDeviceSelectorFromPairingState(this: *mut core::ffi::c_void, pairingstate: bool, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDeviceStatics2_Impl::GetDeviceSelectorFromPairingState(this, pairingstate) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelectorFromConnectionStatus(this: *mut core::ffi::c_void, connectionstatus: BluetoothConnectionStatus, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDeviceStatics2_Impl::GetDeviceSelectorFromConnectionStatus(this, connectionstatus) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelectorFromDeviceName(this: *mut core::ffi::c_void, devicename: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDeviceStatics2_Impl::GetDeviceSelectorFromDeviceName(this, core::mem::transmute(&devicename)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelectorFromBluetoothAddress(this: *mut core::ffi::c_void, bluetoothaddress: u64, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDeviceStatics2_Impl::GetDeviceSelectorFromBluetoothAddress(this, bluetoothaddress) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelectorFromBluetoothAddressWithBluetoothAddressType(this: *mut core::ffi::c_void, bluetoothaddress: u64, bluetoothaddresstype: BluetoothAddressType, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDeviceStatics2_Impl::GetDeviceSelectorFromBluetoothAddressWithBluetoothAddressType(this, bluetoothaddress, bluetoothaddresstype) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelectorFromAppearance(this: *mut core::ffi::c_void, appearance: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDeviceStatics2_Impl::GetDeviceSelectorFromAppearance(this, core::mem::transmute_copy(&appearance)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FromBluetoothAddressWithBluetoothAddressTypeAsync(this: *mut core::ffi::c_void, bluetoothaddress: u64, bluetoothaddresstype: BluetoothAddressType, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEDeviceStatics2_Impl::FromBluetoothAddressWithBluetoothAddressTypeAsync(this, bluetoothaddress, bluetoothaddresstype) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDeviceSelectorFromPairingState: GetDeviceSelectorFromPairingState::, + GetDeviceSelectorFromConnectionStatus: GetDeviceSelectorFromConnectionStatus::, + GetDeviceSelectorFromDeviceName: GetDeviceSelectorFromDeviceName::, + GetDeviceSelectorFromBluetoothAddress: GetDeviceSelectorFromBluetoothAddress::, + GetDeviceSelectorFromBluetoothAddressWithBluetoothAddressType: GetDeviceSelectorFromBluetoothAddressWithBluetoothAddressType::, + GetDeviceSelectorFromAppearance: GetDeviceSelectorFromAppearance::, + FromBluetoothAddressWithBluetoothAddressTypeAsync: FromBluetoothAddressWithBluetoothAddressTypeAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEDeviceStatics2_Vtbl { @@ -3076,6 +7636,77 @@ windows_core::imp::define_interface!(IBluetoothLEPreferredConnectionParameters, impl windows_core::RuntimeType for IBluetoothLEPreferredConnectionParameters { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEPreferredConnectionParameters { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEPreferredConnectionParameters"; +} +pub trait IBluetoothLEPreferredConnectionParameters_Impl: windows_core::IUnknownImpl { + fn LinkTimeout(&self) -> windows_core::Result; + fn ConnectionLatency(&self) -> windows_core::Result; + fn MinConnectionInterval(&self) -> windows_core::Result; + fn MaxConnectionInterval(&self) -> windows_core::Result; +} +impl IBluetoothLEPreferredConnectionParameters_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn LinkTimeout(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEPreferredConnectionParameters_Impl::LinkTimeout(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ConnectionLatency(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEPreferredConnectionParameters_Impl::ConnectionLatency(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MinConnectionInterval(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEPreferredConnectionParameters_Impl::MinConnectionInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxConnectionInterval(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEPreferredConnectionParameters_Impl::MaxConnectionInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + LinkTimeout: LinkTimeout::, + ConnectionLatency: ConnectionLatency::, + MinConnectionInterval: MinConnectionInterval::, + MaxConnectionInterval: MaxConnectionInterval::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEPreferredConnectionParameters_Vtbl { @@ -3089,6 +7720,35 @@ windows_core::imp::define_interface!(IBluetoothLEPreferredConnectionParametersRe impl windows_core::RuntimeType for IBluetoothLEPreferredConnectionParametersRequest { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEPreferredConnectionParametersRequest { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEPreferredConnectionParametersRequest"; +} +pub trait IBluetoothLEPreferredConnectionParametersRequest_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; +} +impl IBluetoothLEPreferredConnectionParametersRequest_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut BluetoothLEPreferredConnectionParametersRequestStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEPreferredConnectionParametersRequest_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Status: Status::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEPreferredConnectionParametersRequest_Vtbl { @@ -3099,6 +7759,66 @@ windows_core::imp::define_interface!(IBluetoothLEPreferredConnectionParametersSt impl windows_core::RuntimeType for IBluetoothLEPreferredConnectionParametersStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEPreferredConnectionParametersStatics { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothLEPreferredConnectionParametersStatics"; +} +pub trait IBluetoothLEPreferredConnectionParametersStatics_Impl: windows_core::IUnknownImpl { + fn Balanced(&self) -> windows_core::Result; + fn ThroughputOptimized(&self) -> windows_core::Result; + fn PowerOptimized(&self) -> windows_core::Result; +} +impl IBluetoothLEPreferredConnectionParametersStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Balanced(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEPreferredConnectionParametersStatics_Impl::Balanced(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ThroughputOptimized(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEPreferredConnectionParametersStatics_Impl::ThroughputOptimized(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PowerOptimized(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEPreferredConnectionParametersStatics_Impl::PowerOptimized(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Balanced: Balanced::, + ThroughputOptimized: ThroughputOptimized::, + PowerOptimized: PowerOptimized::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEPreferredConnectionParametersStatics_Vtbl { @@ -3111,6 +7831,113 @@ windows_core::imp::define_interface!(IBluetoothSignalStrengthFilter, IBluetoothS impl windows_core::RuntimeType for IBluetoothSignalStrengthFilter { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothSignalStrengthFilter { + const NAME: &'static str = "Windows.Devices.Bluetooth.IBluetoothSignalStrengthFilter"; +} +pub trait IBluetoothSignalStrengthFilter_Impl: windows_core::IUnknownImpl { + fn InRangeThresholdInDBm(&self) -> windows_core::Result>; + fn SetInRangeThresholdInDBm(&self, value: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn OutOfRangeThresholdInDBm(&self) -> windows_core::Result>; + fn SetOutOfRangeThresholdInDBm(&self, value: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn OutOfRangeTimeout(&self) -> windows_core::Result>; + fn SetOutOfRangeTimeout(&self, value: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn SamplingInterval(&self) -> windows_core::Result>; + fn SetSamplingInterval(&self, value: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result<()>; +} +impl IBluetoothSignalStrengthFilter_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn InRangeThresholdInDBm(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothSignalStrengthFilter_Impl::InRangeThresholdInDBm(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetInRangeThresholdInDBm(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothSignalStrengthFilter_Impl::SetInRangeThresholdInDBm(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn OutOfRangeThresholdInDBm(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothSignalStrengthFilter_Impl::OutOfRangeThresholdInDBm(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetOutOfRangeThresholdInDBm(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothSignalStrengthFilter_Impl::SetOutOfRangeThresholdInDBm(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn OutOfRangeTimeout(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothSignalStrengthFilter_Impl::OutOfRangeTimeout(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetOutOfRangeTimeout(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothSignalStrengthFilter_Impl::SetOutOfRangeTimeout(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn SamplingInterval(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothSignalStrengthFilter_Impl::SamplingInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetSamplingInterval(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothSignalStrengthFilter_Impl::SetSamplingInterval(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + InRangeThresholdInDBm: InRangeThresholdInDBm::, + SetInRangeThresholdInDBm: SetInRangeThresholdInDBm::, + OutOfRangeThresholdInDBm: OutOfRangeThresholdInDBm::, + SetOutOfRangeThresholdInDBm: SetOutOfRangeThresholdInDBm::, + OutOfRangeTimeout: OutOfRangeTimeout::, + SetOutOfRangeTimeout: SetOutOfRangeTimeout::, + SamplingInterval: SamplingInterval::, + SetSamplingInterval: SetSamplingInterval::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothSignalStrengthFilter_Vtbl { @@ -3124,6 +7951,7 @@ pub struct IBluetoothSignalStrengthFilter_Vtbl { pub SamplingInterval: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, pub SetSamplingInterval: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, } +#[cfg(feature = "Devices_Bluetooth_Advertisement")] pub mod Advertisement{ #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] @@ -3137,7 +7965,67 @@ impl BluetoothLEAdvertisement { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn Flags(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Flags)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn SetFlags(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetFlags)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn LocalName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LocalName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetLocalName(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetLocalName)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn ServiceUuids(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ServiceUuids)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ManufacturerData(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ManufacturerData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DataSections(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DataSections)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetManufacturerDataByCompanyId(&self, companyid: u16) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetManufacturerDataByCompanyId)(windows_core::Interface::as_raw(this), companyid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetSectionsByType(&self, r#type: u8) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetSectionsByType)(windows_core::Interface::as_raw(this), r#type, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for BluetoothLEAdvertisement { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -3162,6 +8050,44 @@ impl BluetoothLEAdvertisementBytePattern { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn DataType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DataType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetDataType(&self, value: u8) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDataType)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Offset(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Offset)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetOffset(&self, value: i16) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetOffset)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn Data(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Data)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn SetData(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetData)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } #[cfg(feature = "Storage_Streams")] pub fn Create(datatype: u8, offset: i16, data: P2) -> windows_core::Result where @@ -3201,6 +8127,33 @@ impl BluetoothLEAdvertisementDataSection { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn DataType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DataType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetDataType(&self, value: u8) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDataType)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn Data(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Data)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn SetData(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetData)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } #[cfg(feature = "Storage_Streams")] pub fn Create(datatype: u8, data: P1) -> windows_core::Result where @@ -3240,7 +8193,28 @@ impl BluetoothLEAdvertisementFilter { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn Advertisement(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Advertisement)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn SetAdvertisement(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAdvertisement)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn BytePatterns(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BytePatterns)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for BluetoothLEAdvertisementFilter { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -3304,43 +8278,6 @@ impl core::ops::Not for BluetoothLEAdvertisementFlags { } } #[repr(transparent)] -#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] -pub struct BluetoothLEAdvertisementPhyType(pub i32); -impl BluetoothLEAdvertisementPhyType { - pub const Unspecified: Self = Self(0i32); - pub const Uncoded1MPhy: Self = Self(1i32); - pub const Uncoded2MPhy: Self = Self(2i32); - pub const CodedPhy: Self = Self(3i32); -} -impl windows_core::TypeKind for BluetoothLEAdvertisementPhyType { - type TypeKind = windows_core::CopyType; -} -impl windows_core::RuntimeType for BluetoothLEAdvertisementPhyType { - const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementPhyType;i4)"); -} -#[repr(transparent)] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct BluetoothLEAdvertisementScanParameters(windows_core::IUnknown); -windows_core::imp::interface_hierarchy!(BluetoothLEAdvertisementScanParameters, windows_core::IUnknown, windows_core::IInspectable); -impl BluetoothLEAdvertisementScanParameters { - fn IBluetoothLEAdvertisementScanParametersStatics windows_core::Result>(callback: F) -> windows_core::Result { - static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); - SHARED.call(callback) - } -} -impl windows_core::RuntimeType for BluetoothLEAdvertisementScanParameters { - const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); -} -unsafe impl windows_core::Interface for BluetoothLEAdvertisementScanParameters { - type Vtable = ::Vtable; - const IID: windows_core::GUID = ::IID; -} -impl windows_core::RuntimeName for BluetoothLEAdvertisementScanParameters { - const NAME: &'static str = "Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementScanParameters"; -} -unsafe impl Send for BluetoothLEAdvertisementScanParameters {} -unsafe impl Sync for BluetoothLEAdvertisementScanParameters {} -#[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] pub struct BluetoothLEManufacturerData(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(BluetoothLEManufacturerData, windows_core::IUnknown, windows_core::IInspectable); @@ -3352,6 +8289,33 @@ impl BluetoothLEManufacturerData { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn CompanyId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CompanyId)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetCompanyId(&self, value: u16) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetCompanyId)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn Data(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Data)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn SetData(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetData)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } #[cfg(feature = "Storage_Streams")] pub fn Create(companyid: u16, data: P1) -> windows_core::Result where @@ -3383,6 +8347,142 @@ windows_core::imp::define_interface!(IBluetoothLEAdvertisement, IBluetoothLEAdve impl windows_core::RuntimeType for IBluetoothLEAdvertisement { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEAdvertisement { + const NAME: &'static str = "Windows.Devices.Bluetooth.Advertisement.IBluetoothLEAdvertisement"; +} +pub trait IBluetoothLEAdvertisement_Impl: windows_core::IUnknownImpl { + fn Flags(&self) -> windows_core::Result>; + fn SetFlags(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn LocalName(&self) -> windows_core::Result; + fn SetLocalName(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn ServiceUuids(&self) -> windows_core::Result>; + fn ManufacturerData(&self) -> windows_core::Result>; + fn DataSections(&self) -> windows_core::Result>; + fn GetManufacturerDataByCompanyId(&self, companyId: u16) -> windows_core::Result>; + fn GetSectionsByType(&self, r#type: u8) -> windows_core::Result>; +} +impl IBluetoothLEAdvertisement_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Flags(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisement_Impl::Flags(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetFlags(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEAdvertisement_Impl::SetFlags(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn LocalName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisement_Impl::LocalName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetLocalName(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEAdvertisement_Impl::SetLocalName(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn ServiceUuids(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisement_Impl::ServiceUuids(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ManufacturerData(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisement_Impl::ManufacturerData(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DataSections(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisement_Impl::DataSections(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetManufacturerDataByCompanyId(this: *mut core::ffi::c_void, companyid: u16, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisement_Impl::GetManufacturerDataByCompanyId(this, companyid) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetSectionsByType(this: *mut core::ffi::c_void, r#type: u8, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisement_Impl::GetSectionsByType(this, r#type) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Flags: Flags::, + SetFlags: SetFlags::, + LocalName: LocalName::, + SetLocalName: SetLocalName::, + ServiceUuids: ServiceUuids::, + ManufacturerData: ManufacturerData::, + DataSections: DataSections::, + GetManufacturerDataByCompanyId: GetManufacturerDataByCompanyId::, + GetSectionsByType: GetSectionsByType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEAdvertisement_Vtbl { @@ -3401,6 +8501,91 @@ windows_core::imp::define_interface!(IBluetoothLEAdvertisementBytePattern, IBlue impl windows_core::RuntimeType for IBluetoothLEAdvertisementBytePattern { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IBluetoothLEAdvertisementBytePattern { + const NAME: &'static str = "Windows.Devices.Bluetooth.Advertisement.IBluetoothLEAdvertisementBytePattern"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IBluetoothLEAdvertisementBytePattern_Impl: windows_core::IUnknownImpl { + fn DataType(&self) -> windows_core::Result; + fn SetDataType(&self, value: u8) -> windows_core::Result<()>; + fn Offset(&self) -> windows_core::Result; + fn SetOffset(&self, value: i16) -> windows_core::Result<()>; + fn Data(&self) -> windows_core::Result; + fn SetData(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result<()>; +} +#[cfg(feature = "Storage_Streams")] +impl IBluetoothLEAdvertisementBytePattern_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DataType(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementBytePattern_Impl::DataType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDataType(this: *mut core::ffi::c_void, value: u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEAdvertisementBytePattern_Impl::SetDataType(this, value).into() + } + } + unsafe extern "system" fn Offset(this: *mut core::ffi::c_void, result__: *mut i16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementBytePattern_Impl::Offset(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetOffset(this: *mut core::ffi::c_void, value: i16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEAdvertisementBytePattern_Impl::SetOffset(this, value).into() + } + } + unsafe extern "system" fn Data(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementBytePattern_Impl::Data(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetData(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEAdvertisementBytePattern_Impl::SetData(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DataType: DataType::, + SetDataType: SetDataType::, + Offset: Offset::, + SetOffset: SetOffset::, + Data: Data::, + SetData: SetData::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEAdvertisementBytePattern_Vtbl { @@ -3422,6 +8607,39 @@ windows_core::imp::define_interface!(IBluetoothLEAdvertisementBytePatternFactory impl windows_core::RuntimeType for IBluetoothLEAdvertisementBytePatternFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IBluetoothLEAdvertisementBytePatternFactory { + const NAME: &'static str = "Windows.Devices.Bluetooth.Advertisement.IBluetoothLEAdvertisementBytePatternFactory"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IBluetoothLEAdvertisementBytePatternFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, dataType: u8, offset: i16, data: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IBluetoothLEAdvertisementBytePatternFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, datatype: u8, offset: i16, data: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementBytePatternFactory_Impl::Create(this, datatype, offset, core::mem::transmute_copy(&data)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Create: Create::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEAdvertisementBytePatternFactory_Vtbl { @@ -3435,6 +8653,69 @@ windows_core::imp::define_interface!(IBluetoothLEAdvertisementDataSection, IBlue impl windows_core::RuntimeType for IBluetoothLEAdvertisementDataSection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IBluetoothLEAdvertisementDataSection { + const NAME: &'static str = "Windows.Devices.Bluetooth.Advertisement.IBluetoothLEAdvertisementDataSection"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IBluetoothLEAdvertisementDataSection_Impl: windows_core::IUnknownImpl { + fn DataType(&self) -> windows_core::Result; + fn SetDataType(&self, value: u8) -> windows_core::Result<()>; + fn Data(&self) -> windows_core::Result; + fn SetData(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result<()>; +} +#[cfg(feature = "Storage_Streams")] +impl IBluetoothLEAdvertisementDataSection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DataType(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementDataSection_Impl::DataType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDataType(this: *mut core::ffi::c_void, value: u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEAdvertisementDataSection_Impl::SetDataType(this, value).into() + } + } + unsafe extern "system" fn Data(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementDataSection_Impl::Data(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetData(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEAdvertisementDataSection_Impl::SetData(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DataType: DataType::, + SetDataType: SetDataType::, + Data: Data::, + SetData: SetData::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEAdvertisementDataSection_Vtbl { @@ -3454,6 +8735,39 @@ windows_core::imp::define_interface!(IBluetoothLEAdvertisementDataSectionFactory impl windows_core::RuntimeType for IBluetoothLEAdvertisementDataSectionFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IBluetoothLEAdvertisementDataSectionFactory { + const NAME: &'static str = "Windows.Devices.Bluetooth.Advertisement.IBluetoothLEAdvertisementDataSectionFactory"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IBluetoothLEAdvertisementDataSectionFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, dataType: u8, data: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IBluetoothLEAdvertisementDataSectionFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, datatype: u8, data: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementDataSectionFactory_Impl::Create(this, datatype, core::mem::transmute_copy(&data)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Create: Create::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEAdvertisementDataSectionFactory_Vtbl { @@ -3467,6 +8781,59 @@ windows_core::imp::define_interface!(IBluetoothLEAdvertisementFilter, IBluetooth impl windows_core::RuntimeType for IBluetoothLEAdvertisementFilter { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBluetoothLEAdvertisementFilter { + const NAME: &'static str = "Windows.Devices.Bluetooth.Advertisement.IBluetoothLEAdvertisementFilter"; +} +pub trait IBluetoothLEAdvertisementFilter_Impl: windows_core::IUnknownImpl { + fn Advertisement(&self) -> windows_core::Result; + fn SetAdvertisement(&self, value: windows_core::Ref<'_, BluetoothLEAdvertisement>) -> windows_core::Result<()>; + fn BytePatterns(&self) -> windows_core::Result>; +} +impl IBluetoothLEAdvertisementFilter_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Advertisement(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementFilter_Impl::Advertisement(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAdvertisement(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEAdvertisementFilter_Impl::SetAdvertisement(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn BytePatterns(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEAdvertisementFilter_Impl::BytePatterns(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Advertisement: Advertisement::, + SetAdvertisement: SetAdvertisement::, + BytePatterns: BytePatterns::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEAdvertisementFilter_Vtbl { @@ -3475,32 +8842,73 @@ pub struct IBluetoothLEAdvertisementFilter_Vtbl { pub SetAdvertisement: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, pub BytePatterns: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, } -windows_core::imp::define_interface!(IBluetoothLEAdvertisementScanParameters, IBluetoothLEAdvertisementScanParameters_Vtbl, 0x94f91413_63d9_53bd_af4c_e6b1a6514595); -impl windows_core::RuntimeType for IBluetoothLEAdvertisementScanParameters { - const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); -} -#[repr(C)] -#[doc(hidden)] -pub struct IBluetoothLEAdvertisementScanParameters_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub ScanWindow: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u16) -> windows_core::HRESULT, - pub ScanInterval: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u16) -> windows_core::HRESULT, -} -windows_core::imp::define_interface!(IBluetoothLEAdvertisementScanParametersStatics, IBluetoothLEAdvertisementScanParametersStatics_Vtbl, 0x548e39cd_3c9e_5f8d_b5e1_adebed5c357c); -impl windows_core::RuntimeType for IBluetoothLEAdvertisementScanParametersStatics { - const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); -} -#[repr(C)] -#[doc(hidden)] -pub struct IBluetoothLEAdvertisementScanParametersStatics_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub CoexistenceOptimized: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, - pub LowLatency: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, -} windows_core::imp::define_interface!(IBluetoothLEManufacturerData, IBluetoothLEManufacturerData_Vtbl, 0x912dba18_6963_4533_b061_4694dafb34e5); impl windows_core::RuntimeType for IBluetoothLEManufacturerData { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IBluetoothLEManufacturerData { + const NAME: &'static str = "Windows.Devices.Bluetooth.Advertisement.IBluetoothLEManufacturerData"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IBluetoothLEManufacturerData_Impl: windows_core::IUnknownImpl { + fn CompanyId(&self) -> windows_core::Result; + fn SetCompanyId(&self, value: u16) -> windows_core::Result<()>; + fn Data(&self) -> windows_core::Result; + fn SetData(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result<()>; +} +#[cfg(feature = "Storage_Streams")] +impl IBluetoothLEManufacturerData_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CompanyId(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEManufacturerData_Impl::CompanyId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetCompanyId(this: *mut core::ffi::c_void, value: u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEManufacturerData_Impl::SetCompanyId(this, value).into() + } + } + unsafe extern "system" fn Data(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEManufacturerData_Impl::Data(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetData(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBluetoothLEManufacturerData_Impl::SetData(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CompanyId: CompanyId::, + SetCompanyId: SetCompanyId::, + Data: Data::, + SetData: SetData::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEManufacturerData_Vtbl { @@ -3520,6 +8928,36 @@ windows_core::imp::define_interface!(IBluetoothLEManufacturerDataFactory, IBluet impl windows_core::RuntimeType for IBluetoothLEManufacturerDataFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IBluetoothLEManufacturerDataFactory { + const NAME: &'static str = "Windows.Devices.Bluetooth.Advertisement.IBluetoothLEManufacturerDataFactory"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IBluetoothLEManufacturerDataFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, companyId: u16, data: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IBluetoothLEManufacturerDataFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, companyid: u16, data: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBluetoothLEManufacturerDataFactory_Impl::Create(this, companyid, core::mem::transmute_copy(&data)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBluetoothLEManufacturerDataFactory_Vtbl { @@ -3530,6 +8968,7 @@ pub struct IBluetoothLEManufacturerDataFactory_Vtbl { Create: usize, } } +#[cfg(feature = "Devices_Bluetooth_Background")] pub mod Background{ #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -3549,6 +8988,92 @@ windows_core::imp::define_interface!(IRfcommInboundConnectionInformation, IRfcom impl windows_core::RuntimeType for IRfcommInboundConnectionInformation { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(all(feature = "Devices_Bluetooth_Rfcomm", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IRfcommInboundConnectionInformation { + const NAME: &'static str = "Windows.Devices.Bluetooth.Background.IRfcommInboundConnectionInformation"; +} +#[cfg(all(feature = "Devices_Bluetooth_Rfcomm", feature = "Storage_Streams"))] +pub trait IRfcommInboundConnectionInformation_Impl: windows_core::IUnknownImpl { + fn SdpRecord(&self) -> windows_core::Result; + fn SetSdpRecord(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result<()>; + fn LocalServiceId(&self) -> windows_core::Result; + fn SetLocalServiceId(&self, value: windows_core::Ref<'_, super::Rfcomm::RfcommServiceId>) -> windows_core::Result<()>; + fn ServiceCapabilities(&self) -> windows_core::Result; + fn SetServiceCapabilities(&self, value: super::BluetoothServiceCapabilities) -> windows_core::Result<()>; +} +#[cfg(all(feature = "Devices_Bluetooth_Rfcomm", feature = "Storage_Streams"))] +impl IRfcommInboundConnectionInformation_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SdpRecord(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommInboundConnectionInformation_Impl::SdpRecord(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetSdpRecord(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IRfcommInboundConnectionInformation_Impl::SetSdpRecord(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn LocalServiceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommInboundConnectionInformation_Impl::LocalServiceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetLocalServiceId(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IRfcommInboundConnectionInformation_Impl::SetLocalServiceId(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn ServiceCapabilities(this: *mut core::ffi::c_void, result__: *mut super::BluetoothServiceCapabilities) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommInboundConnectionInformation_Impl::ServiceCapabilities(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetServiceCapabilities(this: *mut core::ffi::c_void, value: super::BluetoothServiceCapabilities) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IRfcommInboundConnectionInformation_Impl::SetServiceCapabilities(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SdpRecord: SdpRecord::, + SetSdpRecord: SetSdpRecord::, + LocalServiceId: LocalServiceId::, + SetLocalServiceId: SetLocalServiceId::, + ServiceCapabilities: ServiceCapabilities::, + SetServiceCapabilities: SetServiceCapabilities::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IRfcommInboundConnectionInformation_Vtbl { @@ -3576,6 +9101,47 @@ windows_core::imp::define_interface!(IRfcommOutboundConnectionInformation, IRfco impl windows_core::RuntimeType for IRfcommOutboundConnectionInformation { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Bluetooth_Rfcomm")] +impl windows_core::RuntimeName for IRfcommOutboundConnectionInformation { + const NAME: &'static str = "Windows.Devices.Bluetooth.Background.IRfcommOutboundConnectionInformation"; +} +#[cfg(feature = "Devices_Bluetooth_Rfcomm")] +pub trait IRfcommOutboundConnectionInformation_Impl: windows_core::IUnknownImpl { + fn RemoteServiceId(&self) -> windows_core::Result; + fn SetRemoteServiceId(&self, value: windows_core::Ref<'_, super::Rfcomm::RfcommServiceId>) -> windows_core::Result<()>; +} +#[cfg(feature = "Devices_Bluetooth_Rfcomm")] +impl IRfcommOutboundConnectionInformation_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn RemoteServiceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommOutboundConnectionInformation_Impl::RemoteServiceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRemoteServiceId(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IRfcommOutboundConnectionInformation_Impl::SetRemoteServiceId(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + RemoteServiceId: RemoteServiceId::, + SetRemoteServiceId: SetRemoteServiceId::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IRfcommOutboundConnectionInformation_Vtbl { @@ -3593,6 +9159,51 @@ pub struct IRfcommOutboundConnectionInformation_Vtbl { #[derive(Clone, Debug, Eq, PartialEq)] pub struct RfcommInboundConnectionInformation(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(RfcommInboundConnectionInformation, windows_core::IUnknown, windows_core::IInspectable); +impl RfcommInboundConnectionInformation { + #[cfg(feature = "Storage_Streams")] + pub fn SdpRecord(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SdpRecord)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn SetSdpRecord(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSdpRecord)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + #[cfg(feature = "Devices_Bluetooth_Rfcomm")] + pub fn LocalServiceId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LocalServiceId)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Devices_Bluetooth_Rfcomm")] + pub fn SetLocalServiceId(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetLocalServiceId)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn ServiceCapabilities(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ServiceCapabilities)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetServiceCapabilities(&self, value: super::BluetoothServiceCapabilities) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetServiceCapabilities)(windows_core::Interface::as_raw(this), value).ok() } + } +} impl windows_core::RuntimeType for RfcommInboundConnectionInformation { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -3609,6 +9220,24 @@ unsafe impl Sync for RfcommInboundConnectionInformation {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct RfcommOutboundConnectionInformation(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(RfcommOutboundConnectionInformation, windows_core::IUnknown, windows_core::IInspectable); +impl RfcommOutboundConnectionInformation { + #[cfg(feature = "Devices_Bluetooth_Rfcomm")] + pub fn RemoteServiceId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RemoteServiceId)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Devices_Bluetooth_Rfcomm")] + pub fn SetRemoteServiceId(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetRemoteServiceId)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } +} impl windows_core::RuntimeType for RfcommOutboundConnectionInformation { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -3622,12 +9251,210 @@ impl windows_core::RuntimeName for RfcommOutboundConnectionInformation { unsafe impl Send for RfcommOutboundConnectionInformation {} unsafe impl Sync for RfcommOutboundConnectionInformation {} } +#[cfg(feature = "Devices_Bluetooth_GenericAttributeProfile")] pub mod GenericAttributeProfile{ #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] pub struct GattCharacteristic(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattCharacteristic, windows_core::IUnknown, windows_core::IInspectable); impl GattCharacteristic { + #[cfg(feature = "deprecated")] + pub fn GetDescriptors(&self, descriptoruuid: windows_core::GUID) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDescriptors)(windows_core::Interface::as_raw(this), descriptoruuid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CharacteristicProperties(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CharacteristicProperties)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ProtectionLevel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProtectionLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetProtectionLevel(&self, value: GattProtectionLevel) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetProtectionLevel)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn UserDescription(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UserDescription)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Uuid(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Uuid)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AttributeHandle(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AttributeHandle)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PresentationFormats(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PresentationFormats)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ReadValueAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadValueAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ReadValueWithCacheModeAsync(&self, cachemode: super::BluetoothCacheMode) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadValueWithCacheModeAsync)(windows_core::Interface::as_raw(this), cachemode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn WriteValueAsync(&self, value: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteValueAsync)(windows_core::Interface::as_raw(this), value.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn WriteValueWithOptionAsync(&self, value: P0, writeoption: GattWriteOption) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteValueWithOptionAsync)(windows_core::Interface::as_raw(this), value.param().abi(), writeoption, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ReadClientCharacteristicConfigurationDescriptorAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadClientCharacteristicConfigurationDescriptorAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn WriteClientCharacteristicConfigurationDescriptorAsync(&self, clientcharacteristicconfigurationdescriptorvalue: GattClientCharacteristicConfigurationDescriptorValue) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteClientCharacteristicConfigurationDescriptorAsync)(windows_core::Interface::as_raw(this), clientcharacteristicconfigurationdescriptorvalue, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ValueChanged(&self, valuechangedhandler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ValueChanged)(windows_core::Interface::as_raw(this), valuechangedhandler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveValueChanged(&self, valuechangedeventcookie: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveValueChanged)(windows_core::Interface::as_raw(this), valuechangedeventcookie).ok() } + } + pub fn Service(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Service)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "deprecated")] + pub fn GetAllDescriptors(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAllDescriptors)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetDescriptorsAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDescriptorsAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetDescriptorsWithCacheModeAsync(&self, cachemode: super::BluetoothCacheMode) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDescriptorsWithCacheModeAsync)(windows_core::Interface::as_raw(this), cachemode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetDescriptorsForUuidAsync(&self, descriptoruuid: windows_core::GUID) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDescriptorsForUuidAsync)(windows_core::Interface::as_raw(this), descriptoruuid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetDescriptorsForUuidWithCacheModeAsync(&self, descriptoruuid: windows_core::GUID, cachemode: super::BluetoothCacheMode) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDescriptorsForUuidWithCacheModeAsync)(windows_core::Interface::as_raw(this), descriptoruuid, cachemode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn WriteValueWithResultAsync(&self, value: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteValueWithResultAsync)(windows_core::Interface::as_raw(this), value.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn WriteValueWithResultAndOptionAsync(&self, value: P0, writeoption: GattWriteOption) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteValueWithResultAndOptionAsync)(windows_core::Interface::as_raw(this), value.param().abi(), writeoption, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn WriteClientCharacteristicConfigurationDescriptorWithResultAsync(&self, clientcharacteristicconfigurationdescriptorvalue: GattClientCharacteristicConfigurationDescriptorValue) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteClientCharacteristicConfigurationDescriptorWithResultAsync)(windows_core::Interface::as_raw(this), clientcharacteristicconfigurationdescriptorvalue, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "deprecated")] + pub fn ConvertShortIdToUuid(shortid: u16) -> windows_core::Result { + Self::IGattCharacteristicStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ConvertShortIdToUuid)(windows_core::Interface::as_raw(this), shortid, &mut result__).map(|| result__) + }) + } fn IGattCharacteristicStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -3704,6 +9531,29 @@ impl core::ops::Not for GattCharacteristicProperties { #[derive(Clone, Debug, Eq, PartialEq)] pub struct GattCharacteristicsResult(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattCharacteristicsResult, windows_core::IUnknown, windows_core::IInspectable); +impl GattCharacteristicsResult { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ProtocolError(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProtocolError)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Characteristics(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Characteristics)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for GattCharacteristicsResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -3734,6 +9584,36 @@ impl windows_core::RuntimeType for GattClientCharacteristicConfigurationDescript #[derive(Clone, Debug, Eq, PartialEq)] pub struct GattClientNotificationResult(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattClientNotificationResult, windows_core::IUnknown, windows_core::IInspectable); +impl GattClientNotificationResult { + pub fn SubscribedClient(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SubscribedClient)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ProtocolError(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProtocolError)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn BytesSent(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BytesSent)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for GattClientNotificationResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -3766,6 +9646,74 @@ impl windows_core::RuntimeType for GattCommunicationStatus { pub struct GattDescriptor(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattDescriptor, windows_core::IUnknown, windows_core::IInspectable); impl GattDescriptor { + pub fn ProtectionLevel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProtectionLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetProtectionLevel(&self, value: GattProtectionLevel) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetProtectionLevel)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Uuid(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Uuid)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AttributeHandle(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AttributeHandle)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadValueAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadValueAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ReadValueWithCacheModeAsync(&self, cachemode: super::BluetoothCacheMode) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadValueWithCacheModeAsync)(windows_core::Interface::as_raw(this), cachemode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn WriteValueAsync(&self, value: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteValueAsync)(windows_core::Interface::as_raw(this), value.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn WriteValueWithResultAsync(&self, value: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteValueWithResultAsync)(windows_core::Interface::as_raw(this), value.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "deprecated")] + pub fn ConvertShortIdToUuid(shortid: u16) -> windows_core::Result { + Self::IGattDescriptorStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ConvertShortIdToUuid)(windows_core::Interface::as_raw(this), shortid, &mut result__).map(|| result__) + }) + } fn IGattDescriptorStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -3787,6 +9735,29 @@ unsafe impl Sync for GattDescriptor {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct GattDescriptorsResult(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattDescriptorsResult, windows_core::IUnknown, windows_core::IInspectable); +impl GattDescriptorsResult { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ProtocolError(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProtocolError)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Descriptors(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Descriptors)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for GattDescriptorsResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -3809,6 +9780,83 @@ impl GattDeviceService { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + #[cfg(feature = "deprecated")] + pub fn GetCharacteristics(&self, characteristicuuid: windows_core::GUID) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCharacteristics)(windows_core::Interface::as_raw(this), characteristicuuid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "deprecated")] + pub fn GetIncludedServices(&self, serviceuuid: windows_core::GUID) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetIncludedServices)(windows_core::Interface::as_raw(this), serviceuuid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeviceId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Uuid(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Uuid)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AttributeHandle(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AttributeHandle)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "deprecated")] + pub fn Device(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Device)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "deprecated")] + pub fn ParentServices(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ParentServices)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "deprecated")] + pub fn GetAllCharacteristics(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAllCharacteristics)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "deprecated")] + pub fn GetAllIncludedServices(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAllIncludedServices)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Devices_Enumeration")] + pub fn DeviceAccessInformation(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceAccessInformation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Session(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; unsafe { @@ -3816,12 +9864,152 @@ impl GattDeviceService { (windows_core::Interface::vtable(this).Session)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn SharingMode(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SharingMode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Devices_Enumeration")] + pub fn RequestAccessAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestAccessAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn OpenAsync(&self, sharingmode: GattSharingMode) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenAsync)(windows_core::Interface::as_raw(this), sharingmode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetCharacteristicsAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCharacteristicsAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetCharacteristicsWithCacheModeAsync(&self, cachemode: super::BluetoothCacheMode) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCharacteristicsWithCacheModeAsync)(windows_core::Interface::as_raw(this), cachemode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetCharacteristicsForUuidAsync(&self, characteristicuuid: windows_core::GUID) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCharacteristicsForUuidAsync)(windows_core::Interface::as_raw(this), characteristicuuid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetCharacteristicsForUuidWithCacheModeAsync(&self, characteristicuuid: windows_core::GUID, cachemode: super::BluetoothCacheMode) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCharacteristicsForUuidWithCacheModeAsync)(windows_core::Interface::as_raw(this), characteristicuuid, cachemode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetIncludedServicesAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetIncludedServicesAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetIncludedServicesWithCacheModeAsync(&self, cachemode: super::BluetoothCacheMode) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetIncludedServicesWithCacheModeAsync)(windows_core::Interface::as_raw(this), cachemode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetIncludedServicesForUuidAsync(&self, serviceuuid: windows_core::GUID) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetIncludedServicesForUuidAsync)(windows_core::Interface::as_raw(this), serviceuuid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetIncludedServicesForUuidWithCacheModeAsync(&self, serviceuuid: windows_core::GUID, cachemode: super::BluetoothCacheMode) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetIncludedServicesForUuidWithCacheModeAsync)(windows_core::Interface::as_raw(this), serviceuuid, cachemode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn FromIdAsync(deviceid: &windows_core::HSTRING) -> windows_core::Result> { Self::IGattDeviceServiceStatics(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).FromIdAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn GetDeviceSelectorFromUuid(serviceuuid: windows_core::GUID) -> windows_core::Result { + Self::IGattDeviceServiceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeviceSelectorFromUuid)(windows_core::Interface::as_raw(this), serviceuuid, &mut result__).map(|| core::mem::transmute(result__)) + }) + } + #[cfg(feature = "deprecated")] + pub fn GetDeviceSelectorFromShortId(serviceshortid: u16) -> windows_core::Result { + Self::IGattDeviceServiceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeviceSelectorFromShortId)(windows_core::Interface::as_raw(this), serviceshortid, &mut result__).map(|| core::mem::transmute(result__)) + }) + } + #[cfg(feature = "deprecated")] + pub fn ConvertShortIdToUuid(shortid: u16) -> windows_core::Result { + Self::IGattDeviceServiceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ConvertShortIdToUuid)(windows_core::Interface::as_raw(this), shortid, &mut result__).map(|| result__) + }) + } + pub fn FromIdWithSharingModeAsync(deviceid: &windows_core::HSTRING, sharingmode: GattSharingMode) -> windows_core::Result> { + Self::IGattDeviceServiceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FromIdWithSharingModeAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), sharingmode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetDeviceSelectorForBluetoothDeviceId(bluetoothdeviceid: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IGattDeviceServiceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeviceSelectorForBluetoothDeviceId)(windows_core::Interface::as_raw(this), bluetoothdeviceid.param().abi(), &mut result__).map(|| core::mem::transmute(result__)) + }) + } + pub fn GetDeviceSelectorForBluetoothDeviceIdWithCacheMode(bluetoothdeviceid: P0, cachemode: super::BluetoothCacheMode) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IGattDeviceServiceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeviceSelectorForBluetoothDeviceIdWithCacheMode)(windows_core::Interface::as_raw(this), bluetoothdeviceid.param().abi(), cachemode, &mut result__).map(|| core::mem::transmute(result__)) + }) + } + pub fn GetDeviceSelectorForBluetoothDeviceIdAndUuid(bluetoothdeviceid: P0, serviceuuid: windows_core::GUID) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IGattDeviceServiceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeviceSelectorForBluetoothDeviceIdAndUuid)(windows_core::Interface::as_raw(this), bluetoothdeviceid.param().abi(), serviceuuid, &mut result__).map(|| core::mem::transmute(result__)) + }) + } + pub fn GetDeviceSelectorForBluetoothDeviceIdAndUuidWithCacheMode(bluetoothdeviceid: P0, serviceuuid: windows_core::GUID, cachemode: super::BluetoothCacheMode) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IGattDeviceServiceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeviceSelectorForBluetoothDeviceIdAndUuidWithCacheMode)(windows_core::Interface::as_raw(this), bluetoothdeviceid.param().abi(), serviceuuid, cachemode, &mut result__).map(|| core::mem::transmute(result__)) + }) + } fn IGattDeviceServiceStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -3847,6 +10035,29 @@ unsafe impl Sync for GattDeviceService {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct GattDeviceServicesResult(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattDeviceServicesResult, windows_core::IUnknown, windows_core::IInspectable); +impl GattDeviceServicesResult { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ProtocolError(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProtocolError)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Services(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Services)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for GattDeviceServicesResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -3863,6 +10074,147 @@ unsafe impl Sync for GattDeviceServicesResult {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct GattLocalCharacteristic(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattLocalCharacteristic, windows_core::IUnknown, windows_core::IInspectable); +impl GattLocalCharacteristic { + pub fn Uuid(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Uuid)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn StaticValue(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StaticValue)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CharacteristicProperties(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CharacteristicProperties)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadProtectionLevel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadProtectionLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn WriteProtectionLevel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteProtectionLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CreateDescriptorAsync(&self, descriptoruuid: windows_core::GUID, parameters: P1) -> windows_core::Result> + where + P1: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateDescriptorAsync)(windows_core::Interface::as_raw(this), descriptoruuid, parameters.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Descriptors(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Descriptors)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn UserDescription(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UserDescription)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn PresentationFormats(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PresentationFormats)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SubscribedClients(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SubscribedClients)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SubscribedClientsChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SubscribedClientsChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveSubscribedClientsChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveSubscribedClientsChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn ReadRequested(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadRequested)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveReadRequested(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveReadRequested)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn WriteRequested(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteRequested)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveWriteRequested(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveWriteRequested)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn NotifyValueAsync(&self, value: P0) -> windows_core::Result>> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NotifyValueAsync)(windows_core::Interface::as_raw(this), value.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn NotifyValueForSubscribedClientAsync(&self, value: P0, subscribedclient: P1) -> windows_core::Result> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NotifyValueForSubscribedClientAsync)(windows_core::Interface::as_raw(this), value.param().abi(), subscribedclient.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for GattLocalCharacteristic { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -3887,7 +10239,74 @@ impl GattLocalCharacteristicParameters { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + #[cfg(feature = "Storage_Streams")] + pub fn SetStaticValue(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetStaticValue)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } } + #[cfg(feature = "Storage_Streams")] + pub fn StaticValue(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StaticValue)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetCharacteristicProperties(&self, value: GattCharacteristicProperties) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetCharacteristicProperties)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn CharacteristicProperties(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CharacteristicProperties)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetReadProtectionLevel(&self, value: GattProtectionLevel) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetReadProtectionLevel)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ReadProtectionLevel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadProtectionLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetWriteProtectionLevel(&self, value: GattProtectionLevel) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetWriteProtectionLevel)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteProtectionLevel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteProtectionLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetUserDescription(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetUserDescription)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn UserDescription(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UserDescription)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn PresentationFormats(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PresentationFormats)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for GattLocalCharacteristicParameters { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -3905,6 +10324,13 @@ unsafe impl Sync for GattLocalCharacteristicParameters {} pub struct GattLocalCharacteristicResult(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattLocalCharacteristicResult, windows_core::IUnknown, windows_core::IInspectable); impl GattLocalCharacteristicResult { + pub fn Characteristic(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Characteristic)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Error(&self) -> windows_core::Result { let this = self; unsafe { @@ -3929,6 +10355,65 @@ unsafe impl Sync for GattLocalCharacteristicResult {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct GattLocalDescriptor(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattLocalDescriptor, windows_core::IUnknown, windows_core::IInspectable); +impl GattLocalDescriptor { + pub fn Uuid(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Uuid)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn StaticValue(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StaticValue)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ReadProtectionLevel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadProtectionLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn WriteProtectionLevel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteProtectionLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadRequested(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadRequested)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveReadRequested(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveReadRequested)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn WriteRequested(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteRequested)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveWriteRequested(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveWriteRequested)(windows_core::Interface::as_raw(this), token).ok() } + } +} impl windows_core::RuntimeType for GattLocalDescriptor { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -3953,7 +10438,45 @@ impl GattLocalDescriptorParameters { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + #[cfg(feature = "Storage_Streams")] + pub fn SetStaticValue(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetStaticValue)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } } + #[cfg(feature = "Storage_Streams")] + pub fn StaticValue(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StaticValue)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetReadProtectionLevel(&self, value: GattProtectionLevel) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetReadProtectionLevel)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ReadProtectionLevel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadProtectionLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetWriteProtectionLevel(&self, value: GattProtectionLevel) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetWriteProtectionLevel)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteProtectionLevel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteProtectionLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for GattLocalDescriptorParameters { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -3971,6 +10494,13 @@ unsafe impl Sync for GattLocalDescriptorParameters {} pub struct GattLocalDescriptorResult(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattLocalDescriptorResult, windows_core::IUnknown, windows_core::IInspectable); impl GattLocalDescriptorResult { + pub fn Descriptor(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Descriptor)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Error(&self) -> windows_core::Result { let this = self; unsafe { @@ -3995,6 +10525,32 @@ unsafe impl Sync for GattLocalDescriptorResult {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct GattLocalService(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattLocalService, windows_core::IUnknown, windows_core::IInspectable); +impl GattLocalService { + pub fn Uuid(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Uuid)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CreateCharacteristicAsync(&self, characteristicuuid: windows_core::GUID, parameters: P1) -> windows_core::Result> + where + P1: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateCharacteristicAsync)(windows_core::Interface::as_raw(this), characteristicuuid, parameters.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Characteristics(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Characteristics)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for GattLocalService { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -4029,6 +10585,53 @@ impl windows_core::RuntimeType for GattOpenStatus { pub struct GattPresentationFormat(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattPresentationFormat, windows_core::IUnknown, windows_core::IInspectable); impl GattPresentationFormat { + pub fn FormatType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FormatType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Exponent(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Exponent)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Unit(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Unit)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Namespace(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Namespace)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Description(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Description)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn BluetoothSigAssignedNumbers() -> windows_core::Result { + Self::IGattPresentationFormatStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BluetoothSigAssignedNumbers)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + }) + } + pub fn FromParts(formattype: u8, exponent: i32, unit: u16, namespaceid: u8, description: u16) -> windows_core::Result { + Self::IGattPresentationFormatStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FromParts)(windows_core::Interface::as_raw(this), formattype, exponent, unit, namespaceid, description, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IGattPresentationFormatStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -4069,6 +10672,29 @@ impl windows_core::RuntimeType for GattProtectionLevel { #[derive(Clone, Debug, Eq, PartialEq)] pub struct GattReadClientCharacteristicConfigurationDescriptorResult(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattReadClientCharacteristicConfigurationDescriptorResult, windows_core::IUnknown, windows_core::IInspectable); +impl GattReadClientCharacteristicConfigurationDescriptorResult { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ClientCharacteristicConfigurationDescriptor(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ClientCharacteristicConfigurationDescriptor)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ProtocolError(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProtocolError)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for GattReadClientCharacteristicConfigurationDescriptorResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -4086,6 +10712,13 @@ unsafe impl Sync for GattReadClientCharacteristicConfigurationDescriptorResult { pub struct GattReadRequest(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattReadRequest, windows_core::IUnknown, windows_core::IInspectable); impl GattReadRequest { + pub fn Offset(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Offset)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Length(&self) -> windows_core::Result { let this = self; unsafe { @@ -4093,7 +10726,40 @@ impl GattReadRequest { (windows_core::Interface::vtable(this).Length)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) } } + pub fn State(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).State)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } + pub fn StateChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StateChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveStateChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveStateChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn RespondWithValue(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RespondWithValue)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn RespondWithProtocolError(&self, protocolerror: u8) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RespondWithProtocolError)(windows_core::Interface::as_raw(this), protocolerror).ok() } + } +} impl windows_core::RuntimeType for GattReadRequest { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -4118,7 +10784,21 @@ impl GattReadRequestedEventArgs { (windows_core::Interface::vtable(this).Session)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn GetDeferral(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeferral)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn GetRequestAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetRequestAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for GattReadRequestedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -4135,6 +10815,30 @@ unsafe impl Sync for GattReadRequestedEventArgs {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct GattReadResult(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattReadResult, windows_core::IUnknown, windows_core::IInspectable); +impl GattReadResult { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ProtocolError(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProtocolError)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for GattReadResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -4166,6 +10870,13 @@ impl windows_core::RuntimeType for GattRequestState { pub struct GattRequestStateChangedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattRequestStateChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); impl GattRequestStateChangedEventArgs { + pub fn State(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).State)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Error(&self) -> windows_core::Result { let this = self; unsafe { @@ -4198,7 +10909,45 @@ impl GattServiceProviderAdvertisingParameters { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn SetIsConnectable(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetIsConnectable)(windows_core::Interface::as_raw(this), value).ok() } } + pub fn IsConnectable(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsConnectable)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetIsDiscoverable(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetIsDiscoverable)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn IsDiscoverable(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsDiscoverable)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn SetServiceData(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetServiceData)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn ServiceData(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ServiceData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for GattServiceProviderAdvertisingParameters { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -4221,6 +10970,82 @@ impl GattSession { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn DeviceId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CanMaintainConnection(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanMaintainConnection)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetMaintainConnection(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMaintainConnection)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn MaintainConnection(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaintainConnection)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaxPduSize(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxPduSize)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SessionStatus(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SessionStatus)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaxPduSizeChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxPduSizeChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveMaxPduSizeChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveMaxPduSizeChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn SessionStatusChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SessionStatusChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveSessionStatusChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveSessionStatusChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn FromDeviceIdAsync(deviceid: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::IGattSessionStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FromDeviceIdAsync)(windows_core::Interface::as_raw(this), deviceid.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IGattSessionStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -4263,7 +11088,14 @@ impl GattSessionStatusChangedEventArgs { (windows_core::Interface::vtable(this).Error)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) } } + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } +} impl windows_core::RuntimeType for GattSessionStatusChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -4303,7 +11135,28 @@ impl GattSubscribedClient { (windows_core::Interface::vtable(this).Session)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn MaxNotificationSize(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxNotificationSize)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } + pub fn MaxNotificationSizeChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxNotificationSizeChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveMaxNotificationSizeChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveMaxNotificationSizeChanged)(windows_core::Interface::as_raw(this), token).ok() } + } +} impl windows_core::RuntimeType for GattSubscribedClient { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -4320,6 +11173,23 @@ unsafe impl Sync for GattSubscribedClient {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct GattValueChangedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattValueChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl GattValueChangedEventArgs { + #[cfg(feature = "Storage_Streams")] + pub fn CharacteristicValue(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CharacteristicValue)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for GattValueChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -4349,6 +11219,59 @@ impl windows_core::RuntimeType for GattWriteOption { #[derive(Clone, Debug, Eq, PartialEq)] pub struct GattWriteRequest(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattWriteRequest, windows_core::IUnknown, windows_core::IInspectable); +impl GattWriteRequest { + #[cfg(feature = "Storage_Streams")] + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Offset(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Offset)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Option(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Option)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn State(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).State)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn StateChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StateChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveStateChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveStateChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn Respond(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Respond)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn RespondWithProtocolError(&self, protocolerror: u8) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RespondWithProtocolError)(windows_core::Interface::as_raw(this), protocolerror).ok() } + } +} impl windows_core::RuntimeType for GattWriteRequest { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -4373,7 +11296,21 @@ impl GattWriteRequestedEventArgs { (windows_core::Interface::vtable(this).Session)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn GetDeferral(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeferral)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn GetRequestAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetRequestAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for GattWriteRequestedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -4390,6 +11327,22 @@ unsafe impl Sync for GattWriteRequestedEventArgs {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct GattWriteResult(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(GattWriteResult, windows_core::IUnknown, windows_core::IInspectable); +impl GattWriteResult { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ProtocolError(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProtocolError)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for GattWriteResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -4406,11 +11359,253 @@ windows_core::imp::define_interface!(IGattCharacteristic, IGattCharacteristic_Vt impl windows_core::RuntimeType for IGattCharacteristic { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IGattCharacteristic { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattCharacteristic"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IGattCharacteristic_Impl: windows_core::IUnknownImpl { + fn GetDescriptors(&self, descriptorUuid: &windows_core::GUID) -> windows_core::Result>; + fn CharacteristicProperties(&self) -> windows_core::Result; + fn ProtectionLevel(&self) -> windows_core::Result; + fn SetProtectionLevel(&self, value: GattProtectionLevel) -> windows_core::Result<()>; + fn UserDescription(&self) -> windows_core::Result; + fn Uuid(&self) -> windows_core::Result; + fn AttributeHandle(&self) -> windows_core::Result; + fn PresentationFormats(&self) -> windows_core::Result>; + fn ReadValueAsync(&self) -> windows_core::Result>; + fn ReadValueWithCacheModeAsync(&self, cacheMode: super::BluetoothCacheMode) -> windows_core::Result>; + fn WriteValueAsync(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result>; + fn WriteValueWithOptionAsync(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>, writeOption: GattWriteOption) -> windows_core::Result>; + fn ReadClientCharacteristicConfigurationDescriptorAsync(&self) -> windows_core::Result>; + fn WriteClientCharacteristicConfigurationDescriptorAsync(&self, clientCharacteristicConfigurationDescriptorValue: GattClientCharacteristicConfigurationDescriptorValue) -> windows_core::Result>; + fn ValueChanged(&self, valueChangedHandler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveValueChanged(&self, valueChangedEventCookie: i64) -> windows_core::Result<()>; +} +#[cfg(feature = "Storage_Streams")] +impl IGattCharacteristic_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDescriptors(this: *mut core::ffi::c_void, descriptoruuid: windows_core::GUID, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic_Impl::GetDescriptors(this, core::mem::transmute(&descriptoruuid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CharacteristicProperties(this: *mut core::ffi::c_void, result__: *mut GattCharacteristicProperties) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic_Impl::CharacteristicProperties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ProtectionLevel(this: *mut core::ffi::c_void, result__: *mut GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic_Impl::ProtectionLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetProtectionLevel(this: *mut core::ffi::c_void, value: GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattCharacteristic_Impl::SetProtectionLevel(this, value).into() + } + } + unsafe extern "system" fn UserDescription(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic_Impl::UserDescription(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Uuid(this: *mut core::ffi::c_void, result__: *mut windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic_Impl::Uuid(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AttributeHandle(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic_Impl::AttributeHandle(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PresentationFormats(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic_Impl::PresentationFormats(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadValueAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic_Impl::ReadValueAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadValueWithCacheModeAsync(this: *mut core::ffi::c_void, cachemode: super::BluetoothCacheMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic_Impl::ReadValueWithCacheModeAsync(this, cachemode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WriteValueAsync(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic_Impl::WriteValueAsync(this, core::mem::transmute_copy(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WriteValueWithOptionAsync(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void, writeoption: GattWriteOption, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic_Impl::WriteValueWithOptionAsync(this, core::mem::transmute_copy(&value), writeoption) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadClientCharacteristicConfigurationDescriptorAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic_Impl::ReadClientCharacteristicConfigurationDescriptorAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WriteClientCharacteristicConfigurationDescriptorAsync(this: *mut core::ffi::c_void, clientcharacteristicconfigurationdescriptorvalue: GattClientCharacteristicConfigurationDescriptorValue, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic_Impl::WriteClientCharacteristicConfigurationDescriptorAsync(this, clientcharacteristicconfigurationdescriptorvalue) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ValueChanged(this: *mut core::ffi::c_void, valuechangedhandler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic_Impl::ValueChanged(this, core::mem::transmute_copy(&valuechangedhandler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveValueChanged(this: *mut core::ffi::c_void, valuechangedeventcookie: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattCharacteristic_Impl::RemoveValueChanged(this, valuechangedeventcookie).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDescriptors: GetDescriptors::, + CharacteristicProperties: CharacteristicProperties::, + ProtectionLevel: ProtectionLevel::, + SetProtectionLevel: SetProtectionLevel::, + UserDescription: UserDescription::, + Uuid: Uuid::, + AttributeHandle: AttributeHandle::, + PresentationFormats: PresentationFormats::, + ReadValueAsync: ReadValueAsync::, + ReadValueWithCacheModeAsync: ReadValueWithCacheModeAsync::, + WriteValueAsync: WriteValueAsync::, + WriteValueWithOptionAsync: WriteValueWithOptionAsync::, + ReadClientCharacteristicConfigurationDescriptorAsync: ReadClientCharacteristicConfigurationDescriptorAsync::, + WriteClientCharacteristicConfigurationDescriptorAsync: WriteClientCharacteristicConfigurationDescriptorAsync::, + ValueChanged: ValueChanged::, + RemoveValueChanged: RemoveValueChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattCharacteristic_Vtbl { pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "deprecated")] pub GetDescriptors: unsafe extern "system" fn(*mut core::ffi::c_void, windows_core::GUID, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + GetDescriptors: usize, pub CharacteristicProperties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut GattCharacteristicProperties) -> windows_core::HRESULT, pub ProtectionLevel: unsafe extern "system" fn(*mut core::ffi::c_void, *mut GattProtectionLevel) -> windows_core::HRESULT, pub SetProtectionLevel: unsafe extern "system" fn(*mut core::ffi::c_void, GattProtectionLevel) -> windows_core::HRESULT, @@ -4437,17 +11632,191 @@ windows_core::imp::define_interface!(IGattCharacteristic2, IGattCharacteristic2_ impl windows_core::RuntimeType for IGattCharacteristic2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IGattCharacteristic2 { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattCharacteristic2"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IGattCharacteristic2_Impl: IGattCharacteristic_Impl { + fn Service(&self) -> windows_core::Result; + fn GetAllDescriptors(&self) -> windows_core::Result>; +} +#[cfg(feature = "Storage_Streams")] +impl IGattCharacteristic2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Service(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic2_Impl::Service(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetAllDescriptors(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic2_Impl::GetAllDescriptors(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Service: Service::, + GetAllDescriptors: GetAllDescriptors::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattCharacteristic2_Vtbl { pub base__: windows_core::IInspectable_Vtbl, pub Service: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "deprecated")] pub GetAllDescriptors: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + GetAllDescriptors: usize, } windows_core::imp::define_interface!(IGattCharacteristic3, IGattCharacteristic3_Vtbl, 0x3f3c663e_93d4_406b_b817_db81f8ed53b3); impl windows_core::RuntimeType for IGattCharacteristic3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IGattCharacteristic3 { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattCharacteristic3"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IGattCharacteristic3_Impl: windows_core::IUnknownImpl { + fn GetDescriptorsAsync(&self) -> windows_core::Result>; + fn GetDescriptorsWithCacheModeAsync(&self, cacheMode: super::BluetoothCacheMode) -> windows_core::Result>; + fn GetDescriptorsForUuidAsync(&self, descriptorUuid: &windows_core::GUID) -> windows_core::Result>; + fn GetDescriptorsForUuidWithCacheModeAsync(&self, descriptorUuid: &windows_core::GUID, cacheMode: super::BluetoothCacheMode) -> windows_core::Result>; + fn WriteValueWithResultAsync(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result>; + fn WriteValueWithResultAndOptionAsync(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>, writeOption: GattWriteOption) -> windows_core::Result>; + fn WriteClientCharacteristicConfigurationDescriptorWithResultAsync(&self, clientCharacteristicConfigurationDescriptorValue: GattClientCharacteristicConfigurationDescriptorValue) -> windows_core::Result>; +} +#[cfg(feature = "Storage_Streams")] +impl IGattCharacteristic3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDescriptorsAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic3_Impl::GetDescriptorsAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDescriptorsWithCacheModeAsync(this: *mut core::ffi::c_void, cachemode: super::BluetoothCacheMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic3_Impl::GetDescriptorsWithCacheModeAsync(this, cachemode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDescriptorsForUuidAsync(this: *mut core::ffi::c_void, descriptoruuid: windows_core::GUID, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic3_Impl::GetDescriptorsForUuidAsync(this, core::mem::transmute(&descriptoruuid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDescriptorsForUuidWithCacheModeAsync(this: *mut core::ffi::c_void, descriptoruuid: windows_core::GUID, cachemode: super::BluetoothCacheMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic3_Impl::GetDescriptorsForUuidWithCacheModeAsync(this, core::mem::transmute(&descriptoruuid), cachemode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WriteValueWithResultAsync(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic3_Impl::WriteValueWithResultAsync(this, core::mem::transmute_copy(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WriteValueWithResultAndOptionAsync(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void, writeoption: GattWriteOption, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic3_Impl::WriteValueWithResultAndOptionAsync(this, core::mem::transmute_copy(&value), writeoption) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WriteClientCharacteristicConfigurationDescriptorWithResultAsync(this: *mut core::ffi::c_void, clientcharacteristicconfigurationdescriptorvalue: GattClientCharacteristicConfigurationDescriptorValue, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristic3_Impl::WriteClientCharacteristicConfigurationDescriptorWithResultAsync(this, clientcharacteristicconfigurationdescriptorvalue) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDescriptorsAsync: GetDescriptorsAsync::, + GetDescriptorsWithCacheModeAsync: GetDescriptorsWithCacheModeAsync::, + GetDescriptorsForUuidAsync: GetDescriptorsForUuidAsync::, + GetDescriptorsForUuidWithCacheModeAsync: GetDescriptorsForUuidWithCacheModeAsync::, + WriteValueWithResultAsync: WriteValueWithResultAsync::, + WriteValueWithResultAndOptionAsync: WriteValueWithResultAndOptionAsync::, + WriteClientCharacteristicConfigurationDescriptorWithResultAsync: WriteClientCharacteristicConfigurationDescriptorWithResultAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattCharacteristic3_Vtbl { @@ -4470,16 +11839,107 @@ windows_core::imp::define_interface!(IGattCharacteristicStatics, IGattCharacteri impl windows_core::RuntimeType for IGattCharacteristicStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattCharacteristicStatics { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattCharacteristicStatics"; +} +pub trait IGattCharacteristicStatics_Impl: windows_core::IUnknownImpl { + fn ConvertShortIdToUuid(&self, shortId: u16) -> windows_core::Result; +} +impl IGattCharacteristicStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ConvertShortIdToUuid(this: *mut core::ffi::c_void, shortid: u16, result__: *mut windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristicStatics_Impl::ConvertShortIdToUuid(this, shortid) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ConvertShortIdToUuid: ConvertShortIdToUuid::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattCharacteristicStatics_Vtbl { pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "deprecated")] pub ConvertShortIdToUuid: unsafe extern "system" fn(*mut core::ffi::c_void, u16, *mut windows_core::GUID) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + ConvertShortIdToUuid: usize, } windows_core::imp::define_interface!(IGattCharacteristicsResult, IGattCharacteristicsResult_Vtbl, 0x1194945c_b257_4f3e_9db7_f68bc9a9aef2); impl windows_core::RuntimeType for IGattCharacteristicsResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattCharacteristicsResult { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattCharacteristicsResult"; +} +pub trait IGattCharacteristicsResult_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; + fn ProtocolError(&self) -> windows_core::Result>; + fn Characteristics(&self) -> windows_core::Result>; +} +impl IGattCharacteristicsResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut GattCommunicationStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristicsResult_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ProtocolError(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristicsResult_Impl::ProtocolError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Characteristics(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattCharacteristicsResult_Impl::Characteristics(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Status: Status::, + ProtocolError: ProtocolError::, + Characteristics: Characteristics::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattCharacteristicsResult_Vtbl { @@ -4492,6 +11952,65 @@ windows_core::imp::define_interface!(IGattClientNotificationResult, IGattClientN impl windows_core::RuntimeType for IGattClientNotificationResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattClientNotificationResult { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattClientNotificationResult"; +} +pub trait IGattClientNotificationResult_Impl: windows_core::IUnknownImpl { + fn SubscribedClient(&self) -> windows_core::Result; + fn Status(&self) -> windows_core::Result; + fn ProtocolError(&self) -> windows_core::Result>; +} +impl IGattClientNotificationResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SubscribedClient(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattClientNotificationResult_Impl::SubscribedClient(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut GattCommunicationStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattClientNotificationResult_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ProtocolError(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattClientNotificationResult_Impl::ProtocolError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SubscribedClient: SubscribedClient::, + Status: Status::, + ProtocolError: ProtocolError::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattClientNotificationResult_Vtbl { @@ -4504,6 +12023,32 @@ windows_core::imp::define_interface!(IGattClientNotificationResult2, IGattClient impl windows_core::RuntimeType for IGattClientNotificationResult2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattClientNotificationResult2 { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattClientNotificationResult2"; +} +pub trait IGattClientNotificationResult2_Impl: windows_core::IUnknownImpl { + fn BytesSent(&self) -> windows_core::Result; +} +impl IGattClientNotificationResult2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn BytesSent(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattClientNotificationResult2_Impl::BytesSent(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), BytesSent: BytesSent:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattClientNotificationResult2_Vtbl { @@ -4514,6 +12059,119 @@ windows_core::imp::define_interface!(IGattDescriptor, IGattDescriptor_Vtbl, 0x92 impl windows_core::RuntimeType for IGattDescriptor { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IGattDescriptor { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDescriptor"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IGattDescriptor_Impl: windows_core::IUnknownImpl { + fn ProtectionLevel(&self) -> windows_core::Result; + fn SetProtectionLevel(&self, value: GattProtectionLevel) -> windows_core::Result<()>; + fn Uuid(&self) -> windows_core::Result; + fn AttributeHandle(&self) -> windows_core::Result; + fn ReadValueAsync(&self) -> windows_core::Result>; + fn ReadValueWithCacheModeAsync(&self, cacheMode: super::BluetoothCacheMode) -> windows_core::Result>; + fn WriteValueAsync(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result>; +} +#[cfg(feature = "Storage_Streams")] +impl IGattDescriptor_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ProtectionLevel(this: *mut core::ffi::c_void, result__: *mut GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDescriptor_Impl::ProtectionLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetProtectionLevel(this: *mut core::ffi::c_void, value: GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattDescriptor_Impl::SetProtectionLevel(this, value).into() + } + } + unsafe extern "system" fn Uuid(this: *mut core::ffi::c_void, result__: *mut windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDescriptor_Impl::Uuid(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AttributeHandle(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDescriptor_Impl::AttributeHandle(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadValueAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDescriptor_Impl::ReadValueAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadValueWithCacheModeAsync(this: *mut core::ffi::c_void, cachemode: super::BluetoothCacheMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDescriptor_Impl::ReadValueWithCacheModeAsync(this, cachemode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WriteValueAsync(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDescriptor_Impl::WriteValueAsync(this, core::mem::transmute_copy(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ProtectionLevel: ProtectionLevel::, + SetProtectionLevel: SetProtectionLevel::, + Uuid: Uuid::, + AttributeHandle: AttributeHandle::, + ReadValueAsync: ReadValueAsync::, + ReadValueWithCacheModeAsync: ReadValueWithCacheModeAsync::, + WriteValueAsync: WriteValueAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattDescriptor_Vtbl { @@ -4533,6 +12191,39 @@ windows_core::imp::define_interface!(IGattDescriptor2, IGattDescriptor2_Vtbl, 0x impl windows_core::RuntimeType for IGattDescriptor2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IGattDescriptor2 { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDescriptor2"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IGattDescriptor2_Impl: windows_core::IUnknownImpl { + fn WriteValueWithResultAsync(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result>; +} +#[cfg(feature = "Storage_Streams")] +impl IGattDescriptor2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn WriteValueWithResultAsync(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDescriptor2_Impl::WriteValueWithResultAsync(this, core::mem::transmute_copy(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + WriteValueWithResultAsync: WriteValueWithResultAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattDescriptor2_Vtbl { @@ -4546,16 +12237,107 @@ windows_core::imp::define_interface!(IGattDescriptorStatics, IGattDescriptorStat impl windows_core::RuntimeType for IGattDescriptorStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattDescriptorStatics { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDescriptorStatics"; +} +pub trait IGattDescriptorStatics_Impl: windows_core::IUnknownImpl { + fn ConvertShortIdToUuid(&self, shortId: u16) -> windows_core::Result; +} +impl IGattDescriptorStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ConvertShortIdToUuid(this: *mut core::ffi::c_void, shortid: u16, result__: *mut windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDescriptorStatics_Impl::ConvertShortIdToUuid(this, shortid) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ConvertShortIdToUuid: ConvertShortIdToUuid::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattDescriptorStatics_Vtbl { pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "deprecated")] pub ConvertShortIdToUuid: unsafe extern "system" fn(*mut core::ffi::c_void, u16, *mut windows_core::GUID) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + ConvertShortIdToUuid: usize, } windows_core::imp::define_interface!(IGattDescriptorsResult, IGattDescriptorsResult_Vtbl, 0x9bc091f3_95e7_4489_8d25_ff81955a57b9); impl windows_core::RuntimeType for IGattDescriptorsResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattDescriptorsResult { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDescriptorsResult"; +} +pub trait IGattDescriptorsResult_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; + fn ProtocolError(&self) -> windows_core::Result>; + fn Descriptors(&self) -> windows_core::Result>; +} +impl IGattDescriptorsResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut GattCommunicationStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDescriptorsResult_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ProtocolError(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDescriptorsResult_Impl::ProtocolError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Descriptors(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDescriptorsResult_Impl::Descriptors(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Status: Status::, + ProtocolError: ProtocolError::, + Descriptors: Descriptors::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattDescriptorsResult_Vtbl { @@ -4568,12 +12350,106 @@ windows_core::imp::define_interface!(IGattDeviceService, IGattDeviceService_Vtbl impl windows_core::RuntimeType for IGattDeviceService { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattDeviceService { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDeviceService"; +} +pub trait IGattDeviceService_Impl: super::super::super::Foundation::IClosable_Impl { + fn GetCharacteristics(&self, characteristicUuid: &windows_core::GUID) -> windows_core::Result>; + fn GetIncludedServices(&self, serviceUuid: &windows_core::GUID) -> windows_core::Result>; + fn DeviceId(&self) -> windows_core::Result; + fn Uuid(&self) -> windows_core::Result; + fn AttributeHandle(&self) -> windows_core::Result; +} +impl IGattDeviceService_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetCharacteristics(this: *mut core::ffi::c_void, characteristicuuid: windows_core::GUID, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService_Impl::GetCharacteristics(this, core::mem::transmute(&characteristicuuid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetIncludedServices(this: *mut core::ffi::c_void, serviceuuid: windows_core::GUID, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService_Impl::GetIncludedServices(this, core::mem::transmute(&serviceuuid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Uuid(this: *mut core::ffi::c_void, result__: *mut windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService_Impl::Uuid(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AttributeHandle(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService_Impl::AttributeHandle(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetCharacteristics: GetCharacteristics::, + GetIncludedServices: GetIncludedServices::, + DeviceId: DeviceId::, + Uuid: Uuid::, + AttributeHandle: AttributeHandle::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattDeviceService_Vtbl { pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "deprecated")] pub GetCharacteristics: unsafe extern "system" fn(*mut core::ffi::c_void, windows_core::GUID, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + GetCharacteristics: usize, + #[cfg(feature = "deprecated")] pub GetIncludedServices: unsafe extern "system" fn(*mut core::ffi::c_void, windows_core::GUID, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + GetIncludedServices: usize, pub DeviceId: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, pub Uuid: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_core::GUID) -> windows_core::HRESULT, pub AttributeHandle: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u16) -> windows_core::HRESULT, @@ -4582,19 +12458,318 @@ windows_core::imp::define_interface!(IGattDeviceService2, IGattDeviceService2_Vt impl windows_core::RuntimeType for IGattDeviceService2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattDeviceService2 { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDeviceService2"; +} +pub trait IGattDeviceService2_Impl: super::super::super::Foundation::IClosable_Impl + IGattDeviceService_Impl { + fn Device(&self) -> windows_core::Result; + fn ParentServices(&self) -> windows_core::Result>; + fn GetAllCharacteristics(&self) -> windows_core::Result>; + fn GetAllIncludedServices(&self) -> windows_core::Result>; +} +impl IGattDeviceService2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Device(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService2_Impl::Device(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ParentServices(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService2_Impl::ParentServices(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetAllCharacteristics(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService2_Impl::GetAllCharacteristics(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetAllIncludedServices(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService2_Impl::GetAllIncludedServices(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Device: Device::, + ParentServices: ParentServices::, + GetAllCharacteristics: GetAllCharacteristics::, + GetAllIncludedServices: GetAllIncludedServices::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattDeviceService2_Vtbl { pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "deprecated")] pub Device: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + Device: usize, + #[cfg(feature = "deprecated")] pub ParentServices: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + ParentServices: usize, + #[cfg(feature = "deprecated")] pub GetAllCharacteristics: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + GetAllCharacteristics: usize, + #[cfg(feature = "deprecated")] pub GetAllIncludedServices: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + GetAllIncludedServices: usize, } windows_core::imp::define_interface!(IGattDeviceService3, IGattDeviceService3_Vtbl, 0xb293a950_0c53_437c_a9b3_5c3210c6e569); impl windows_core::RuntimeType for IGattDeviceService3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Enumeration")] +impl windows_core::RuntimeName for IGattDeviceService3 { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDeviceService3"; +} +#[cfg(feature = "Devices_Enumeration")] +pub trait IGattDeviceService3_Impl: windows_core::IUnknownImpl { + fn DeviceAccessInformation(&self) -> windows_core::Result; + fn Session(&self) -> windows_core::Result; + fn SharingMode(&self) -> windows_core::Result; + fn RequestAccessAsync(&self) -> windows_core::Result>; + fn OpenAsync(&self, sharingMode: GattSharingMode) -> windows_core::Result>; + fn GetCharacteristicsAsync(&self) -> windows_core::Result>; + fn GetCharacteristicsWithCacheModeAsync(&self, cacheMode: super::BluetoothCacheMode) -> windows_core::Result>; + fn GetCharacteristicsForUuidAsync(&self, characteristicUuid: &windows_core::GUID) -> windows_core::Result>; + fn GetCharacteristicsForUuidWithCacheModeAsync(&self, characteristicUuid: &windows_core::GUID, cacheMode: super::BluetoothCacheMode) -> windows_core::Result>; + fn GetIncludedServicesAsync(&self) -> windows_core::Result>; + fn GetIncludedServicesWithCacheModeAsync(&self, cacheMode: super::BluetoothCacheMode) -> windows_core::Result>; + fn GetIncludedServicesForUuidAsync(&self, serviceUuid: &windows_core::GUID) -> windows_core::Result>; + fn GetIncludedServicesForUuidWithCacheModeAsync(&self, serviceUuid: &windows_core::GUID, cacheMode: super::BluetoothCacheMode) -> windows_core::Result>; +} +#[cfg(feature = "Devices_Enumeration")] +impl IGattDeviceService3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceAccessInformation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService3_Impl::DeviceAccessInformation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Session(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService3_Impl::Session(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SharingMode(this: *mut core::ffi::c_void, result__: *mut GattSharingMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService3_Impl::SharingMode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RequestAccessAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService3_Impl::RequestAccessAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OpenAsync(this: *mut core::ffi::c_void, sharingmode: GattSharingMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService3_Impl::OpenAsync(this, sharingmode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetCharacteristicsAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService3_Impl::GetCharacteristicsAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetCharacteristicsWithCacheModeAsync(this: *mut core::ffi::c_void, cachemode: super::BluetoothCacheMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService3_Impl::GetCharacteristicsWithCacheModeAsync(this, cachemode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetCharacteristicsForUuidAsync(this: *mut core::ffi::c_void, characteristicuuid: windows_core::GUID, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService3_Impl::GetCharacteristicsForUuidAsync(this, core::mem::transmute(&characteristicuuid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetCharacteristicsForUuidWithCacheModeAsync(this: *mut core::ffi::c_void, characteristicuuid: windows_core::GUID, cachemode: super::BluetoothCacheMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService3_Impl::GetCharacteristicsForUuidWithCacheModeAsync(this, core::mem::transmute(&characteristicuuid), cachemode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetIncludedServicesAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService3_Impl::GetIncludedServicesAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetIncludedServicesWithCacheModeAsync(this: *mut core::ffi::c_void, cachemode: super::BluetoothCacheMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService3_Impl::GetIncludedServicesWithCacheModeAsync(this, cachemode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetIncludedServicesForUuidAsync(this: *mut core::ffi::c_void, serviceuuid: windows_core::GUID, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService3_Impl::GetIncludedServicesForUuidAsync(this, core::mem::transmute(&serviceuuid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetIncludedServicesForUuidWithCacheModeAsync(this: *mut core::ffi::c_void, serviceuuid: windows_core::GUID, cachemode: super::BluetoothCacheMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceService3_Impl::GetIncludedServicesForUuidWithCacheModeAsync(this, core::mem::transmute(&serviceuuid), cachemode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DeviceAccessInformation: DeviceAccessInformation::, + Session: Session::, + SharingMode: SharingMode::, + RequestAccessAsync: RequestAccessAsync::, + OpenAsync: OpenAsync::, + GetCharacteristicsAsync: GetCharacteristicsAsync::, + GetCharacteristicsWithCacheModeAsync: GetCharacteristicsWithCacheModeAsync::, + GetCharacteristicsForUuidAsync: GetCharacteristicsForUuidAsync::, + GetCharacteristicsForUuidWithCacheModeAsync: GetCharacteristicsForUuidWithCacheModeAsync::, + GetIncludedServicesAsync: GetIncludedServicesAsync::, + GetIncludedServicesWithCacheModeAsync: GetIncludedServicesWithCacheModeAsync::, + GetIncludedServicesForUuidAsync: GetIncludedServicesForUuidAsync::, + GetIncludedServicesForUuidWithCacheModeAsync: GetIncludedServicesForUuidWithCacheModeAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattDeviceService3_Vtbl { @@ -4623,19 +12798,189 @@ windows_core::imp::define_interface!(IGattDeviceServiceStatics, IGattDeviceServi impl windows_core::RuntimeType for IGattDeviceServiceStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattDeviceServiceStatics { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDeviceServiceStatics"; +} +pub trait IGattDeviceServiceStatics_Impl: windows_core::IUnknownImpl { + fn FromIdAsync(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; + fn GetDeviceSelectorFromUuid(&self, serviceUuid: &windows_core::GUID) -> windows_core::Result; + fn GetDeviceSelectorFromShortId(&self, serviceShortId: u16) -> windows_core::Result; + fn ConvertShortIdToUuid(&self, shortId: u16) -> windows_core::Result; +} +impl IGattDeviceServiceStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FromIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceServiceStatics_Impl::FromIdAsync(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelectorFromUuid(this: *mut core::ffi::c_void, serviceuuid: windows_core::GUID, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceServiceStatics_Impl::GetDeviceSelectorFromUuid(this, core::mem::transmute(&serviceuuid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelectorFromShortId(this: *mut core::ffi::c_void, serviceshortid: u16, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceServiceStatics_Impl::GetDeviceSelectorFromShortId(this, serviceshortid) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ConvertShortIdToUuid(this: *mut core::ffi::c_void, shortid: u16, result__: *mut windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceServiceStatics_Impl::ConvertShortIdToUuid(this, shortid) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FromIdAsync: FromIdAsync::, + GetDeviceSelectorFromUuid: GetDeviceSelectorFromUuid::, + GetDeviceSelectorFromShortId: GetDeviceSelectorFromShortId::, + ConvertShortIdToUuid: ConvertShortIdToUuid::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattDeviceServiceStatics_Vtbl { pub base__: windows_core::IInspectable_Vtbl, pub FromIdAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, pub GetDeviceSelectorFromUuid: unsafe extern "system" fn(*mut core::ffi::c_void, windows_core::GUID, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "deprecated")] pub GetDeviceSelectorFromShortId: unsafe extern "system" fn(*mut core::ffi::c_void, u16, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + GetDeviceSelectorFromShortId: usize, + #[cfg(feature = "deprecated")] pub ConvertShortIdToUuid: unsafe extern "system" fn(*mut core::ffi::c_void, u16, *mut windows_core::GUID) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + ConvertShortIdToUuid: usize, } windows_core::imp::define_interface!(IGattDeviceServiceStatics2, IGattDeviceServiceStatics2_Vtbl, 0x0604186e_24a6_4b0d_a2f2_30cc01545d25); impl windows_core::RuntimeType for IGattDeviceServiceStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattDeviceServiceStatics2 { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDeviceServiceStatics2"; +} +pub trait IGattDeviceServiceStatics2_Impl: windows_core::IUnknownImpl { + fn FromIdWithSharingModeAsync(&self, deviceId: &windows_core::HSTRING, sharingMode: GattSharingMode) -> windows_core::Result>; + fn GetDeviceSelectorForBluetoothDeviceId(&self, bluetoothDeviceId: windows_core::Ref<'_, super::BluetoothDeviceId>) -> windows_core::Result; + fn GetDeviceSelectorForBluetoothDeviceIdWithCacheMode(&self, bluetoothDeviceId: windows_core::Ref<'_, super::BluetoothDeviceId>, cacheMode: super::BluetoothCacheMode) -> windows_core::Result; + fn GetDeviceSelectorForBluetoothDeviceIdAndUuid(&self, bluetoothDeviceId: windows_core::Ref<'_, super::BluetoothDeviceId>, serviceUuid: &windows_core::GUID) -> windows_core::Result; + fn GetDeviceSelectorForBluetoothDeviceIdAndUuidWithCacheMode(&self, bluetoothDeviceId: windows_core::Ref<'_, super::BluetoothDeviceId>, serviceUuid: &windows_core::GUID, cacheMode: super::BluetoothCacheMode) -> windows_core::Result; +} +impl IGattDeviceServiceStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FromIdWithSharingModeAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, sharingmode: GattSharingMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceServiceStatics2_Impl::FromIdWithSharingModeAsync(this, core::mem::transmute(&deviceid), sharingmode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelectorForBluetoothDeviceId(this: *mut core::ffi::c_void, bluetoothdeviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceServiceStatics2_Impl::GetDeviceSelectorForBluetoothDeviceId(this, core::mem::transmute_copy(&bluetoothdeviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelectorForBluetoothDeviceIdWithCacheMode(this: *mut core::ffi::c_void, bluetoothdeviceid: *mut core::ffi::c_void, cachemode: super::BluetoothCacheMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceServiceStatics2_Impl::GetDeviceSelectorForBluetoothDeviceIdWithCacheMode(this, core::mem::transmute_copy(&bluetoothdeviceid), cachemode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelectorForBluetoothDeviceIdAndUuid(this: *mut core::ffi::c_void, bluetoothdeviceid: *mut core::ffi::c_void, serviceuuid: windows_core::GUID, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceServiceStatics2_Impl::GetDeviceSelectorForBluetoothDeviceIdAndUuid(this, core::mem::transmute_copy(&bluetoothdeviceid), core::mem::transmute(&serviceuuid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelectorForBluetoothDeviceIdAndUuidWithCacheMode(this: *mut core::ffi::c_void, bluetoothdeviceid: *mut core::ffi::c_void, serviceuuid: windows_core::GUID, cachemode: super::BluetoothCacheMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceServiceStatics2_Impl::GetDeviceSelectorForBluetoothDeviceIdAndUuidWithCacheMode(this, core::mem::transmute_copy(&bluetoothdeviceid), core::mem::transmute(&serviceuuid), cachemode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FromIdWithSharingModeAsync: FromIdWithSharingModeAsync::, + GetDeviceSelectorForBluetoothDeviceId: GetDeviceSelectorForBluetoothDeviceId::, + GetDeviceSelectorForBluetoothDeviceIdWithCacheMode: GetDeviceSelectorForBluetoothDeviceIdWithCacheMode::, + GetDeviceSelectorForBluetoothDeviceIdAndUuid: GetDeviceSelectorForBluetoothDeviceIdAndUuid::, + GetDeviceSelectorForBluetoothDeviceIdAndUuidWithCacheMode: GetDeviceSelectorForBluetoothDeviceIdAndUuidWithCacheMode::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattDeviceServiceStatics2_Vtbl { @@ -4650,6 +12995,65 @@ windows_core::imp::define_interface!(IGattDeviceServicesResult, IGattDeviceServi impl windows_core::RuntimeType for IGattDeviceServicesResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattDeviceServicesResult { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDeviceServicesResult"; +} +pub trait IGattDeviceServicesResult_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; + fn ProtocolError(&self) -> windows_core::Result>; + fn Services(&self) -> windows_core::Result>; +} +impl IGattDeviceServicesResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut GattCommunicationStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceServicesResult_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ProtocolError(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceServicesResult_Impl::ProtocolError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Services(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattDeviceServicesResult_Impl::Services(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Status: Status::, + ProtocolError: ProtocolError::, + Services: Services::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattDeviceServicesResult_Vtbl { @@ -4662,6 +13066,266 @@ windows_core::imp::define_interface!(IGattLocalCharacteristic, IGattLocalCharact impl windows_core::RuntimeType for IGattLocalCharacteristic { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IGattLocalCharacteristic { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattLocalCharacteristic"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IGattLocalCharacteristic_Impl: windows_core::IUnknownImpl { + fn Uuid(&self) -> windows_core::Result; + fn StaticValue(&self) -> windows_core::Result; + fn CharacteristicProperties(&self) -> windows_core::Result; + fn ReadProtectionLevel(&self) -> windows_core::Result; + fn WriteProtectionLevel(&self) -> windows_core::Result; + fn CreateDescriptorAsync(&self, descriptorUuid: &windows_core::GUID, parameters: windows_core::Ref<'_, GattLocalDescriptorParameters>) -> windows_core::Result>; + fn Descriptors(&self) -> windows_core::Result>; + fn UserDescription(&self) -> windows_core::Result; + fn PresentationFormats(&self) -> windows_core::Result>; + fn SubscribedClients(&self) -> windows_core::Result>; + fn SubscribedClientsChanged(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveSubscribedClientsChanged(&self, token: i64) -> windows_core::Result<()>; + fn ReadRequested(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveReadRequested(&self, token: i64) -> windows_core::Result<()>; + fn WriteRequested(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveWriteRequested(&self, token: i64) -> windows_core::Result<()>; + fn NotifyValueAsync(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result>>; + fn NotifyValueForSubscribedClientAsync(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>, subscribedClient: windows_core::Ref<'_, GattSubscribedClient>) -> windows_core::Result>; +} +#[cfg(feature = "Storage_Streams")] +impl IGattLocalCharacteristic_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Uuid(this: *mut core::ffi::c_void, result__: *mut windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristic_Impl::Uuid(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StaticValue(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristic_Impl::StaticValue(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CharacteristicProperties(this: *mut core::ffi::c_void, result__: *mut GattCharacteristicProperties) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristic_Impl::CharacteristicProperties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadProtectionLevel(this: *mut core::ffi::c_void, result__: *mut GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristic_Impl::ReadProtectionLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WriteProtectionLevel(this: *mut core::ffi::c_void, result__: *mut GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristic_Impl::WriteProtectionLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateDescriptorAsync(this: *mut core::ffi::c_void, descriptoruuid: windows_core::GUID, parameters: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristic_Impl::CreateDescriptorAsync(this, core::mem::transmute(&descriptoruuid), core::mem::transmute_copy(¶meters)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Descriptors(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristic_Impl::Descriptors(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn UserDescription(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristic_Impl::UserDescription(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PresentationFormats(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristic_Impl::PresentationFormats(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SubscribedClients(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristic_Impl::SubscribedClients(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SubscribedClientsChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristic_Impl::SubscribedClientsChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveSubscribedClientsChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattLocalCharacteristic_Impl::RemoveSubscribedClientsChanged(this, token).into() + } + } + unsafe extern "system" fn ReadRequested(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristic_Impl::ReadRequested(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveReadRequested(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattLocalCharacteristic_Impl::RemoveReadRequested(this, token).into() + } + } + unsafe extern "system" fn WriteRequested(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristic_Impl::WriteRequested(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveWriteRequested(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattLocalCharacteristic_Impl::RemoveWriteRequested(this, token).into() + } + } + unsafe extern "system" fn NotifyValueAsync(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristic_Impl::NotifyValueAsync(this, core::mem::transmute_copy(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NotifyValueForSubscribedClientAsync(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void, subscribedclient: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristic_Impl::NotifyValueForSubscribedClientAsync(this, core::mem::transmute_copy(&value), core::mem::transmute_copy(&subscribedclient)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Uuid: Uuid::, + StaticValue: StaticValue::, + CharacteristicProperties: CharacteristicProperties::, + ReadProtectionLevel: ReadProtectionLevel::, + WriteProtectionLevel: WriteProtectionLevel::, + CreateDescriptorAsync: CreateDescriptorAsync::, + Descriptors: Descriptors::, + UserDescription: UserDescription::, + PresentationFormats: PresentationFormats::, + SubscribedClients: SubscribedClients::, + SubscribedClientsChanged: SubscribedClientsChanged::, + RemoveSubscribedClientsChanged: RemoveSubscribedClientsChanged::, + ReadRequested: ReadRequested::, + RemoveReadRequested: RemoveReadRequested::, + WriteRequested: WriteRequested::, + RemoveWriteRequested: RemoveWriteRequested::, + NotifyValueAsync: NotifyValueAsync::, + NotifyValueForSubscribedClientAsync: NotifyValueForSubscribedClientAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattLocalCharacteristic_Vtbl { @@ -4698,6 +13362,151 @@ windows_core::imp::define_interface!(IGattLocalCharacteristicParameters, IGattLo impl windows_core::RuntimeType for IGattLocalCharacteristicParameters { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IGattLocalCharacteristicParameters { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattLocalCharacteristicParameters"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IGattLocalCharacteristicParameters_Impl: windows_core::IUnknownImpl { + fn SetStaticValue(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result<()>; + fn StaticValue(&self) -> windows_core::Result; + fn SetCharacteristicProperties(&self, value: GattCharacteristicProperties) -> windows_core::Result<()>; + fn CharacteristicProperties(&self) -> windows_core::Result; + fn SetReadProtectionLevel(&self, value: GattProtectionLevel) -> windows_core::Result<()>; + fn ReadProtectionLevel(&self) -> windows_core::Result; + fn SetWriteProtectionLevel(&self, value: GattProtectionLevel) -> windows_core::Result<()>; + fn WriteProtectionLevel(&self) -> windows_core::Result; + fn SetUserDescription(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn UserDescription(&self) -> windows_core::Result; + fn PresentationFormats(&self) -> windows_core::Result>; +} +#[cfg(feature = "Storage_Streams")] +impl IGattLocalCharacteristicParameters_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetStaticValue(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattLocalCharacteristicParameters_Impl::SetStaticValue(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn StaticValue(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristicParameters_Impl::StaticValue(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetCharacteristicProperties(this: *mut core::ffi::c_void, value: GattCharacteristicProperties) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattLocalCharacteristicParameters_Impl::SetCharacteristicProperties(this, value).into() + } + } + unsafe extern "system" fn CharacteristicProperties(this: *mut core::ffi::c_void, result__: *mut GattCharacteristicProperties) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristicParameters_Impl::CharacteristicProperties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetReadProtectionLevel(this: *mut core::ffi::c_void, value: GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattLocalCharacteristicParameters_Impl::SetReadProtectionLevel(this, value).into() + } + } + unsafe extern "system" fn ReadProtectionLevel(this: *mut core::ffi::c_void, result__: *mut GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristicParameters_Impl::ReadProtectionLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetWriteProtectionLevel(this: *mut core::ffi::c_void, value: GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattLocalCharacteristicParameters_Impl::SetWriteProtectionLevel(this, value).into() + } + } + unsafe extern "system" fn WriteProtectionLevel(this: *mut core::ffi::c_void, result__: *mut GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristicParameters_Impl::WriteProtectionLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetUserDescription(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattLocalCharacteristicParameters_Impl::SetUserDescription(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn UserDescription(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristicParameters_Impl::UserDescription(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PresentationFormats(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristicParameters_Impl::PresentationFormats(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetStaticValue: SetStaticValue::, + StaticValue: StaticValue::, + SetCharacteristicProperties: SetCharacteristicProperties::, + CharacteristicProperties: CharacteristicProperties::, + SetReadProtectionLevel: SetReadProtectionLevel::, + ReadProtectionLevel: ReadProtectionLevel::, + SetWriteProtectionLevel: SetWriteProtectionLevel::, + WriteProtectionLevel: WriteProtectionLevel::, + SetUserDescription: SetUserDescription::, + UserDescription: UserDescription::, + PresentationFormats: PresentationFormats::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattLocalCharacteristicParameters_Vtbl { @@ -4724,6 +13533,50 @@ windows_core::imp::define_interface!(IGattLocalCharacteristicResult, IGattLocalC impl windows_core::RuntimeType for IGattLocalCharacteristicResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattLocalCharacteristicResult { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattLocalCharacteristicResult"; +} +pub trait IGattLocalCharacteristicResult_Impl: windows_core::IUnknownImpl { + fn Characteristic(&self) -> windows_core::Result; + fn Error(&self) -> windows_core::Result; +} +impl IGattLocalCharacteristicResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Characteristic(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristicResult_Impl::Characteristic(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Error(this: *mut core::ffi::c_void, result__: *mut super::BluetoothError) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalCharacteristicResult_Impl::Error(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Characteristic: Characteristic::, + Error: Error::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattLocalCharacteristicResult_Vtbl { @@ -4735,6 +13588,125 @@ windows_core::imp::define_interface!(IGattLocalDescriptor, IGattLocalDescriptor_ impl windows_core::RuntimeType for IGattLocalDescriptor { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IGattLocalDescriptor { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattLocalDescriptor"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IGattLocalDescriptor_Impl: windows_core::IUnknownImpl { + fn Uuid(&self) -> windows_core::Result; + fn StaticValue(&self) -> windows_core::Result; + fn ReadProtectionLevel(&self) -> windows_core::Result; + fn WriteProtectionLevel(&self) -> windows_core::Result; + fn ReadRequested(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveReadRequested(&self, token: i64) -> windows_core::Result<()>; + fn WriteRequested(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveWriteRequested(&self, token: i64) -> windows_core::Result<()>; +} +#[cfg(feature = "Storage_Streams")] +impl IGattLocalDescriptor_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Uuid(this: *mut core::ffi::c_void, result__: *mut windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalDescriptor_Impl::Uuid(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StaticValue(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalDescriptor_Impl::StaticValue(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadProtectionLevel(this: *mut core::ffi::c_void, result__: *mut GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalDescriptor_Impl::ReadProtectionLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WriteProtectionLevel(this: *mut core::ffi::c_void, result__: *mut GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalDescriptor_Impl::WriteProtectionLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadRequested(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalDescriptor_Impl::ReadRequested(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveReadRequested(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattLocalDescriptor_Impl::RemoveReadRequested(this, token).into() + } + } + unsafe extern "system" fn WriteRequested(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalDescriptor_Impl::WriteRequested(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveWriteRequested(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattLocalDescriptor_Impl::RemoveWriteRequested(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Uuid: Uuid::, + StaticValue: StaticValue::, + ReadProtectionLevel: ReadProtectionLevel::, + WriteProtectionLevel: WriteProtectionLevel::, + ReadRequested: ReadRequested::, + RemoveReadRequested: RemoveReadRequested::, + WriteRequested: WriteRequested::, + RemoveWriteRequested: RemoveWriteRequested::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattLocalDescriptor_Vtbl { @@ -4755,6 +13727,91 @@ windows_core::imp::define_interface!(IGattLocalDescriptorParameters, IGattLocalD impl windows_core::RuntimeType for IGattLocalDescriptorParameters { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IGattLocalDescriptorParameters { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattLocalDescriptorParameters"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IGattLocalDescriptorParameters_Impl: windows_core::IUnknownImpl { + fn SetStaticValue(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result<()>; + fn StaticValue(&self) -> windows_core::Result; + fn SetReadProtectionLevel(&self, value: GattProtectionLevel) -> windows_core::Result<()>; + fn ReadProtectionLevel(&self) -> windows_core::Result; + fn SetWriteProtectionLevel(&self, value: GattProtectionLevel) -> windows_core::Result<()>; + fn WriteProtectionLevel(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IGattLocalDescriptorParameters_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetStaticValue(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattLocalDescriptorParameters_Impl::SetStaticValue(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn StaticValue(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalDescriptorParameters_Impl::StaticValue(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetReadProtectionLevel(this: *mut core::ffi::c_void, value: GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattLocalDescriptorParameters_Impl::SetReadProtectionLevel(this, value).into() + } + } + unsafe extern "system" fn ReadProtectionLevel(this: *mut core::ffi::c_void, result__: *mut GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalDescriptorParameters_Impl::ReadProtectionLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetWriteProtectionLevel(this: *mut core::ffi::c_void, value: GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattLocalDescriptorParameters_Impl::SetWriteProtectionLevel(this, value).into() + } + } + unsafe extern "system" fn WriteProtectionLevel(this: *mut core::ffi::c_void, result__: *mut GattProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalDescriptorParameters_Impl::WriteProtectionLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetStaticValue: SetStaticValue::, + StaticValue: StaticValue::, + SetReadProtectionLevel: SetReadProtectionLevel::, + ReadProtectionLevel: ReadProtectionLevel::, + SetWriteProtectionLevel: SetWriteProtectionLevel::, + WriteProtectionLevel: WriteProtectionLevel::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattLocalDescriptorParameters_Vtbl { @@ -4776,6 +13833,50 @@ windows_core::imp::define_interface!(IGattLocalDescriptorResult, IGattLocalDescr impl windows_core::RuntimeType for IGattLocalDescriptorResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattLocalDescriptorResult { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattLocalDescriptorResult"; +} +pub trait IGattLocalDescriptorResult_Impl: windows_core::IUnknownImpl { + fn Descriptor(&self) -> windows_core::Result; + fn Error(&self) -> windows_core::Result; +} +impl IGattLocalDescriptorResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Descriptor(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalDescriptorResult_Impl::Descriptor(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Error(this: *mut core::ffi::c_void, result__: *mut super::BluetoothError) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalDescriptorResult_Impl::Error(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Descriptor: Descriptor::, + Error: Error::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattLocalDescriptorResult_Vtbl { @@ -4787,6 +13888,65 @@ windows_core::imp::define_interface!(IGattLocalService, IGattLocalService_Vtbl, impl windows_core::RuntimeType for IGattLocalService { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattLocalService { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattLocalService"; +} +pub trait IGattLocalService_Impl: windows_core::IUnknownImpl { + fn Uuid(&self) -> windows_core::Result; + fn CreateCharacteristicAsync(&self, characteristicUuid: &windows_core::GUID, parameters: windows_core::Ref<'_, GattLocalCharacteristicParameters>) -> windows_core::Result>; + fn Characteristics(&self) -> windows_core::Result>; +} +impl IGattLocalService_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Uuid(this: *mut core::ffi::c_void, result__: *mut windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalService_Impl::Uuid(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateCharacteristicAsync(this: *mut core::ffi::c_void, characteristicuuid: windows_core::GUID, parameters: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalService_Impl::CreateCharacteristicAsync(this, core::mem::transmute(&characteristicuuid), core::mem::transmute_copy(¶meters)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Characteristics(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattLocalService_Impl::Characteristics(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Uuid: Uuid::, + CreateCharacteristicAsync: CreateCharacteristicAsync::, + Characteristics: Characteristics::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattLocalService_Vtbl { @@ -4799,6 +13959,91 @@ windows_core::imp::define_interface!(IGattPresentationFormat, IGattPresentationF impl windows_core::RuntimeType for IGattPresentationFormat { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattPresentationFormat { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattPresentationFormat"; +} +pub trait IGattPresentationFormat_Impl: windows_core::IUnknownImpl { + fn FormatType(&self) -> windows_core::Result; + fn Exponent(&self) -> windows_core::Result; + fn Unit(&self) -> windows_core::Result; + fn Namespace(&self) -> windows_core::Result; + fn Description(&self) -> windows_core::Result; +} +impl IGattPresentationFormat_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FormatType(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattPresentationFormat_Impl::FormatType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Exponent(this: *mut core::ffi::c_void, result__: *mut i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattPresentationFormat_Impl::Exponent(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Unit(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattPresentationFormat_Impl::Unit(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Namespace(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattPresentationFormat_Impl::Namespace(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Description(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattPresentationFormat_Impl::Description(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FormatType: FormatType::, + Exponent: Exponent::, + Unit: Unit::, + Namespace: Namespace::, + Description: Description::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattPresentationFormat_Vtbl { @@ -4813,6 +14058,35 @@ windows_core::imp::define_interface!(IGattPresentationFormatStatics, IGattPresen impl windows_core::RuntimeType for IGattPresentationFormatStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattPresentationFormatStatics { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattPresentationFormatStatics"; +} +pub trait IGattPresentationFormatStatics_Impl: windows_core::IUnknownImpl { + fn BluetoothSigAssignedNumbers(&self) -> windows_core::Result; +} +impl IGattPresentationFormatStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn BluetoothSigAssignedNumbers(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattPresentationFormatStatics_Impl::BluetoothSigAssignedNumbers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + BluetoothSigAssignedNumbers: BluetoothSigAssignedNumbers::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattPresentationFormatStatics_Vtbl { @@ -4823,6 +14097,33 @@ windows_core::imp::define_interface!(IGattPresentationFormatStatics2, IGattPrese impl windows_core::RuntimeType for IGattPresentationFormatStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattPresentationFormatStatics2 { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattPresentationFormatStatics2"; +} +pub trait IGattPresentationFormatStatics2_Impl: IGattPresentationFormatStatics_Impl { + fn FromParts(&self, formatType: u8, exponent: i32, unit: u16, namespaceId: u8, description: u16) -> windows_core::Result; +} +impl IGattPresentationFormatStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FromParts(this: *mut core::ffi::c_void, formattype: u8, exponent: i32, unit: u16, namespaceid: u8, description: u16, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattPresentationFormatStatics2_Impl::FromParts(this, formattype, exponent, unit, namespaceid, description) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), FromParts: FromParts:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattPresentationFormatStatics2_Vtbl { @@ -4833,6 +14134,49 @@ windows_core::imp::define_interface!(IGattReadClientCharacteristicConfigurationD impl windows_core::RuntimeType for IGattReadClientCharacteristicConfigurationDescriptorResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattReadClientCharacteristicConfigurationDescriptorResult { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattReadClientCharacteristicConfigurationDescriptorResult"; +} +pub trait IGattReadClientCharacteristicConfigurationDescriptorResult_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; + fn ClientCharacteristicConfigurationDescriptor(&self) -> windows_core::Result; +} +impl IGattReadClientCharacteristicConfigurationDescriptorResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut GattCommunicationStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattReadClientCharacteristicConfigurationDescriptorResult_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ClientCharacteristicConfigurationDescriptor(this: *mut core::ffi::c_void, result__: *mut GattClientCharacteristicConfigurationDescriptorValue) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattReadClientCharacteristicConfigurationDescriptorResult_Impl::ClientCharacteristicConfigurationDescriptor(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Status: Status::, + ClientCharacteristicConfigurationDescriptor: ClientCharacteristicConfigurationDescriptor::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattReadClientCharacteristicConfigurationDescriptorResult_Vtbl { @@ -4844,6 +14188,36 @@ windows_core::imp::define_interface!(IGattReadClientCharacteristicConfigurationD impl windows_core::RuntimeType for IGattReadClientCharacteristicConfigurationDescriptorResult2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattReadClientCharacteristicConfigurationDescriptorResult2 { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattReadClientCharacteristicConfigurationDescriptorResult2"; +} +pub trait IGattReadClientCharacteristicConfigurationDescriptorResult2_Impl: windows_core::IUnknownImpl { + fn ProtocolError(&self) -> windows_core::Result>; +} +impl IGattReadClientCharacteristicConfigurationDescriptorResult2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ProtocolError(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattReadClientCharacteristicConfigurationDescriptorResult2_Impl::ProtocolError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ProtocolError: ProtocolError::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattReadClientCharacteristicConfigurationDescriptorResult2_Vtbl { @@ -4854,6 +14228,104 @@ windows_core::imp::define_interface!(IGattReadRequest, IGattReadRequest_Vtbl, 0x impl windows_core::RuntimeType for IGattReadRequest { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IGattReadRequest { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattReadRequest"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IGattReadRequest_Impl: windows_core::IUnknownImpl { + fn Offset(&self) -> windows_core::Result; + fn Length(&self) -> windows_core::Result; + fn State(&self) -> windows_core::Result; + fn StateChanged(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveStateChanged(&self, token: i64) -> windows_core::Result<()>; + fn RespondWithValue(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result<()>; + fn RespondWithProtocolError(&self, protocolError: u8) -> windows_core::Result<()>; +} +#[cfg(feature = "Storage_Streams")] +impl IGattReadRequest_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Offset(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattReadRequest_Impl::Offset(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Length(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattReadRequest_Impl::Length(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn State(this: *mut core::ffi::c_void, result__: *mut GattRequestState) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattReadRequest_Impl::State(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StateChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattReadRequest_Impl::StateChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveStateChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattReadRequest_Impl::RemoveStateChanged(this, token).into() + } + } + unsafe extern "system" fn RespondWithValue(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattReadRequest_Impl::RespondWithValue(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn RespondWithProtocolError(this: *mut core::ffi::c_void, protocolerror: u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattReadRequest_Impl::RespondWithProtocolError(this, protocolerror).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Offset: Offset::, + Length: Length::, + State: State::, + StateChanged: StateChanged::, + RemoveStateChanged: RemoveStateChanged::, + RespondWithValue: RespondWithValue::, + RespondWithProtocolError: RespondWithProtocolError::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattReadRequest_Vtbl { @@ -4873,6 +14345,66 @@ windows_core::imp::define_interface!(IGattReadRequestedEventArgs, IGattReadReque impl windows_core::RuntimeType for IGattReadRequestedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattReadRequestedEventArgs { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattReadRequestedEventArgs"; +} +pub trait IGattReadRequestedEventArgs_Impl: windows_core::IUnknownImpl { + fn Session(&self) -> windows_core::Result; + fn GetDeferral(&self) -> windows_core::Result; + fn GetRequestAsync(&self) -> windows_core::Result>; +} +impl IGattReadRequestedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Session(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattReadRequestedEventArgs_Impl::Session(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeferral(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattReadRequestedEventArgs_Impl::GetDeferral(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetRequestAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattReadRequestedEventArgs_Impl::GetRequestAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Session: Session::, + GetDeferral: GetDeferral::, + GetRequestAsync: GetRequestAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattReadRequestedEventArgs_Vtbl { @@ -4885,6 +14417,53 @@ windows_core::imp::define_interface!(IGattReadResult, IGattReadResult_Vtbl, 0x63 impl windows_core::RuntimeType for IGattReadResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IGattReadResult { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattReadResult"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IGattReadResult_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; + fn Value(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IGattReadResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut GattCommunicationStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattReadResult_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattReadResult_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Status: Status::, + Value: Value::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattReadResult_Vtbl { @@ -4899,6 +14478,33 @@ windows_core::imp::define_interface!(IGattReadResult2, IGattReadResult2_Vtbl, 0x impl windows_core::RuntimeType for IGattReadResult2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattReadResult2 { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattReadResult2"; +} +pub trait IGattReadResult2_Impl: windows_core::IUnknownImpl { + fn ProtocolError(&self) -> windows_core::Result>; +} +impl IGattReadResult2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ProtocolError(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattReadResult2_Impl::ProtocolError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), ProtocolError: ProtocolError:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattReadResult2_Vtbl { @@ -4909,6 +14515,49 @@ windows_core::imp::define_interface!(IGattRequestStateChangedEventArgs, IGattReq impl windows_core::RuntimeType for IGattRequestStateChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattRequestStateChangedEventArgs { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattRequestStateChangedEventArgs"; +} +pub trait IGattRequestStateChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn State(&self) -> windows_core::Result; + fn Error(&self) -> windows_core::Result; +} +impl IGattRequestStateChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn State(this: *mut core::ffi::c_void, result__: *mut GattRequestState) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattRequestStateChangedEventArgs_Impl::State(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Error(this: *mut core::ffi::c_void, result__: *mut super::BluetoothError) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattRequestStateChangedEventArgs_Impl::Error(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + State: State::, + Error: Error::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattRequestStateChangedEventArgs_Vtbl { @@ -4920,6 +14569,65 @@ windows_core::imp::define_interface!(IGattServiceProviderAdvertisingParameters, impl windows_core::RuntimeType for IGattServiceProviderAdvertisingParameters { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattServiceProviderAdvertisingParameters { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattServiceProviderAdvertisingParameters"; +} +pub trait IGattServiceProviderAdvertisingParameters_Impl: windows_core::IUnknownImpl { + fn SetIsConnectable(&self, value: bool) -> windows_core::Result<()>; + fn IsConnectable(&self) -> windows_core::Result; + fn SetIsDiscoverable(&self, value: bool) -> windows_core::Result<()>; + fn IsDiscoverable(&self) -> windows_core::Result; +} +impl IGattServiceProviderAdvertisingParameters_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetIsConnectable(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattServiceProviderAdvertisingParameters_Impl::SetIsConnectable(this, value).into() + } + } + unsafe extern "system" fn IsConnectable(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattServiceProviderAdvertisingParameters_Impl::IsConnectable(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetIsDiscoverable(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattServiceProviderAdvertisingParameters_Impl::SetIsDiscoverable(this, value).into() + } + } + unsafe extern "system" fn IsDiscoverable(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattServiceProviderAdvertisingParameters_Impl::IsDiscoverable(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetIsConnectable: SetIsConnectable::, + IsConnectable: IsConnectable::, + SetIsDiscoverable: SetIsDiscoverable::, + IsDiscoverable: IsDiscoverable::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattServiceProviderAdvertisingParameters_Vtbl { @@ -4933,6 +14641,47 @@ windows_core::imp::define_interface!(IGattServiceProviderAdvertisingParameters2, impl windows_core::RuntimeType for IGattServiceProviderAdvertisingParameters2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IGattServiceProviderAdvertisingParameters2 { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattServiceProviderAdvertisingParameters2"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IGattServiceProviderAdvertisingParameters2_Impl: windows_core::IUnknownImpl { + fn SetServiceData(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result<()>; + fn ServiceData(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IGattServiceProviderAdvertisingParameters2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetServiceData(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattServiceProviderAdvertisingParameters2_Impl::SetServiceData(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn ServiceData(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattServiceProviderAdvertisingParameters2_Impl::ServiceData(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetServiceData: SetServiceData::, + ServiceData: ServiceData::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattServiceProviderAdvertisingParameters2_Vtbl { @@ -4946,23 +14695,148 @@ pub struct IGattServiceProviderAdvertisingParameters2_Vtbl { #[cfg(not(feature = "Storage_Streams"))] ServiceData: usize, } -windows_core::imp::define_interface!(IGattServiceProviderAdvertisingParameters3, IGattServiceProviderAdvertisingParameters3_Vtbl, 0xa23546b2_b216_5929_9055_f1313dd53e2a); -impl windows_core::RuntimeType for IGattServiceProviderAdvertisingParameters3 { - const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); -} -#[repr(C)] -#[doc(hidden)] -pub struct IGattServiceProviderAdvertisingParameters3_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub UseLowEnergyUncoded1MPhyAsSecondaryPhy: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, - pub SetUseLowEnergyUncoded1MPhyAsSecondaryPhy: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, - pub UseLowEnergyUncoded2MPhyAsSecondaryPhy: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, - pub SetUseLowEnergyUncoded2MPhyAsSecondaryPhy: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, -} windows_core::imp::define_interface!(IGattSession, IGattSession_Vtbl, 0xd23b5143_e04e_4c24_999c_9c256f9856b1); impl windows_core::RuntimeType for IGattSession { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattSession { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattSession"; +} +pub trait IGattSession_Impl: windows_core::IUnknownImpl { + fn DeviceId(&self) -> windows_core::Result; + fn CanMaintainConnection(&self) -> windows_core::Result; + fn SetMaintainConnection(&self, value: bool) -> windows_core::Result<()>; + fn MaintainConnection(&self) -> windows_core::Result; + fn MaxPduSize(&self) -> windows_core::Result; + fn SessionStatus(&self) -> windows_core::Result; + fn MaxPduSizeChanged(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveMaxPduSizeChanged(&self, token: i64) -> windows_core::Result<()>; + fn SessionStatusChanged(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveSessionStatusChanged(&self, token: i64) -> windows_core::Result<()>; +} +impl IGattSession_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattSession_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CanMaintainConnection(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattSession_Impl::CanMaintainConnection(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMaintainConnection(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattSession_Impl::SetMaintainConnection(this, value).into() + } + } + unsafe extern "system" fn MaintainConnection(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattSession_Impl::MaintainConnection(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxPduSize(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattSession_Impl::MaxPduSize(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SessionStatus(this: *mut core::ffi::c_void, result__: *mut GattSessionStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattSession_Impl::SessionStatus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxPduSizeChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattSession_Impl::MaxPduSizeChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveMaxPduSizeChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattSession_Impl::RemoveMaxPduSizeChanged(this, token).into() + } + } + unsafe extern "system" fn SessionStatusChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattSession_Impl::SessionStatusChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveSessionStatusChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattSession_Impl::RemoveSessionStatusChanged(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DeviceId: DeviceId::, + CanMaintainConnection: CanMaintainConnection::, + SetMaintainConnection: SetMaintainConnection::, + MaintainConnection: MaintainConnection::, + MaxPduSize: MaxPduSize::, + SessionStatus: SessionStatus::, + MaxPduSizeChanged: MaxPduSizeChanged::, + RemoveMaxPduSizeChanged: RemoveMaxPduSizeChanged::, + SessionStatusChanged: SessionStatusChanged::, + RemoveSessionStatusChanged: RemoveSessionStatusChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattSession_Vtbl { @@ -4982,6 +14856,36 @@ windows_core::imp::define_interface!(IGattSessionStatics, IGattSessionStatics_Vt impl windows_core::RuntimeType for IGattSessionStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattSessionStatics { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattSessionStatics"; +} +pub trait IGattSessionStatics_Impl: windows_core::IUnknownImpl { + fn FromDeviceIdAsync(&self, deviceId: windows_core::Ref<'_, super::BluetoothDeviceId>) -> windows_core::Result>; +} +impl IGattSessionStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FromDeviceIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattSessionStatics_Impl::FromDeviceIdAsync(this, core::mem::transmute_copy(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FromDeviceIdAsync: FromDeviceIdAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattSessionStatics_Vtbl { @@ -4992,6 +14896,49 @@ windows_core::imp::define_interface!(IGattSessionStatusChangedEventArgs, IGattSe impl windows_core::RuntimeType for IGattSessionStatusChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattSessionStatusChangedEventArgs { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattSessionStatusChangedEventArgs"; +} +pub trait IGattSessionStatusChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn Error(&self) -> windows_core::Result; + fn Status(&self) -> windows_core::Result; +} +impl IGattSessionStatusChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Error(this: *mut core::ffi::c_void, result__: *mut super::BluetoothError) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattSessionStatusChangedEventArgs_Impl::Error(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut GattSessionStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattSessionStatusChangedEventArgs_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Error: Error::, + Status: Status::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattSessionStatusChangedEventArgs_Vtbl { @@ -5003,6 +14950,72 @@ windows_core::imp::define_interface!(IGattSubscribedClient, IGattSubscribedClien impl windows_core::RuntimeType for IGattSubscribedClient { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattSubscribedClient { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattSubscribedClient"; +} +pub trait IGattSubscribedClient_Impl: windows_core::IUnknownImpl { + fn Session(&self) -> windows_core::Result; + fn MaxNotificationSize(&self) -> windows_core::Result; + fn MaxNotificationSizeChanged(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveMaxNotificationSizeChanged(&self, token: i64) -> windows_core::Result<()>; +} +impl IGattSubscribedClient_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Session(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattSubscribedClient_Impl::Session(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxNotificationSize(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattSubscribedClient_Impl::MaxNotificationSize(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxNotificationSizeChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattSubscribedClient_Impl::MaxNotificationSizeChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveMaxNotificationSizeChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattSubscribedClient_Impl::RemoveMaxNotificationSizeChanged(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Session: Session::, + MaxNotificationSize: MaxNotificationSize::, + MaxNotificationSizeChanged: MaxNotificationSizeChanged::, + RemoveMaxNotificationSizeChanged: RemoveMaxNotificationSizeChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattSubscribedClient_Vtbl { @@ -5016,6 +15029,53 @@ windows_core::imp::define_interface!(IGattValueChangedEventArgs, IGattValueChang impl windows_core::RuntimeType for IGattValueChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IGattValueChangedEventArgs { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattValueChangedEventArgs"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IGattValueChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn CharacteristicValue(&self) -> windows_core::Result; + fn Timestamp(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IGattValueChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CharacteristicValue(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattValueChangedEventArgs_Impl::CharacteristicValue(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Timestamp(this: *mut core::ffi::c_void, result__: *mut super::super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattValueChangedEventArgs_Impl::Timestamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CharacteristicValue: CharacteristicValue::, + Timestamp: Timestamp::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattValueChangedEventArgs_Vtbl { @@ -5030,6 +15090,119 @@ windows_core::imp::define_interface!(IGattWriteRequest, IGattWriteRequest_Vtbl, impl windows_core::RuntimeType for IGattWriteRequest { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IGattWriteRequest { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattWriteRequest"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IGattWriteRequest_Impl: windows_core::IUnknownImpl { + fn Value(&self) -> windows_core::Result; + fn Offset(&self) -> windows_core::Result; + fn Option(&self) -> windows_core::Result; + fn State(&self) -> windows_core::Result; + fn StateChanged(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveStateChanged(&self, token: i64) -> windows_core::Result<()>; + fn Respond(&self) -> windows_core::Result<()>; + fn RespondWithProtocolError(&self, protocolError: u8) -> windows_core::Result<()>; +} +#[cfg(feature = "Storage_Streams")] +impl IGattWriteRequest_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattWriteRequest_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Offset(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattWriteRequest_Impl::Offset(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Option(this: *mut core::ffi::c_void, result__: *mut GattWriteOption) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattWriteRequest_Impl::Option(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn State(this: *mut core::ffi::c_void, result__: *mut GattRequestState) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattWriteRequest_Impl::State(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StateChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattWriteRequest_Impl::StateChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveStateChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattWriteRequest_Impl::RemoveStateChanged(this, token).into() + } + } + unsafe extern "system" fn Respond(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattWriteRequest_Impl::Respond(this).into() + } + } + unsafe extern "system" fn RespondWithProtocolError(this: *mut core::ffi::c_void, protocolerror: u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IGattWriteRequest_Impl::RespondWithProtocolError(this, protocolerror).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Value: Value::, + Offset: Offset::, + Option: Option::, + State: State::, + StateChanged: StateChanged::, + RemoveStateChanged: RemoveStateChanged::, + Respond: Respond::, + RespondWithProtocolError: RespondWithProtocolError::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattWriteRequest_Vtbl { @@ -5050,6 +15223,66 @@ windows_core::imp::define_interface!(IGattWriteRequestedEventArgs, IGattWriteReq impl windows_core::RuntimeType for IGattWriteRequestedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattWriteRequestedEventArgs { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattWriteRequestedEventArgs"; +} +pub trait IGattWriteRequestedEventArgs_Impl: windows_core::IUnknownImpl { + fn Session(&self) -> windows_core::Result; + fn GetDeferral(&self) -> windows_core::Result; + fn GetRequestAsync(&self) -> windows_core::Result>; +} +impl IGattWriteRequestedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Session(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattWriteRequestedEventArgs_Impl::Session(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeferral(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattWriteRequestedEventArgs_Impl::GetDeferral(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetRequestAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattWriteRequestedEventArgs_Impl::GetRequestAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Session: Session::, + GetDeferral: GetDeferral::, + GetRequestAsync: GetRequestAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattWriteRequestedEventArgs_Vtbl { @@ -5062,6 +15295,50 @@ windows_core::imp::define_interface!(IGattWriteResult, IGattWriteResult_Vtbl, 0x impl windows_core::RuntimeType for IGattWriteResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IGattWriteResult { + const NAME: &'static str = "Windows.Devices.Bluetooth.GenericAttributeProfile.IGattWriteResult"; +} +pub trait IGattWriteResult_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; + fn ProtocolError(&self) -> windows_core::Result>; +} +impl IGattWriteResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut GattCommunicationStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattWriteResult_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ProtocolError(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IGattWriteResult_Impl::ProtocolError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Status: Status::, + ProtocolError: ProtocolError::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IGattWriteResult_Vtbl { @@ -5070,11 +15347,70 @@ pub struct IGattWriteResult_Vtbl { pub ProtocolError: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, } } +#[cfg(feature = "Devices_Bluetooth_Rfcomm")] pub mod Rfcomm{ windows_core::imp::define_interface!(IRfcommServiceId, IRfcommServiceId_Vtbl, 0x22629204_7e02_4017_8136_da1b6a1b9bbf); impl windows_core::RuntimeType for IRfcommServiceId { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IRfcommServiceId { + const NAME: &'static str = "Windows.Devices.Bluetooth.Rfcomm.IRfcommServiceId"; +} +pub trait IRfcommServiceId_Impl: windows_core::IUnknownImpl { + fn Uuid(&self) -> windows_core::Result; + fn AsShortId(&self) -> windows_core::Result; + fn AsString(&self) -> windows_core::Result; +} +impl IRfcommServiceId_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Uuid(this: *mut core::ffi::c_void, result__: *mut windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommServiceId_Impl::Uuid(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AsShortId(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommServiceId_Impl::AsShortId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AsString(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommServiceId_Impl::AsString(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Uuid: Uuid::, + AsShortId: AsShortId::, + AsString: AsString::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IRfcommServiceId_Vtbl { @@ -5087,6 +15423,141 @@ windows_core::imp::define_interface!(IRfcommServiceIdStatics, IRfcommServiceIdSt impl windows_core::RuntimeType for IRfcommServiceIdStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IRfcommServiceIdStatics { + const NAME: &'static str = "Windows.Devices.Bluetooth.Rfcomm.IRfcommServiceIdStatics"; +} +pub trait IRfcommServiceIdStatics_Impl: windows_core::IUnknownImpl { + fn FromUuid(&self, uuid: &windows_core::GUID) -> windows_core::Result; + fn FromShortId(&self, shortId: u32) -> windows_core::Result; + fn SerialPort(&self) -> windows_core::Result; + fn ObexObjectPush(&self) -> windows_core::Result; + fn ObexFileTransfer(&self) -> windows_core::Result; + fn PhoneBookAccessPce(&self) -> windows_core::Result; + fn PhoneBookAccessPse(&self) -> windows_core::Result; + fn GenericFileTransfer(&self) -> windows_core::Result; +} +impl IRfcommServiceIdStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FromUuid(this: *mut core::ffi::c_void, uuid: windows_core::GUID, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommServiceIdStatics_Impl::FromUuid(this, core::mem::transmute(&uuid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FromShortId(this: *mut core::ffi::c_void, shortid: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommServiceIdStatics_Impl::FromShortId(this, shortid) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SerialPort(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommServiceIdStatics_Impl::SerialPort(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ObexObjectPush(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommServiceIdStatics_Impl::ObexObjectPush(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ObexFileTransfer(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommServiceIdStatics_Impl::ObexFileTransfer(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PhoneBookAccessPce(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommServiceIdStatics_Impl::PhoneBookAccessPce(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PhoneBookAccessPse(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommServiceIdStatics_Impl::PhoneBookAccessPse(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GenericFileTransfer(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRfcommServiceIdStatics_Impl::GenericFileTransfer(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FromUuid: FromUuid::, + FromShortId: FromShortId::, + SerialPort: SerialPort::, + ObexObjectPush: ObexObjectPush::, + ObexFileTransfer: ObexFileTransfer::, + PhoneBookAccessPce: PhoneBookAccessPce::, + PhoneBookAccessPse: PhoneBookAccessPse::, + GenericFileTransfer: GenericFileTransfer::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IRfcommServiceIdStatics_Vtbl { @@ -5105,6 +15576,75 @@ pub struct IRfcommServiceIdStatics_Vtbl { pub struct RfcommServiceId(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(RfcommServiceId, windows_core::IUnknown, windows_core::IInspectable); impl RfcommServiceId { + pub fn Uuid(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Uuid)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AsShortId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AsShortId)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AsString(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AsString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn FromUuid(uuid: windows_core::GUID) -> windows_core::Result { + Self::IRfcommServiceIdStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FromUuid)(windows_core::Interface::as_raw(this), uuid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn FromShortId(shortid: u32) -> windows_core::Result { + Self::IRfcommServiceIdStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FromShortId)(windows_core::Interface::as_raw(this), shortid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn SerialPort() -> windows_core::Result { + Self::IRfcommServiceIdStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SerialPort)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn ObexObjectPush() -> windows_core::Result { + Self::IRfcommServiceIdStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ObexObjectPush)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn ObexFileTransfer() -> windows_core::Result { + Self::IRfcommServiceIdStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ObexFileTransfer)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn PhoneBookAccessPce() -> windows_core::Result { + Self::IRfcommServiceIdStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PhoneBookAccessPce)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn PhoneBookAccessPse() -> windows_core::Result { + Self::IRfcommServiceIdStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PhoneBookAccessPse)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GenericFileTransfer() -> windows_core::Result { + Self::IRfcommServiceIdStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GenericFileTransfer)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IRfcommServiceIdStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -5124,12 +15664,20 @@ unsafe impl Send for RfcommServiceId {} unsafe impl Sync for RfcommServiceId {} } } +#[cfg(feature = "Devices_Enumeration")] pub mod Enumeration{ #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] pub struct DeviceAccessChangedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(DeviceAccessChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); impl DeviceAccessChangedEventArgs { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Id(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; unsafe { @@ -5137,7 +15685,14 @@ impl DeviceAccessChangedEventArgs { (windows_core::Interface::vtable(this).Id)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn UserPromptRequired(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UserPromptRequired)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } +} impl windows_core::RuntimeType for DeviceAccessChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -5155,6 +15710,52 @@ unsafe impl Sync for DeviceAccessChangedEventArgs {} pub struct DeviceAccessInformation(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(DeviceAccessInformation, windows_core::IUnknown, windows_core::IInspectable); impl DeviceAccessInformation { + pub fn AccessChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AccessChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveAccessChanged(&self, cookie: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveAccessChanged)(windows_core::Interface::as_raw(this), cookie).ok() } + } + pub fn CurrentStatus(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CurrentStatus)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn UserPromptRequired(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UserPromptRequired)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CreateFromId(deviceid: &windows_core::HSTRING) -> windows_core::Result { + Self::IDeviceAccessInformationStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromId)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromDeviceClassId(deviceclassid: windows_core::GUID) -> windows_core::Result { + Self::IDeviceAccessInformationStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromDeviceClassId)(windows_core::Interface::as_raw(this), deviceclassid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromDeviceClass(deviceclass: DeviceClass) -> windows_core::Result { + Self::IDeviceAccessInformationStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromDeviceClass)(windows_core::Interface::as_raw(this), deviceclass, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IDeviceAccessInformationStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -5224,18 +15825,203 @@ impl DeviceInformation { (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn IsEnabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsDefault(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsDefault)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn EnclosureLocation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).EnclosureLocation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Properties(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Update(&self, updateinfo: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Update)(windows_core::Interface::as_raw(this), updateinfo.param().abi()).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetThumbnailAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetGlyphThumbnailAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetGlyphThumbnailAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Kind(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Kind)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Pairing(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Pairing)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFromIdAsync(deviceid: &windows_core::HSTRING) -> windows_core::Result> { + Self::IDeviceInformationStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromIdAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromIdAsyncAdditionalProperties(deviceid: &windows_core::HSTRING, additionalproperties: P1) -> windows_core::Result> + where + P1: windows_core::Param>, + { + Self::IDeviceInformationStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromIdAsyncAdditionalProperties)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), additionalproperties.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn FindAllAsync() -> windows_core::Result> { + Self::IDeviceInformationStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindAllAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn FindAllAsyncDeviceClass(deviceclass: DeviceClass) -> windows_core::Result> { + Self::IDeviceInformationStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindAllAsyncDeviceClass)(windows_core::Interface::as_raw(this), deviceclass, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn FindAllAsyncAqsFilter(aqsfilter: &windows_core::HSTRING) -> windows_core::Result> { Self::IDeviceInformationStatics(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).FindAllAsyncAqsFilter)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(aqsfilter), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn FindAllAsyncAqsFilterAndAdditionalProperties(aqsfilter: &windows_core::HSTRING, additionalproperties: P1) -> windows_core::Result> + where + P1: windows_core::Param>, + { + Self::IDeviceInformationStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindAllAsyncAqsFilterAndAdditionalProperties)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(aqsfilter), additionalproperties.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateWatcher() -> windows_core::Result { + Self::IDeviceInformationStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWatcher)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateWatcherDeviceClass(deviceclass: DeviceClass) -> windows_core::Result { + Self::IDeviceInformationStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWatcherDeviceClass)(windows_core::Interface::as_raw(this), deviceclass, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn CreateWatcherAqsFilter(aqsfilter: &windows_core::HSTRING) -> windows_core::Result { Self::IDeviceInformationStatics(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).CreateWatcherAqsFilter)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(aqsfilter), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn CreateWatcherAqsFilterAndAdditionalProperties(aqsfilter: &windows_core::HSTRING, additionalproperties: P1) -> windows_core::Result + where + P1: windows_core::Param>, + { + Self::IDeviceInformationStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWatcherAqsFilterAndAdditionalProperties)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(aqsfilter), additionalproperties.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetAqsFilterFromDeviceClass(deviceclass: DeviceClass) -> windows_core::Result { + Self::IDeviceInformationStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAqsFilterFromDeviceClass)(windows_core::Interface::as_raw(this), deviceclass, &mut result__).map(|| core::mem::transmute(result__)) + }) + } + pub fn CreateFromIdAsyncWithKindAndAdditionalProperties(deviceid: &windows_core::HSTRING, additionalproperties: P1, kind: DeviceInformationKind) -> windows_core::Result> + where + P1: windows_core::Param>, + { + Self::IDeviceInformationStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromIdAsyncWithKindAndAdditionalProperties)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), additionalproperties.param().abi(), kind, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn FindAllAsyncWithKindAqsFilterAndAdditionalProperties(aqsfilter: &windows_core::HSTRING, additionalproperties: P1, kind: DeviceInformationKind) -> windows_core::Result> + where + P1: windows_core::Param>, + { + Self::IDeviceInformationStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindAllAsyncWithKindAqsFilterAndAdditionalProperties)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(aqsfilter), additionalproperties.param().abi(), kind, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateWatcherWithKindAqsFilterAndAdditionalProperties(aqsfilter: &windows_core::HSTRING, additionalproperties: P1, kind: DeviceInformationKind) -> windows_core::Result + where + P1: windows_core::Param>, + { + Self::IDeviceInformationStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWatcherWithKindAqsFilterAndAdditionalProperties)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(aqsfilter), additionalproperties.param().abi(), kind, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromIdAsyncWithAdditionalPropertiesKindAndSettings(deviceid: &windows_core::HSTRING, additionalproperties: P1, kind: DeviceInformationKind, settings: P3) -> windows_core::Result> + where + P1: windows_core::Param>, + P3: windows_core::Param, + { + Self::IDeviceInformationStatics3(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromIdAsyncWithAdditionalPropertiesKindAndSettings)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), additionalproperties.param().abi(), kind, settings.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn FindAllAsyncWithAqsFilterAdditionalPropertiesKindAndSettings(aqsfilter: &windows_core::HSTRING, additionalproperties: P1, kind: DeviceInformationKind, settings: P3) -> windows_core::Result> + where + P1: windows_core::Param>, + P3: windows_core::Param, + { + Self::IDeviceInformationStatics3(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindAllAsyncWithAqsFilterAdditionalPropertiesKindAndSettings)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(aqsfilter), additionalproperties.param().abi(), kind, settings.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateWatcherWithAqsFilterAdditionalPropertiesKindAndSettings(aqsfilter: &windows_core::HSTRING, additionalproperties: P1, kind: DeviceInformationKind, settings: P3) -> windows_core::Result + where + P1: windows_core::Param>, + P3: windows_core::Param, + { + Self::IDeviceInformationStatics3(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWatcherWithAqsFilterAdditionalPropertiesKindAndSettings)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(aqsfilter), additionalproperties.param().abi(), kind, settings.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IDeviceInformationStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -5274,7 +16060,38 @@ impl DeviceInformationCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn Size(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for DeviceInformationCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::>(); } @@ -5305,6 +16122,67 @@ impl IntoIterator for &DeviceInformationCollection { #[derive(Clone, Debug, Eq, PartialEq)] pub struct DeviceInformationCustomPairing(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(DeviceInformationCustomPairing, windows_core::IUnknown, windows_core::IInspectable); +impl DeviceInformationCustomPairing { + pub fn PairAsync(&self, pairingkindssupported: DevicePairingKinds) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PairAsync)(windows_core::Interface::as_raw(this), pairingkindssupported, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PairWithProtectionLevelAsync(&self, pairingkindssupported: DevicePairingKinds, minprotectionlevel: DevicePairingProtectionLevel) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PairWithProtectionLevelAsync)(windows_core::Interface::as_raw(this), pairingkindssupported, minprotectionlevel, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PairWithProtectionLevelAndSettingsAsync(&self, pairingkindssupported: DevicePairingKinds, minprotectionlevel: DevicePairingProtectionLevel, devicepairingsettings: P2) -> windows_core::Result> + where + P2: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PairWithProtectionLevelAndSettingsAsync)(windows_core::Interface::as_raw(this), pairingkindssupported, minprotectionlevel, devicepairingsettings.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PairingRequested(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PairingRequested)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemovePairingRequested(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemovePairingRequested)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn AddPairingSetMember(&self, device: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).AddPairingSetMember)(windows_core::Interface::as_raw(this), device.param().abi()).ok() } + } + pub fn PairingSetMembersRequested(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PairingSetMembersRequested)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemovePairingSetMembersRequested(&self, token: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemovePairingSetMembersRequested)(windows_core::Interface::as_raw(this), token).ok() } + } +} impl windows_core::RuntimeType for DeviceInformationCustomPairing { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -5343,6 +16221,77 @@ impl windows_core::RuntimeType for DeviceInformationKind { pub struct DeviceInformationPairing(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(DeviceInformationPairing, windows_core::IUnknown, windows_core::IInspectable); impl DeviceInformationPairing { + pub fn IsPaired(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsPaired)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CanPair(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanPair)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PairAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PairAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PairWithProtectionLevelAsync(&self, minprotectionlevel: DevicePairingProtectionLevel) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PairWithProtectionLevelAsync)(windows_core::Interface::as_raw(this), minprotectionlevel, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ProtectionLevel(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProtectionLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Custom(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Custom)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PairWithProtectionLevelAndSettingsAsync(&self, minprotectionlevel: DevicePairingProtectionLevel, devicepairingsettings: P1) -> windows_core::Result> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PairWithProtectionLevelAndSettingsAsync)(windows_core::Interface::as_raw(this), minprotectionlevel, devicepairingsettings.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn UnpairAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UnpairAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryRegisterForAllInboundPairingRequests(pairingkindssupported: DevicePairingKinds) -> windows_core::Result { + Self::IDeviceInformationPairingStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryRegisterForAllInboundPairingRequests)(windows_core::Interface::as_raw(this), pairingkindssupported, &mut result__).map(|| result__) + }) + } + pub fn TryRegisterForAllInboundPairingRequestsWithProtectionLevel(pairingkindssupported: DevicePairingKinds, minprotectionlevel: DevicePairingProtectionLevel) -> windows_core::Result { + Self::IDeviceInformationPairingStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryRegisterForAllInboundPairingRequestsWithProtectionLevel)(windows_core::Interface::as_raw(this), pairingkindssupported, minprotectionlevel, &mut result__).map(|| result__) + }) + } fn IDeviceInformationPairingStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -5376,7 +16325,21 @@ impl DeviceInformationUpdate { (windows_core::Interface::vtable(this).Id)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn Properties(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn Kind(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Kind)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for DeviceInformationUpdate { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -5476,6 +16439,56 @@ impl windows_core::RuntimeType for DevicePairingProtectionLevel { #[derive(Clone, Debug, Eq, PartialEq)] pub struct DevicePairingRequestedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(DevicePairingRequestedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl DevicePairingRequestedEventArgs { + pub fn DeviceInformation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceInformation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PairingKind(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PairingKind)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Pin(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Pin)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Accept(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Accept)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn AcceptWithPin(&self, pin: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).AcceptWithPin)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(pin)).ok() } + } + pub fn GetDeferral(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeferral)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Security_Credentials")] + pub fn AcceptWithPasswordCredential(&self, passwordcredential: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).AcceptWithPasswordCredential)(windows_core::Interface::as_raw(this), passwordcredential.param().abi()).ok() } + } + pub fn AcceptWithAddress(&self, address: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).AcceptWithAddress)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(address)).ok() } + } +} impl windows_core::RuntimeType for DevicePairingRequestedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -5492,6 +16505,22 @@ unsafe impl Sync for DevicePairingRequestedEventArgs {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct DevicePairingResult(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(DevicePairingResult, windows_core::IUnknown, windows_core::IInspectable); +impl DevicePairingResult { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ProtectionLevelUsed(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProtectionLevelUsed)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for DevicePairingResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -5539,6 +16568,29 @@ impl windows_core::RuntimeType for DevicePairingResultStatus { #[derive(Clone, Debug, Eq, PartialEq)] pub struct DevicePairingSetMembersRequestedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(DevicePairingSetMembersRequestedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl DevicePairingSetMembersRequestedEventArgs { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ParentDeviceInformation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ParentDeviceInformation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PairingSetMembers(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PairingSetMembers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for DevicePairingSetMembersRequestedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -5565,6 +16617,13 @@ impl DeviceThumbnail { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn ContentType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } pub fn ReadAsync(&self, buffer: P0, count: u32, options: super::super::Storage::Streams::InputStreamOptions) -> windows_core::Result> where P0: windows_core::Param, @@ -5575,6 +16634,16 @@ impl DeviceThumbnail { (windows_core::Interface::vtable(this).ReadAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), count, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn WriteAsync(&self, buffer: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn FlushAsync(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::(self)?; unsafe { @@ -5582,6 +16651,24 @@ impl DeviceThumbnail { (windows_core::Interface::vtable(this).FlushAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetSize(&self, value: u64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetSize)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn GetInputStreamAt(&self, position: u64) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn GetOutputStreamAt(&self, position: u64) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; unsafe { @@ -5589,11 +16676,39 @@ impl DeviceThumbnail { (windows_core::Interface::vtable(this).GetOutputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Position(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Position)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Seek(&self, position: u64) -> windows_core::Result<()> { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Seek)(windows_core::Interface::as_raw(this), position).ok() } } + pub fn CloneStream(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CloneStream)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn CanRead(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanRead)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CanWrite(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanWrite)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} #[cfg(feature = "Storage_Streams")] impl windows_core::RuntimeType for DeviceThumbnail { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); @@ -5615,6 +16730,15 @@ unsafe impl Sync for DeviceThumbnail {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct DeviceUnpairingResult(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(DeviceUnpairingResult, windows_core::IUnknown, windows_core::IInspectable); +impl DeviceUnpairingResult { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for DeviceUnpairingResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -5658,6 +16782,10 @@ impl DeviceWatcher { (windows_core::Interface::vtable(this).Added)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) } } + pub fn RemoveAdded(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveAdded)(windows_core::Interface::as_raw(this), token).ok() } + } pub fn Updated(&self, handler: P0) -> windows_core::Result where P0: windows_core::Param>, @@ -5668,6 +16796,10 @@ impl DeviceWatcher { (windows_core::Interface::vtable(this).Updated)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) } } + pub fn RemoveUpdated(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveUpdated)(windows_core::Interface::as_raw(this), token).ok() } + } pub fn Removed(&self, handler: P0) -> windows_core::Result where P0: windows_core::Param>, @@ -5678,6 +16810,10 @@ impl DeviceWatcher { (windows_core::Interface::vtable(this).Removed)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) } } + pub fn RemoveRemoved(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveRemoved)(windows_core::Interface::as_raw(this), token).ok() } + } pub fn EnumerationCompleted(&self, handler: P0) -> windows_core::Result where P0: windows_core::Param>, @@ -5688,6 +16824,31 @@ impl DeviceWatcher { (windows_core::Interface::vtable(this).EnumerationCompleted)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) } } + pub fn RemoveEnumerationCompleted(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveEnumerationCompleted)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn Stopped(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Stopped)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveStopped(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveStopped)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Start(&self) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).Start)(windows_core::Interface::as_raw(this)).ok() } @@ -5696,7 +16857,18 @@ impl DeviceWatcher { let this = self; unsafe { (windows_core::Interface::vtable(this).Stop)(windows_core::Interface::as_raw(this)).ok() } } + #[cfg(feature = "ApplicationModel_Background")] + pub fn GetBackgroundTrigger(&self, requestedeventkinds: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetBackgroundTrigger)(windows_core::Interface::as_raw(this), requestedeventkinds.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } +} impl windows_core::RuntimeType for DeviceWatcher { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -5744,6 +16916,36 @@ impl windows_core::RuntimeType for DeviceWatcherStatus { #[derive(Clone, Debug, Eq, PartialEq)] pub struct EnclosureLocation(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(EnclosureLocation, windows_core::IUnknown, windows_core::IInspectable); +impl EnclosureLocation { + pub fn InDock(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InDock)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn InLid(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InLid)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Panel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Panel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn RotationAngleInDegreesClockwise(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RotationAngleInDegreesClockwise)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for EnclosureLocation { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -5760,6 +16962,32 @@ windows_core::imp::define_interface!(IDeviceAccessChangedEventArgs, IDeviceAcces impl windows_core::RuntimeType for IDeviceAccessChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceAccessChangedEventArgs { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceAccessChangedEventArgs"; +} +pub trait IDeviceAccessChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; +} +impl IDeviceAccessChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut DeviceAccessStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceAccessChangedEventArgs_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Status: Status:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceAccessChangedEventArgs_Vtbl { @@ -5770,6 +16998,33 @@ windows_core::imp::define_interface!(IDeviceAccessChangedEventArgs2, IDeviceAcce impl windows_core::RuntimeType for IDeviceAccessChangedEventArgs2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceAccessChangedEventArgs2 { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceAccessChangedEventArgs2"; +} +pub trait IDeviceAccessChangedEventArgs2_Impl: IDeviceAccessChangedEventArgs_Impl { + fn Id(&self) -> windows_core::Result; +} +impl IDeviceAccessChangedEventArgs2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Id(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceAccessChangedEventArgs2_Impl::Id(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Id: Id:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceAccessChangedEventArgs2_Vtbl { @@ -5780,6 +17035,35 @@ windows_core::imp::define_interface!(IDeviceAccessChangedEventArgs3, IDeviceAcce impl windows_core::RuntimeType for IDeviceAccessChangedEventArgs3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceAccessChangedEventArgs3 { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceAccessChangedEventArgs3"; +} +pub trait IDeviceAccessChangedEventArgs3_Impl: windows_core::IUnknownImpl { + fn UserPromptRequired(&self) -> windows_core::Result; +} +impl IDeviceAccessChangedEventArgs3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn UserPromptRequired(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceAccessChangedEventArgs3_Impl::UserPromptRequired(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + UserPromptRequired: UserPromptRequired::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceAccessChangedEventArgs3_Vtbl { @@ -5790,6 +17074,57 @@ windows_core::imp::define_interface!(IDeviceAccessInformation, IDeviceAccessInfo impl windows_core::RuntimeType for IDeviceAccessInformation { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceAccessInformation { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceAccessInformation"; +} +pub trait IDeviceAccessInformation_Impl: windows_core::IUnknownImpl { + fn AccessChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveAccessChanged(&self, cookie: i64) -> windows_core::Result<()>; + fn CurrentStatus(&self) -> windows_core::Result; +} +impl IDeviceAccessInformation_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AccessChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceAccessInformation_Impl::AccessChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveAccessChanged(this: *mut core::ffi::c_void, cookie: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDeviceAccessInformation_Impl::RemoveAccessChanged(this, cookie).into() + } + } + unsafe extern "system" fn CurrentStatus(this: *mut core::ffi::c_void, result__: *mut DeviceAccessStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceAccessInformation_Impl::CurrentStatus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AccessChanged: AccessChanged::, + RemoveAccessChanged: RemoveAccessChanged::, + CurrentStatus: CurrentStatus::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceAccessInformation_Vtbl { @@ -5802,6 +17137,35 @@ windows_core::imp::define_interface!(IDeviceAccessInformation2, IDeviceAccessInf impl windows_core::RuntimeType for IDeviceAccessInformation2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceAccessInformation2 { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceAccessInformation2"; +} +pub trait IDeviceAccessInformation2_Impl: windows_core::IUnknownImpl { + fn UserPromptRequired(&self) -> windows_core::Result; +} +impl IDeviceAccessInformation2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn UserPromptRequired(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceAccessInformation2_Impl::UserPromptRequired(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + UserPromptRequired: UserPromptRequired::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceAccessInformation2_Vtbl { @@ -5812,6 +17176,66 @@ windows_core::imp::define_interface!(IDeviceAccessInformationStatics, IDeviceAcc impl windows_core::RuntimeType for IDeviceAccessInformationStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceAccessInformationStatics { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceAccessInformationStatics"; +} +pub trait IDeviceAccessInformationStatics_Impl: windows_core::IUnknownImpl { + fn CreateFromId(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromDeviceClassId(&self, deviceClassId: &windows_core::GUID) -> windows_core::Result; + fn CreateFromDeviceClass(&self, deviceClass: DeviceClass) -> windows_core::Result; +} +impl IDeviceAccessInformationStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromId(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceAccessInformationStatics_Impl::CreateFromId(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromDeviceClassId(this: *mut core::ffi::c_void, deviceclassid: windows_core::GUID, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceAccessInformationStatics_Impl::CreateFromDeviceClassId(this, core::mem::transmute(&deviceclassid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromDeviceClass(this: *mut core::ffi::c_void, deviceclass: DeviceClass, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceAccessInformationStatics_Impl::CreateFromDeviceClass(this, deviceclass) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromId: CreateFromId::, + CreateFromDeviceClassId: CreateFromDeviceClassId::, + CreateFromDeviceClass: CreateFromDeviceClass::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceAccessInformationStatics_Vtbl { @@ -5846,6 +17270,150 @@ windows_core::imp::define_interface!(IDeviceInformation, IDeviceInformation_Vtbl impl windows_core::RuntimeType for IDeviceInformation { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IDeviceInformation { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceInformation"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IDeviceInformation_Impl: windows_core::IUnknownImpl { + fn Id(&self) -> windows_core::Result; + fn Name(&self) -> windows_core::Result; + fn IsEnabled(&self) -> windows_core::Result; + fn IsDefault(&self) -> windows_core::Result; + fn EnclosureLocation(&self) -> windows_core::Result; + fn Properties(&self) -> windows_core::Result>; + fn Update(&self, updateInfo: windows_core::Ref<'_, DeviceInformationUpdate>) -> windows_core::Result<()>; + fn GetThumbnailAsync(&self) -> windows_core::Result>; + fn GetGlyphThumbnailAsync(&self) -> windows_core::Result>; +} +#[cfg(feature = "Storage_Streams")] +impl IDeviceInformation_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Id(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformation_Impl::Id(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Name(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformation_Impl::Name(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformation_Impl::IsEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsDefault(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformation_Impl::IsDefault(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn EnclosureLocation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformation_Impl::EnclosureLocation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformation_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Update(this: *mut core::ffi::c_void, updateinfo: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDeviceInformation_Impl::Update(this, core::mem::transmute_copy(&updateinfo)).into() + } + } + unsafe extern "system" fn GetThumbnailAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformation_Impl::GetThumbnailAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetGlyphThumbnailAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformation_Impl::GetGlyphThumbnailAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Id: Id::, + Name: Name::, + IsEnabled: IsEnabled::, + IsDefault: IsDefault::, + EnclosureLocation: EnclosureLocation::, + Properties: Properties::, + Update: Update::, + GetThumbnailAsync: GetThumbnailAsync::, + GetGlyphThumbnailAsync: GetGlyphThumbnailAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceInformation_Vtbl { @@ -5870,6 +17438,50 @@ windows_core::imp::define_interface!(IDeviceInformation2, IDeviceInformation2_Vt impl windows_core::RuntimeType for IDeviceInformation2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceInformation2 { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceInformation2"; +} +pub trait IDeviceInformation2_Impl: windows_core::IUnknownImpl { + fn Kind(&self) -> windows_core::Result; + fn Pairing(&self) -> windows_core::Result; +} +impl IDeviceInformation2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Kind(this: *mut core::ffi::c_void, result__: *mut DeviceInformationKind) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformation2_Impl::Kind(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Pairing(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformation2_Impl::Pairing(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Kind: Kind::, + Pairing: Pairing::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceInformation2_Vtbl { @@ -5881,6 +17493,88 @@ windows_core::imp::define_interface!(IDeviceInformationCustomPairing, IDeviceInf impl windows_core::RuntimeType for IDeviceInformationCustomPairing { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceInformationCustomPairing { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceInformationCustomPairing"; +} +pub trait IDeviceInformationCustomPairing_Impl: windows_core::IUnknownImpl { + fn PairAsync(&self, pairingKindsSupported: DevicePairingKinds) -> windows_core::Result>; + fn PairWithProtectionLevelAsync(&self, pairingKindsSupported: DevicePairingKinds, minProtectionLevel: DevicePairingProtectionLevel) -> windows_core::Result>; + fn PairWithProtectionLevelAndSettingsAsync(&self, pairingKindsSupported: DevicePairingKinds, minProtectionLevel: DevicePairingProtectionLevel, devicePairingSettings: windows_core::Ref<'_, IDevicePairingSettings>) -> windows_core::Result>; + fn PairingRequested(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemovePairingRequested(&self, token: i64) -> windows_core::Result<()>; +} +impl IDeviceInformationCustomPairing_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn PairAsync(this: *mut core::ffi::c_void, pairingkindssupported: DevicePairingKinds, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationCustomPairing_Impl::PairAsync(this, pairingkindssupported) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PairWithProtectionLevelAsync(this: *mut core::ffi::c_void, pairingkindssupported: DevicePairingKinds, minprotectionlevel: DevicePairingProtectionLevel, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationCustomPairing_Impl::PairWithProtectionLevelAsync(this, pairingkindssupported, minprotectionlevel) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PairWithProtectionLevelAndSettingsAsync(this: *mut core::ffi::c_void, pairingkindssupported: DevicePairingKinds, minprotectionlevel: DevicePairingProtectionLevel, devicepairingsettings: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationCustomPairing_Impl::PairWithProtectionLevelAndSettingsAsync(this, pairingkindssupported, minprotectionlevel, core::mem::transmute_copy(&devicepairingsettings)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PairingRequested(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationCustomPairing_Impl::PairingRequested(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemovePairingRequested(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDeviceInformationCustomPairing_Impl::RemovePairingRequested(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + PairAsync: PairAsync::, + PairWithProtectionLevelAsync: PairWithProtectionLevelAsync::, + PairWithProtectionLevelAndSettingsAsync: PairWithProtectionLevelAndSettingsAsync::, + PairingRequested: PairingRequested::, + RemovePairingRequested: RemovePairingRequested::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceInformationCustomPairing_Vtbl { @@ -5895,6 +17589,51 @@ windows_core::imp::define_interface!(IDeviceInformationCustomPairing2, IDeviceIn impl windows_core::RuntimeType for IDeviceInformationCustomPairing2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceInformationCustomPairing2 { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceInformationCustomPairing2"; +} +pub trait IDeviceInformationCustomPairing2_Impl: windows_core::IUnknownImpl { + fn AddPairingSetMember(&self, device: windows_core::Ref<'_, DeviceInformation>) -> windows_core::Result<()>; + fn PairingSetMembersRequested(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemovePairingSetMembersRequested(&self, token: i64) -> windows_core::Result<()>; +} +impl IDeviceInformationCustomPairing2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AddPairingSetMember(this: *mut core::ffi::c_void, device: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDeviceInformationCustomPairing2_Impl::AddPairingSetMember(this, core::mem::transmute_copy(&device)).into() + } + } + unsafe extern "system" fn PairingSetMembersRequested(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationCustomPairing2_Impl::PairingSetMembersRequested(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemovePairingSetMembersRequested(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDeviceInformationCustomPairing2_Impl::RemovePairingSetMembersRequested(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AddPairingSetMember: AddPairingSetMember::, + PairingSetMembersRequested: PairingSetMembersRequested::, + RemovePairingSetMembersRequested: RemovePairingSetMembersRequested::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceInformationCustomPairing2_Vtbl { @@ -5907,6 +17646,79 @@ windows_core::imp::define_interface!(IDeviceInformationPairing, IDeviceInformati impl windows_core::RuntimeType for IDeviceInformationPairing { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceInformationPairing { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceInformationPairing"; +} +pub trait IDeviceInformationPairing_Impl: windows_core::IUnknownImpl { + fn IsPaired(&self) -> windows_core::Result; + fn CanPair(&self) -> windows_core::Result; + fn PairAsync(&self) -> windows_core::Result>; + fn PairWithProtectionLevelAsync(&self, minProtectionLevel: DevicePairingProtectionLevel) -> windows_core::Result>; +} +impl IDeviceInformationPairing_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsPaired(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationPairing_Impl::IsPaired(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CanPair(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationPairing_Impl::CanPair(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PairAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationPairing_Impl::PairAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PairWithProtectionLevelAsync(this: *mut core::ffi::c_void, minprotectionlevel: DevicePairingProtectionLevel, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationPairing_Impl::PairWithProtectionLevelAsync(this, minprotectionlevel) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsPaired: IsPaired::, + CanPair: CanPair::, + PairAsync: PairAsync::, + PairWithProtectionLevelAsync: PairWithProtectionLevelAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceInformationPairing_Vtbl { @@ -5920,6 +17732,80 @@ windows_core::imp::define_interface!(IDeviceInformationPairing2, IDeviceInformat impl windows_core::RuntimeType for IDeviceInformationPairing2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceInformationPairing2 { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceInformationPairing2"; +} +pub trait IDeviceInformationPairing2_Impl: windows_core::IUnknownImpl { + fn ProtectionLevel(&self) -> windows_core::Result; + fn Custom(&self) -> windows_core::Result; + fn PairWithProtectionLevelAndSettingsAsync(&self, minProtectionLevel: DevicePairingProtectionLevel, devicePairingSettings: windows_core::Ref<'_, IDevicePairingSettings>) -> windows_core::Result>; + fn UnpairAsync(&self) -> windows_core::Result>; +} +impl IDeviceInformationPairing2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ProtectionLevel(this: *mut core::ffi::c_void, result__: *mut DevicePairingProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationPairing2_Impl::ProtectionLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Custom(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationPairing2_Impl::Custom(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PairWithProtectionLevelAndSettingsAsync(this: *mut core::ffi::c_void, minprotectionlevel: DevicePairingProtectionLevel, devicepairingsettings: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationPairing2_Impl::PairWithProtectionLevelAndSettingsAsync(this, minprotectionlevel, core::mem::transmute_copy(&devicepairingsettings)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn UnpairAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationPairing2_Impl::UnpairAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ProtectionLevel: ProtectionLevel::, + Custom: Custom::, + PairWithProtectionLevelAndSettingsAsync: PairWithProtectionLevelAndSettingsAsync::, + UnpairAsync: UnpairAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceInformationPairing2_Vtbl { @@ -5933,6 +17819,35 @@ windows_core::imp::define_interface!(IDeviceInformationPairingStatics, IDeviceIn impl windows_core::RuntimeType for IDeviceInformationPairingStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceInformationPairingStatics { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceInformationPairingStatics"; +} +pub trait IDeviceInformationPairingStatics_Impl: windows_core::IUnknownImpl { + fn TryRegisterForAllInboundPairingRequests(&self, pairingKindsSupported: DevicePairingKinds) -> windows_core::Result; +} +impl IDeviceInformationPairingStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TryRegisterForAllInboundPairingRequests(this: *mut core::ffi::c_void, pairingkindssupported: DevicePairingKinds, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationPairingStatics_Impl::TryRegisterForAllInboundPairingRequests(this, pairingkindssupported) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + TryRegisterForAllInboundPairingRequests: TryRegisterForAllInboundPairingRequests::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceInformationPairingStatics_Vtbl { @@ -5943,6 +17858,35 @@ windows_core::imp::define_interface!(IDeviceInformationPairingStatics2, IDeviceI impl windows_core::RuntimeType for IDeviceInformationPairingStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceInformationPairingStatics2 { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceInformationPairingStatics2"; +} +pub trait IDeviceInformationPairingStatics2_Impl: windows_core::IUnknownImpl { + fn TryRegisterForAllInboundPairingRequestsWithProtectionLevel(&self, pairingKindsSupported: DevicePairingKinds, minProtectionLevel: DevicePairingProtectionLevel) -> windows_core::Result; +} +impl IDeviceInformationPairingStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TryRegisterForAllInboundPairingRequestsWithProtectionLevel(this: *mut core::ffi::c_void, pairingkindssupported: DevicePairingKinds, minprotectionlevel: DevicePairingProtectionLevel, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationPairingStatics2_Impl::TryRegisterForAllInboundPairingRequestsWithProtectionLevel(this, pairingkindssupported, minprotectionlevel) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + TryRegisterForAllInboundPairingRequestsWithProtectionLevel: TryRegisterForAllInboundPairingRequestsWithProtectionLevel::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceInformationPairingStatics2_Vtbl { @@ -5953,6 +17897,171 @@ windows_core::imp::define_interface!(IDeviceInformationStatics, IDeviceInformati impl windows_core::RuntimeType for IDeviceInformationStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceInformationStatics { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceInformationStatics"; +} +pub trait IDeviceInformationStatics_Impl: windows_core::IUnknownImpl { + fn CreateFromIdAsync(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; + fn CreateFromIdAsyncAdditionalProperties(&self, deviceId: &windows_core::HSTRING, additionalProperties: windows_core::Ref<'_, windows_collections::IIterable>) -> windows_core::Result>; + fn FindAllAsync(&self) -> windows_core::Result>; + fn FindAllAsyncDeviceClass(&self, deviceClass: DeviceClass) -> windows_core::Result>; + fn FindAllAsyncAqsFilter(&self, aqsFilter: &windows_core::HSTRING) -> windows_core::Result>; + fn FindAllAsyncAqsFilterAndAdditionalProperties(&self, aqsFilter: &windows_core::HSTRING, additionalProperties: windows_core::Ref<'_, windows_collections::IIterable>) -> windows_core::Result>; + fn CreateWatcher(&self) -> windows_core::Result; + fn CreateWatcherDeviceClass(&self, deviceClass: DeviceClass) -> windows_core::Result; + fn CreateWatcherAqsFilter(&self, aqsFilter: &windows_core::HSTRING) -> windows_core::Result; + fn CreateWatcherAqsFilterAndAdditionalProperties(&self, aqsFilter: &windows_core::HSTRING, additionalProperties: windows_core::Ref<'_, windows_collections::IIterable>) -> windows_core::Result; +} +impl IDeviceInformationStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics_Impl::CreateFromIdAsync(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromIdAsyncAdditionalProperties(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, additionalproperties: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics_Impl::CreateFromIdAsyncAdditionalProperties(this, core::mem::transmute(&deviceid), core::mem::transmute_copy(&additionalproperties)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FindAllAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics_Impl::FindAllAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FindAllAsyncDeviceClass(this: *mut core::ffi::c_void, deviceclass: DeviceClass, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics_Impl::FindAllAsyncDeviceClass(this, deviceclass) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FindAllAsyncAqsFilter(this: *mut core::ffi::c_void, aqsfilter: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics_Impl::FindAllAsyncAqsFilter(this, core::mem::transmute(&aqsfilter)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FindAllAsyncAqsFilterAndAdditionalProperties(this: *mut core::ffi::c_void, aqsfilter: *mut core::ffi::c_void, additionalproperties: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics_Impl::FindAllAsyncAqsFilterAndAdditionalProperties(this, core::mem::transmute(&aqsfilter), core::mem::transmute_copy(&additionalproperties)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateWatcher(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics_Impl::CreateWatcher(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateWatcherDeviceClass(this: *mut core::ffi::c_void, deviceclass: DeviceClass, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics_Impl::CreateWatcherDeviceClass(this, deviceclass) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateWatcherAqsFilter(this: *mut core::ffi::c_void, aqsfilter: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics_Impl::CreateWatcherAqsFilter(this, core::mem::transmute(&aqsfilter)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateWatcherAqsFilterAndAdditionalProperties(this: *mut core::ffi::c_void, aqsfilter: *mut core::ffi::c_void, additionalproperties: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics_Impl::CreateWatcherAqsFilterAndAdditionalProperties(this, core::mem::transmute(&aqsfilter), core::mem::transmute_copy(&additionalproperties)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromIdAsync: CreateFromIdAsync::, + CreateFromIdAsyncAdditionalProperties: CreateFromIdAsyncAdditionalProperties::, + FindAllAsync: FindAllAsync::, + FindAllAsyncDeviceClass: FindAllAsyncDeviceClass::, + FindAllAsyncAqsFilter: FindAllAsyncAqsFilter::, + FindAllAsyncAqsFilterAndAdditionalProperties: FindAllAsyncAqsFilterAndAdditionalProperties::, + CreateWatcher: CreateWatcher::, + CreateWatcherDeviceClass: CreateWatcherDeviceClass::, + CreateWatcherAqsFilter: CreateWatcherAqsFilter::, + CreateWatcherAqsFilterAndAdditionalProperties: CreateWatcherAqsFilterAndAdditionalProperties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceInformationStatics_Vtbl { @@ -5972,6 +18081,81 @@ windows_core::imp::define_interface!(IDeviceInformationStatics2, IDeviceInformat impl windows_core::RuntimeType for IDeviceInformationStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceInformationStatics2 { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceInformationStatics2"; +} +pub trait IDeviceInformationStatics2_Impl: windows_core::IUnknownImpl { + fn GetAqsFilterFromDeviceClass(&self, deviceClass: DeviceClass) -> windows_core::Result; + fn CreateFromIdAsyncWithKindAndAdditionalProperties(&self, deviceId: &windows_core::HSTRING, additionalProperties: windows_core::Ref<'_, windows_collections::IIterable>, kind: DeviceInformationKind) -> windows_core::Result>; + fn FindAllAsyncWithKindAqsFilterAndAdditionalProperties(&self, aqsFilter: &windows_core::HSTRING, additionalProperties: windows_core::Ref<'_, windows_collections::IIterable>, kind: DeviceInformationKind) -> windows_core::Result>; + fn CreateWatcherWithKindAqsFilterAndAdditionalProperties(&self, aqsFilter: &windows_core::HSTRING, additionalProperties: windows_core::Ref<'_, windows_collections::IIterable>, kind: DeviceInformationKind) -> windows_core::Result; +} +impl IDeviceInformationStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetAqsFilterFromDeviceClass(this: *mut core::ffi::c_void, deviceclass: DeviceClass, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics2_Impl::GetAqsFilterFromDeviceClass(this, deviceclass) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromIdAsyncWithKindAndAdditionalProperties(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, additionalproperties: *mut core::ffi::c_void, kind: DeviceInformationKind, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics2_Impl::CreateFromIdAsyncWithKindAndAdditionalProperties(this, core::mem::transmute(&deviceid), core::mem::transmute_copy(&additionalproperties), kind) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FindAllAsyncWithKindAqsFilterAndAdditionalProperties(this: *mut core::ffi::c_void, aqsfilter: *mut core::ffi::c_void, additionalproperties: *mut core::ffi::c_void, kind: DeviceInformationKind, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics2_Impl::FindAllAsyncWithKindAqsFilterAndAdditionalProperties(this, core::mem::transmute(&aqsfilter), core::mem::transmute_copy(&additionalproperties), kind) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateWatcherWithKindAqsFilterAndAdditionalProperties(this: *mut core::ffi::c_void, aqsfilter: *mut core::ffi::c_void, additionalproperties: *mut core::ffi::c_void, kind: DeviceInformationKind, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics2_Impl::CreateWatcherWithKindAqsFilterAndAdditionalProperties(this, core::mem::transmute(&aqsfilter), core::mem::transmute_copy(&additionalproperties), kind) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetAqsFilterFromDeviceClass: GetAqsFilterFromDeviceClass::, + CreateFromIdAsyncWithKindAndAdditionalProperties: CreateFromIdAsyncWithKindAndAdditionalProperties::, + FindAllAsyncWithKindAqsFilterAndAdditionalProperties: FindAllAsyncWithKindAqsFilterAndAdditionalProperties::, + CreateWatcherWithKindAqsFilterAndAdditionalProperties: CreateWatcherWithKindAqsFilterAndAdditionalProperties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceInformationStatics2_Vtbl { @@ -5985,6 +18169,66 @@ windows_core::imp::define_interface!(IDeviceInformationStatics3, IDeviceInformat impl windows_core::RuntimeType for IDeviceInformationStatics3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceInformationStatics3 { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceInformationStatics3"; +} +pub trait IDeviceInformationStatics3_Impl: windows_core::IUnknownImpl { + fn CreateFromIdAsyncWithAdditionalPropertiesKindAndSettings(&self, deviceId: &windows_core::HSTRING, additionalProperties: windows_core::Ref<'_, windows_collections::IIterable>, kind: DeviceInformationKind, settings: windows_core::Ref<'_, IDeviceEnumerationSettings>) -> windows_core::Result>; + fn FindAllAsyncWithAqsFilterAdditionalPropertiesKindAndSettings(&self, aqsFilter: &windows_core::HSTRING, additionalProperties: windows_core::Ref<'_, windows_collections::IIterable>, kind: DeviceInformationKind, settings: windows_core::Ref<'_, IDeviceEnumerationSettings>) -> windows_core::Result>; + fn CreateWatcherWithAqsFilterAdditionalPropertiesKindAndSettings(&self, aqsFilter: &windows_core::HSTRING, additionalProperties: windows_core::Ref<'_, windows_collections::IIterable>, kind: DeviceInformationKind, settings: windows_core::Ref<'_, IDeviceEnumerationSettings>) -> windows_core::Result; +} +impl IDeviceInformationStatics3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromIdAsyncWithAdditionalPropertiesKindAndSettings(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, additionalproperties: *mut core::ffi::c_void, kind: DeviceInformationKind, settings: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics3_Impl::CreateFromIdAsyncWithAdditionalPropertiesKindAndSettings(this, core::mem::transmute(&deviceid), core::mem::transmute_copy(&additionalproperties), kind, core::mem::transmute_copy(&settings)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FindAllAsyncWithAqsFilterAdditionalPropertiesKindAndSettings(this: *mut core::ffi::c_void, aqsfilter: *mut core::ffi::c_void, additionalproperties: *mut core::ffi::c_void, kind: DeviceInformationKind, settings: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics3_Impl::FindAllAsyncWithAqsFilterAdditionalPropertiesKindAndSettings(this, core::mem::transmute(&aqsfilter), core::mem::transmute_copy(&additionalproperties), kind, core::mem::transmute_copy(&settings)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateWatcherWithAqsFilterAdditionalPropertiesKindAndSettings(this: *mut core::ffi::c_void, aqsfilter: *mut core::ffi::c_void, additionalproperties: *mut core::ffi::c_void, kind: DeviceInformationKind, settings: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationStatics3_Impl::CreateWatcherWithAqsFilterAdditionalPropertiesKindAndSettings(this, core::mem::transmute(&aqsfilter), core::mem::transmute_copy(&additionalproperties), kind, core::mem::transmute_copy(&settings)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromIdAsyncWithAdditionalPropertiesKindAndSettings: CreateFromIdAsyncWithAdditionalPropertiesKindAndSettings::, + FindAllAsyncWithAqsFilterAdditionalPropertiesKindAndSettings: FindAllAsyncWithAqsFilterAdditionalPropertiesKindAndSettings::, + CreateWatcherWithAqsFilterAdditionalPropertiesKindAndSettings: CreateWatcherWithAqsFilterAdditionalPropertiesKindAndSettings::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceInformationStatics3_Vtbl { @@ -5997,6 +18241,51 @@ windows_core::imp::define_interface!(IDeviceInformationUpdate, IDeviceInformatio impl windows_core::RuntimeType for IDeviceInformationUpdate { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceInformationUpdate { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceInformationUpdate"; +} +pub trait IDeviceInformationUpdate_Impl: windows_core::IUnknownImpl { + fn Id(&self) -> windows_core::Result; + fn Properties(&self) -> windows_core::Result>; +} +impl IDeviceInformationUpdate_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Id(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationUpdate_Impl::Id(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationUpdate_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Id: Id::, + Properties: Properties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceInformationUpdate_Vtbl { @@ -6008,6 +18297,32 @@ windows_core::imp::define_interface!(IDeviceInformationUpdate2, IDeviceInformati impl windows_core::RuntimeType for IDeviceInformationUpdate2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceInformationUpdate2 { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceInformationUpdate2"; +} +pub trait IDeviceInformationUpdate2_Impl: windows_core::IUnknownImpl { + fn Kind(&self) -> windows_core::Result; +} +impl IDeviceInformationUpdate2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Kind(this: *mut core::ffi::c_void, result__: *mut DeviceInformationKind) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceInformationUpdate2_Impl::Kind(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Kind: Kind:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceInformationUpdate2_Vtbl { @@ -6018,6 +18333,96 @@ windows_core::imp::define_interface!(IDevicePairingRequestedEventArgs, IDevicePa impl windows_core::RuntimeType for IDevicePairingRequestedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDevicePairingRequestedEventArgs { + const NAME: &'static str = "Windows.Devices.Enumeration.IDevicePairingRequestedEventArgs"; +} +pub trait IDevicePairingRequestedEventArgs_Impl: windows_core::IUnknownImpl { + fn DeviceInformation(&self) -> windows_core::Result; + fn PairingKind(&self) -> windows_core::Result; + fn Pin(&self) -> windows_core::Result; + fn Accept(&self) -> windows_core::Result<()>; + fn AcceptWithPin(&self, pin: &windows_core::HSTRING) -> windows_core::Result<()>; + fn GetDeferral(&self) -> windows_core::Result; +} +impl IDevicePairingRequestedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceInformation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDevicePairingRequestedEventArgs_Impl::DeviceInformation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PairingKind(this: *mut core::ffi::c_void, result__: *mut DevicePairingKinds) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDevicePairingRequestedEventArgs_Impl::PairingKind(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Pin(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDevicePairingRequestedEventArgs_Impl::Pin(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Accept(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDevicePairingRequestedEventArgs_Impl::Accept(this).into() + } + } + unsafe extern "system" fn AcceptWithPin(this: *mut core::ffi::c_void, pin: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDevicePairingRequestedEventArgs_Impl::AcceptWithPin(this, core::mem::transmute(&pin)).into() + } + } + unsafe extern "system" fn GetDeferral(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDevicePairingRequestedEventArgs_Impl::GetDeferral(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DeviceInformation: DeviceInformation::, + PairingKind: PairingKind::, + Pin: Pin::, + Accept: Accept::, + AcceptWithPin: AcceptWithPin::, + GetDeferral: GetDeferral::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDevicePairingRequestedEventArgs_Vtbl { @@ -6033,6 +18438,32 @@ windows_core::imp::define_interface!(IDevicePairingRequestedEventArgs2, IDeviceP impl windows_core::RuntimeType for IDevicePairingRequestedEventArgs2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Security_Credentials")] +impl windows_core::RuntimeName for IDevicePairingRequestedEventArgs2 { + const NAME: &'static str = "Windows.Devices.Enumeration.IDevicePairingRequestedEventArgs2"; +} +#[cfg(feature = "Security_Credentials")] +pub trait IDevicePairingRequestedEventArgs2_Impl: windows_core::IUnknownImpl { + fn AcceptWithPasswordCredential(&self, passwordCredential: windows_core::Ref<'_, super::super::Security::Credentials::PasswordCredential>) -> windows_core::Result<()>; +} +#[cfg(feature = "Security_Credentials")] +impl IDevicePairingRequestedEventArgs2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AcceptWithPasswordCredential(this: *mut core::ffi::c_void, passwordcredential: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDevicePairingRequestedEventArgs2_Impl::AcceptWithPasswordCredential(this, core::mem::transmute_copy(&passwordcredential)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AcceptWithPasswordCredential: AcceptWithPasswordCredential::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDevicePairingRequestedEventArgs2_Vtbl { @@ -6046,6 +18477,29 @@ windows_core::imp::define_interface!(IDevicePairingRequestedEventArgs3, IDeviceP impl windows_core::RuntimeType for IDevicePairingRequestedEventArgs3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDevicePairingRequestedEventArgs3 { + const NAME: &'static str = "Windows.Devices.Enumeration.IDevicePairingRequestedEventArgs3"; +} +pub trait IDevicePairingRequestedEventArgs3_Impl: windows_core::IUnknownImpl { + fn AcceptWithAddress(&self, address: &windows_core::HSTRING) -> windows_core::Result<()>; +} +impl IDevicePairingRequestedEventArgs3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AcceptWithAddress(this: *mut core::ffi::c_void, address: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDevicePairingRequestedEventArgs3_Impl::AcceptWithAddress(this, core::mem::transmute(&address)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AcceptWithAddress: AcceptWithAddress::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDevicePairingRequestedEventArgs3_Vtbl { @@ -6056,6 +18510,49 @@ windows_core::imp::define_interface!(IDevicePairingResult, IDevicePairingResult_ impl windows_core::RuntimeType for IDevicePairingResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDevicePairingResult { + const NAME: &'static str = "Windows.Devices.Enumeration.IDevicePairingResult"; +} +pub trait IDevicePairingResult_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; + fn ProtectionLevelUsed(&self) -> windows_core::Result; +} +impl IDevicePairingResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut DevicePairingResultStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDevicePairingResult_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ProtectionLevelUsed(this: *mut core::ffi::c_void, result__: *mut DevicePairingProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDevicePairingResult_Impl::ProtectionLevelUsed(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Status: Status::, + ProtectionLevelUsed: ProtectionLevelUsed::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDevicePairingResult_Vtbl { @@ -6067,6 +18564,65 @@ windows_core::imp::define_interface!(IDevicePairingSetMembersRequestedEventArgs, impl windows_core::RuntimeType for IDevicePairingSetMembersRequestedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDevicePairingSetMembersRequestedEventArgs { + const NAME: &'static str = "Windows.Devices.Enumeration.IDevicePairingSetMembersRequestedEventArgs"; +} +pub trait IDevicePairingSetMembersRequestedEventArgs_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; + fn ParentDeviceInformation(&self) -> windows_core::Result; + fn PairingSetMembers(&self) -> windows_core::Result>; +} +impl IDevicePairingSetMembersRequestedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut DevicePairingAddPairingSetMemberStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDevicePairingSetMembersRequestedEventArgs_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ParentDeviceInformation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDevicePairingSetMembersRequestedEventArgs_Impl::ParentDeviceInformation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PairingSetMembers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDevicePairingSetMembersRequestedEventArgs_Impl::PairingSetMembers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Status: Status::, + ParentDeviceInformation: ParentDeviceInformation::, + PairingSetMembers: PairingSetMembers::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDevicePairingSetMembersRequestedEventArgs_Vtbl { @@ -6101,6 +18657,32 @@ windows_core::imp::define_interface!(IDeviceUnpairingResult, IDeviceUnpairingRes impl windows_core::RuntimeType for IDeviceUnpairingResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceUnpairingResult { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceUnpairingResult"; +} +pub trait IDeviceUnpairingResult_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; +} +impl IDeviceUnpairingResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut DeviceUnpairingResultStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceUnpairingResult_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Status: Status:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceUnpairingResult_Vtbl { @@ -6111,6 +18693,161 @@ windows_core::imp::define_interface!(IDeviceWatcher, IDeviceWatcher_Vtbl, 0xc9ea impl windows_core::RuntimeType for IDeviceWatcher { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeviceWatcher { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceWatcher"; +} +pub trait IDeviceWatcher_Impl: windows_core::IUnknownImpl { + fn Added(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveAdded(&self, token: i64) -> windows_core::Result<()>; + fn Updated(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveUpdated(&self, token: i64) -> windows_core::Result<()>; + fn Removed(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveRemoved(&self, token: i64) -> windows_core::Result<()>; + fn EnumerationCompleted(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveEnumerationCompleted(&self, token: i64) -> windows_core::Result<()>; + fn Stopped(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveStopped(&self, token: i64) -> windows_core::Result<()>; + fn Status(&self) -> windows_core::Result; + fn Start(&self) -> windows_core::Result<()>; + fn Stop(&self) -> windows_core::Result<()>; +} +impl IDeviceWatcher_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Added(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceWatcher_Impl::Added(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveAdded(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDeviceWatcher_Impl::RemoveAdded(this, token).into() + } + } + unsafe extern "system" fn Updated(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceWatcher_Impl::Updated(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveUpdated(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDeviceWatcher_Impl::RemoveUpdated(this, token).into() + } + } + unsafe extern "system" fn Removed(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceWatcher_Impl::Removed(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveRemoved(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDeviceWatcher_Impl::RemoveRemoved(this, token).into() + } + } + unsafe extern "system" fn EnumerationCompleted(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceWatcher_Impl::EnumerationCompleted(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveEnumerationCompleted(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDeviceWatcher_Impl::RemoveEnumerationCompleted(this, token).into() + } + } + unsafe extern "system" fn Stopped(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceWatcher_Impl::Stopped(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveStopped(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDeviceWatcher_Impl::RemoveStopped(this, token).into() + } + } + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut DeviceWatcherStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceWatcher_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Start(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDeviceWatcher_Impl::Start(this).into() + } + } + unsafe extern "system" fn Stop(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDeviceWatcher_Impl::Stop(this).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Added: Added::, + RemoveAdded: RemoveAdded::, + Updated: Updated::, + RemoveUpdated: RemoveUpdated::, + Removed: Removed::, + RemoveRemoved: RemoveRemoved::, + EnumerationCompleted: EnumerationCompleted::, + RemoveEnumerationCompleted: RemoveEnumerationCompleted::, + Stopped: Stopped::, + RemoveStopped: RemoveStopped::, + Status: Status::, + Start: Start::, + Stop: Stop::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceWatcher_Vtbl { @@ -6133,6 +18870,39 @@ windows_core::imp::define_interface!(IDeviceWatcher2, IDeviceWatcher2_Vtbl, 0xff impl windows_core::RuntimeType for IDeviceWatcher2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "ApplicationModel_Background")] +impl windows_core::RuntimeName for IDeviceWatcher2 { + const NAME: &'static str = "Windows.Devices.Enumeration.IDeviceWatcher2"; +} +#[cfg(feature = "ApplicationModel_Background")] +pub trait IDeviceWatcher2_Impl: windows_core::IUnknownImpl { + fn GetBackgroundTrigger(&self, requestedEventKinds: windows_core::Ref<'_, windows_collections::IIterable>) -> windows_core::Result; +} +#[cfg(feature = "ApplicationModel_Background")] +impl IDeviceWatcher2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetBackgroundTrigger(this: *mut core::ffi::c_void, requestedeventkinds: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeviceWatcher2_Impl::GetBackgroundTrigger(this, core::mem::transmute_copy(&requestedeventkinds)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetBackgroundTrigger: GetBackgroundTrigger::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeviceWatcher2_Vtbl { @@ -6146,6 +18916,63 @@ windows_core::imp::define_interface!(IEnclosureLocation, IEnclosureLocation_Vtbl impl windows_core::RuntimeType for IEnclosureLocation { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IEnclosureLocation { + const NAME: &'static str = "Windows.Devices.Enumeration.IEnclosureLocation"; +} +pub trait IEnclosureLocation_Impl: windows_core::IUnknownImpl { + fn InDock(&self) -> windows_core::Result; + fn InLid(&self) -> windows_core::Result; + fn Panel(&self) -> windows_core::Result; +} +impl IEnclosureLocation_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn InDock(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IEnclosureLocation_Impl::InDock(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn InLid(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IEnclosureLocation_Impl::InLid(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Panel(this: *mut core::ffi::c_void, result__: *mut Panel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IEnclosureLocation_Impl::Panel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + InDock: InDock::, + InLid: InLid::, + Panel: Panel::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IEnclosureLocation_Vtbl { @@ -6158,6 +18985,35 @@ windows_core::imp::define_interface!(IEnclosureLocation2, IEnclosureLocation2_Vt impl windows_core::RuntimeType for IEnclosureLocation2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IEnclosureLocation2 { + const NAME: &'static str = "Windows.Devices.Enumeration.IEnclosureLocation2"; +} +pub trait IEnclosureLocation2_Impl: IEnclosureLocation_Impl { + fn RotationAngleInDegreesClockwise(&self) -> windows_core::Result; +} +impl IEnclosureLocation2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn RotationAngleInDegreesClockwise(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IEnclosureLocation2_Impl::RotationAngleInDegreesClockwise(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + RotationAngleInDegreesClockwise: RotationAngleInDegreesClockwise::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IEnclosureLocation2_Vtbl { @@ -6183,6 +19039,7 @@ impl windows_core::RuntimeType for Panel { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Devices.Enumeration.Panel;i4)"); } } +#[cfg(feature = "Devices_Geolocation")] pub mod Geolocation{ #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -6198,11 +19055,58 @@ impl windows_core::RuntimeType for VisitMonitoringScope { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Devices.Geolocation.VisitMonitoringScope;i4)"); } } +#[cfg(feature = "Devices_Midi")] pub mod Midi{ windows_core::imp::define_interface!(IMidiChannelPressureMessage, IMidiChannelPressureMessage_Vtbl, 0xbe1fa860_62b4_4d52_a37e_92e54d35b909); impl windows_core::RuntimeType for IMidiChannelPressureMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMidiChannelPressureMessage { + const NAME: &'static str = "Windows.Devices.Midi.IMidiChannelPressureMessage"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMidiChannelPressureMessage_Impl: IMidiMessage_Impl { + fn Channel(&self) -> windows_core::Result; + fn Pressure(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IMidiChannelPressureMessage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Channel(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiChannelPressureMessage_Impl::Channel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Pressure(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiChannelPressureMessage_Impl::Pressure(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Channel: Channel::, + Pressure: Pressure::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiChannelPressureMessage_Vtbl { @@ -6214,6 +19118,36 @@ windows_core::imp::define_interface!(IMidiChannelPressureMessageFactory, IMidiCh impl windows_core::RuntimeType for IMidiChannelPressureMessageFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMidiChannelPressureMessageFactory { + const NAME: &'static str = "Windows.Devices.Midi.IMidiChannelPressureMessageFactory"; +} +pub trait IMidiChannelPressureMessageFactory_Impl: windows_core::IUnknownImpl { + fn CreateMidiChannelPressureMessage(&self, channel: u8, pressure: u8) -> windows_core::Result; +} +impl IMidiChannelPressureMessageFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateMidiChannelPressureMessage(this: *mut core::ffi::c_void, channel: u8, pressure: u8, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiChannelPressureMessageFactory_Impl::CreateMidiChannelPressureMessage(this, channel, pressure) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateMidiChannelPressureMessage: CreateMidiChannelPressureMessage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiChannelPressureMessageFactory_Vtbl { @@ -6224,6 +19158,66 @@ windows_core::imp::define_interface!(IMidiControlChangeMessage, IMidiControlChan impl windows_core::RuntimeType for IMidiControlChangeMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMidiControlChangeMessage { + const NAME: &'static str = "Windows.Devices.Midi.IMidiControlChangeMessage"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMidiControlChangeMessage_Impl: IMidiMessage_Impl { + fn Channel(&self) -> windows_core::Result; + fn Controller(&self) -> windows_core::Result; + fn ControlValue(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IMidiControlChangeMessage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Channel(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiControlChangeMessage_Impl::Channel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Controller(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiControlChangeMessage_Impl::Controller(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ControlValue(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiControlChangeMessage_Impl::ControlValue(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Channel: Channel::, + Controller: Controller::, + ControlValue: ControlValue::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiControlChangeMessage_Vtbl { @@ -6236,6 +19230,36 @@ windows_core::imp::define_interface!(IMidiControlChangeMessageFactory, IMidiCont impl windows_core::RuntimeType for IMidiControlChangeMessageFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMidiControlChangeMessageFactory { + const NAME: &'static str = "Windows.Devices.Midi.IMidiControlChangeMessageFactory"; +} +pub trait IMidiControlChangeMessageFactory_Impl: windows_core::IUnknownImpl { + fn CreateMidiControlChangeMessage(&self, channel: u8, controller: u8, controlValue: u8) -> windows_core::Result; +} +impl IMidiControlChangeMessageFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateMidiControlChangeMessage(this: *mut core::ffi::c_void, channel: u8, controller: u8, controlvalue: u8, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiControlChangeMessageFactory_Impl::CreateMidiControlChangeMessage(this, channel, controller, controlvalue) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateMidiControlChangeMessage: CreateMidiControlChangeMessage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiControlChangeMessageFactory_Vtbl { @@ -6246,6 +19270,58 @@ windows_core::imp::define_interface!(IMidiInPort, IMidiInPort_Vtbl, 0xd5c1d9db_9 impl windows_core::RuntimeType for IMidiInPort { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMidiInPort { + const NAME: &'static str = "Windows.Devices.Midi.IMidiInPort"; +} +pub trait IMidiInPort_Impl: super::super::Foundation::IClosable_Impl { + fn MessageReceived(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveMessageReceived(&self, token: i64) -> windows_core::Result<()>; + fn DeviceId(&self) -> windows_core::Result; +} +impl IMidiInPort_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn MessageReceived(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiInPort_Impl::MessageReceived(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveMessageReceived(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMidiInPort_Impl::RemoveMessageReceived(this, token).into() + } + } + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiInPort_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + MessageReceived: MessageReceived::, + RemoveMessageReceived: RemoveMessageReceived::, + DeviceId: DeviceId::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiInPort_Vtbl { @@ -6258,6 +19334,51 @@ windows_core::imp::define_interface!(IMidiInPortStatics, IMidiInPortStatics_Vtbl impl windows_core::RuntimeType for IMidiInPortStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMidiInPortStatics { + const NAME: &'static str = "Windows.Devices.Midi.IMidiInPortStatics"; +} +pub trait IMidiInPortStatics_Impl: windows_core::IUnknownImpl { + fn FromIdAsync(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; + fn GetDeviceSelector(&self) -> windows_core::Result; +} +impl IMidiInPortStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FromIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiInPortStatics_Impl::FromIdAsync(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelector(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiInPortStatics_Impl::GetDeviceSelector(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FromIdAsync: FromIdAsync::, + GetDeviceSelector: GetDeviceSelector::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiInPortStatics_Vtbl { @@ -6271,6 +19392,13 @@ impl windows_core::RuntimeType for IMidiMessage { } windows_core::imp::interface_hierarchy!(IMidiMessage, windows_core::IUnknown, windows_core::IInspectable); impl IMidiMessage { + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = self; @@ -6279,7 +19407,14 @@ impl IMidiMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } +} #[cfg(feature = "Storage_Streams")] impl windows_core::RuntimeName for IMidiMessage { const NAME: &'static str = "Windows.Devices.Midi.IMidiMessage"; @@ -6356,6 +19491,33 @@ windows_core::imp::define_interface!(IMidiMessageReceivedEventArgs, IMidiMessage impl windows_core::RuntimeType for IMidiMessageReceivedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMidiMessageReceivedEventArgs { + const NAME: &'static str = "Windows.Devices.Midi.IMidiMessageReceivedEventArgs"; +} +pub trait IMidiMessageReceivedEventArgs_Impl: windows_core::IUnknownImpl { + fn Message(&self) -> windows_core::Result; +} +impl IMidiMessageReceivedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Message(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiMessageReceivedEventArgs_Impl::Message(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Message: Message:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiMessageReceivedEventArgs_Vtbl { @@ -6366,6 +19528,66 @@ windows_core::imp::define_interface!(IMidiNoteOffMessage, IMidiNoteOffMessage_Vt impl windows_core::RuntimeType for IMidiNoteOffMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMidiNoteOffMessage { + const NAME: &'static str = "Windows.Devices.Midi.IMidiNoteOffMessage"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMidiNoteOffMessage_Impl: IMidiMessage_Impl { + fn Channel(&self) -> windows_core::Result; + fn Note(&self) -> windows_core::Result; + fn Velocity(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IMidiNoteOffMessage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Channel(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiNoteOffMessage_Impl::Channel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Note(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiNoteOffMessage_Impl::Note(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Velocity(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiNoteOffMessage_Impl::Velocity(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Channel: Channel::, + Note: Note::, + Velocity: Velocity::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiNoteOffMessage_Vtbl { @@ -6378,6 +19600,36 @@ windows_core::imp::define_interface!(IMidiNoteOffMessageFactory, IMidiNoteOffMes impl windows_core::RuntimeType for IMidiNoteOffMessageFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMidiNoteOffMessageFactory { + const NAME: &'static str = "Windows.Devices.Midi.IMidiNoteOffMessageFactory"; +} +pub trait IMidiNoteOffMessageFactory_Impl: windows_core::IUnknownImpl { + fn CreateMidiNoteOffMessage(&self, channel: u8, note: u8, velocity: u8) -> windows_core::Result; +} +impl IMidiNoteOffMessageFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateMidiNoteOffMessage(this: *mut core::ffi::c_void, channel: u8, note: u8, velocity: u8, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiNoteOffMessageFactory_Impl::CreateMidiNoteOffMessage(this, channel, note, velocity) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateMidiNoteOffMessage: CreateMidiNoteOffMessage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiNoteOffMessageFactory_Vtbl { @@ -6388,6 +19640,66 @@ windows_core::imp::define_interface!(IMidiNoteOnMessage, IMidiNoteOnMessage_Vtbl impl windows_core::RuntimeType for IMidiNoteOnMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMidiNoteOnMessage { + const NAME: &'static str = "Windows.Devices.Midi.IMidiNoteOnMessage"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMidiNoteOnMessage_Impl: IMidiMessage_Impl { + fn Channel(&self) -> windows_core::Result; + fn Note(&self) -> windows_core::Result; + fn Velocity(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IMidiNoteOnMessage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Channel(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiNoteOnMessage_Impl::Channel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Note(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiNoteOnMessage_Impl::Note(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Velocity(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiNoteOnMessage_Impl::Velocity(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Channel: Channel::, + Note: Note::, + Velocity: Velocity::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiNoteOnMessage_Vtbl { @@ -6400,6 +19712,36 @@ windows_core::imp::define_interface!(IMidiNoteOnMessageFactory, IMidiNoteOnMessa impl windows_core::RuntimeType for IMidiNoteOnMessageFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMidiNoteOnMessageFactory { + const NAME: &'static str = "Windows.Devices.Midi.IMidiNoteOnMessageFactory"; +} +pub trait IMidiNoteOnMessageFactory_Impl: windows_core::IUnknownImpl { + fn CreateMidiNoteOnMessage(&self, channel: u8, note: u8, velocity: u8) -> windows_core::Result; +} +impl IMidiNoteOnMessageFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateMidiNoteOnMessage(this: *mut core::ffi::c_void, channel: u8, note: u8, velocity: u8, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiNoteOnMessageFactory_Impl::CreateMidiNoteOnMessage(this, channel, note, velocity) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateMidiNoteOnMessage: CreateMidiNoteOnMessage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiNoteOnMessageFactory_Vtbl { @@ -6413,6 +19755,13 @@ impl windows_core::RuntimeType for IMidiOutPort { windows_core::imp::interface_hierarchy!(IMidiOutPort, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(IMidiOutPort, super::super::Foundation::IClosable); impl IMidiOutPort { + pub fn SendMessage(&self, midimessage: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SendMessage)(windows_core::Interface::as_raw(this), midimessage.param().abi()).ok() } + } #[cfg(feature = "Storage_Streams")] pub fn SendBuffer(&self, mididata: P0) -> windows_core::Result<()> where @@ -6421,6 +19770,13 @@ impl IMidiOutPort { let this = self; unsafe { (windows_core::Interface::vtable(this).SendBuffer)(windows_core::Interface::as_raw(this), mididata.param().abi()).ok() } } + pub fn DeviceId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } pub fn Close(&self) -> windows_core::Result<()> { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } @@ -6432,8 +19788,8 @@ impl windows_core::RuntimeName for IMidiOutPort { } #[cfg(feature = "Storage_Streams")] pub trait IMidiOutPort_Impl: super::super::Foundation::IClosable_Impl { - fn SendMessage(&self, midiMessage: windows_core::Ref) -> windows_core::Result<()>; - fn SendBuffer(&self, midiData: windows_core::Ref) -> windows_core::Result<()>; + fn SendMessage(&self, midiMessage: windows_core::Ref<'_, IMidiMessage>) -> windows_core::Result<()>; + fn SendBuffer(&self, midiData: windows_core::Ref<'_, super::super::Storage::Streams::IBuffer>) -> windows_core::Result<()>; fn DeviceId(&self) -> windows_core::Result; } #[cfg(feature = "Storage_Streams")] @@ -6490,6 +19846,51 @@ windows_core::imp::define_interface!(IMidiOutPortStatics, IMidiOutPortStatics_Vt impl windows_core::RuntimeType for IMidiOutPortStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMidiOutPortStatics { + const NAME: &'static str = "Windows.Devices.Midi.IMidiOutPortStatics"; +} +pub trait IMidiOutPortStatics_Impl: windows_core::IUnknownImpl { + fn FromIdAsync(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; + fn GetDeviceSelector(&self) -> windows_core::Result; +} +impl IMidiOutPortStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FromIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiOutPortStatics_Impl::FromIdAsync(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelector(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiOutPortStatics_Impl::GetDeviceSelector(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FromIdAsync: FromIdAsync::, + GetDeviceSelector: GetDeviceSelector::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiOutPortStatics_Vtbl { @@ -6501,6 +19902,52 @@ windows_core::imp::define_interface!(IMidiPitchBendChangeMessage, IMidiPitchBend impl windows_core::RuntimeType for IMidiPitchBendChangeMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMidiPitchBendChangeMessage { + const NAME: &'static str = "Windows.Devices.Midi.IMidiPitchBendChangeMessage"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMidiPitchBendChangeMessage_Impl: IMidiMessage_Impl { + fn Channel(&self) -> windows_core::Result; + fn Bend(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IMidiPitchBendChangeMessage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Channel(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiPitchBendChangeMessage_Impl::Channel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Bend(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiPitchBendChangeMessage_Impl::Bend(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Channel: Channel::, + Bend: Bend::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiPitchBendChangeMessage_Vtbl { @@ -6512,6 +19959,36 @@ windows_core::imp::define_interface!(IMidiPitchBendChangeMessageFactory, IMidiPi impl windows_core::RuntimeType for IMidiPitchBendChangeMessageFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMidiPitchBendChangeMessageFactory { + const NAME: &'static str = "Windows.Devices.Midi.IMidiPitchBendChangeMessageFactory"; +} +pub trait IMidiPitchBendChangeMessageFactory_Impl: windows_core::IUnknownImpl { + fn CreateMidiPitchBendChangeMessage(&self, channel: u8, bend: u16) -> windows_core::Result; +} +impl IMidiPitchBendChangeMessageFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateMidiPitchBendChangeMessage(this: *mut core::ffi::c_void, channel: u8, bend: u16, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiPitchBendChangeMessageFactory_Impl::CreateMidiPitchBendChangeMessage(this, channel, bend) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateMidiPitchBendChangeMessage: CreateMidiPitchBendChangeMessage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiPitchBendChangeMessageFactory_Vtbl { @@ -6522,6 +19999,66 @@ windows_core::imp::define_interface!(IMidiPolyphonicKeyPressureMessage, IMidiPol impl windows_core::RuntimeType for IMidiPolyphonicKeyPressureMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMidiPolyphonicKeyPressureMessage { + const NAME: &'static str = "Windows.Devices.Midi.IMidiPolyphonicKeyPressureMessage"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMidiPolyphonicKeyPressureMessage_Impl: IMidiMessage_Impl { + fn Channel(&self) -> windows_core::Result; + fn Note(&self) -> windows_core::Result; + fn Pressure(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IMidiPolyphonicKeyPressureMessage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Channel(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiPolyphonicKeyPressureMessage_Impl::Channel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Note(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiPolyphonicKeyPressureMessage_Impl::Note(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Pressure(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiPolyphonicKeyPressureMessage_Impl::Pressure(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Channel: Channel::, + Note: Note::, + Pressure: Pressure::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiPolyphonicKeyPressureMessage_Vtbl { @@ -6534,6 +20071,36 @@ windows_core::imp::define_interface!(IMidiPolyphonicKeyPressureMessageFactory, I impl windows_core::RuntimeType for IMidiPolyphonicKeyPressureMessageFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMidiPolyphonicKeyPressureMessageFactory { + const NAME: &'static str = "Windows.Devices.Midi.IMidiPolyphonicKeyPressureMessageFactory"; +} +pub trait IMidiPolyphonicKeyPressureMessageFactory_Impl: windows_core::IUnknownImpl { + fn CreateMidiPolyphonicKeyPressureMessage(&self, channel: u8, note: u8, pressure: u8) -> windows_core::Result; +} +impl IMidiPolyphonicKeyPressureMessageFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateMidiPolyphonicKeyPressureMessage(this: *mut core::ffi::c_void, channel: u8, note: u8, pressure: u8, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiPolyphonicKeyPressureMessageFactory_Impl::CreateMidiPolyphonicKeyPressureMessage(this, channel, note, pressure) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateMidiPolyphonicKeyPressureMessage: CreateMidiPolyphonicKeyPressureMessage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiPolyphonicKeyPressureMessageFactory_Vtbl { @@ -6544,6 +20111,52 @@ windows_core::imp::define_interface!(IMidiProgramChangeMessage, IMidiProgramChan impl windows_core::RuntimeType for IMidiProgramChangeMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMidiProgramChangeMessage { + const NAME: &'static str = "Windows.Devices.Midi.IMidiProgramChangeMessage"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMidiProgramChangeMessage_Impl: IMidiMessage_Impl { + fn Channel(&self) -> windows_core::Result; + fn Program(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IMidiProgramChangeMessage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Channel(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiProgramChangeMessage_Impl::Channel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Program(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiProgramChangeMessage_Impl::Program(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Channel: Channel::, + Program: Program::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiProgramChangeMessage_Vtbl { @@ -6555,6 +20168,36 @@ windows_core::imp::define_interface!(IMidiProgramChangeMessageFactory, IMidiProg impl windows_core::RuntimeType for IMidiProgramChangeMessageFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMidiProgramChangeMessageFactory { + const NAME: &'static str = "Windows.Devices.Midi.IMidiProgramChangeMessageFactory"; +} +pub trait IMidiProgramChangeMessageFactory_Impl: windows_core::IUnknownImpl { + fn CreateMidiProgramChangeMessage(&self, channel: u8, program: u8) -> windows_core::Result; +} +impl IMidiProgramChangeMessageFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateMidiProgramChangeMessage(this: *mut core::ffi::c_void, channel: u8, program: u8, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiProgramChangeMessageFactory_Impl::CreateMidiProgramChangeMessage(this, channel, program) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateMidiProgramChangeMessage: CreateMidiProgramChangeMessage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiProgramChangeMessageFactory_Vtbl { @@ -6565,6 +20208,35 @@ windows_core::imp::define_interface!(IMidiSongPositionPointerMessage, IMidiSongP impl windows_core::RuntimeType for IMidiSongPositionPointerMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMidiSongPositionPointerMessage { + const NAME: &'static str = "Windows.Devices.Midi.IMidiSongPositionPointerMessage"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMidiSongPositionPointerMessage_Impl: IMidiMessage_Impl { + fn Beats(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IMidiSongPositionPointerMessage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Beats(this: *mut core::ffi::c_void, result__: *mut u16) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiSongPositionPointerMessage_Impl::Beats(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Beats: Beats:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiSongPositionPointerMessage_Vtbl { @@ -6575,6 +20247,36 @@ windows_core::imp::define_interface!(IMidiSongPositionPointerMessageFactory, IMi impl windows_core::RuntimeType for IMidiSongPositionPointerMessageFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMidiSongPositionPointerMessageFactory { + const NAME: &'static str = "Windows.Devices.Midi.IMidiSongPositionPointerMessageFactory"; +} +pub trait IMidiSongPositionPointerMessageFactory_Impl: windows_core::IUnknownImpl { + fn CreateMidiSongPositionPointerMessage(&self, beats: u16) -> windows_core::Result; +} +impl IMidiSongPositionPointerMessageFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateMidiSongPositionPointerMessage(this: *mut core::ffi::c_void, beats: u16, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiSongPositionPointerMessageFactory_Impl::CreateMidiSongPositionPointerMessage(this, beats) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateMidiSongPositionPointerMessage: CreateMidiSongPositionPointerMessage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiSongPositionPointerMessageFactory_Vtbl { @@ -6585,6 +20287,35 @@ windows_core::imp::define_interface!(IMidiSongSelectMessage, IMidiSongSelectMess impl windows_core::RuntimeType for IMidiSongSelectMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMidiSongSelectMessage { + const NAME: &'static str = "Windows.Devices.Midi.IMidiSongSelectMessage"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMidiSongSelectMessage_Impl: IMidiMessage_Impl { + fn Song(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IMidiSongSelectMessage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Song(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiSongSelectMessage_Impl::Song(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Song: Song:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiSongSelectMessage_Vtbl { @@ -6595,6 +20326,36 @@ windows_core::imp::define_interface!(IMidiSongSelectMessageFactory, IMidiSongSel impl windows_core::RuntimeType for IMidiSongSelectMessageFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMidiSongSelectMessageFactory { + const NAME: &'static str = "Windows.Devices.Midi.IMidiSongSelectMessageFactory"; +} +pub trait IMidiSongSelectMessageFactory_Impl: windows_core::IUnknownImpl { + fn CreateMidiSongSelectMessage(&self, song: u8) -> windows_core::Result; +} +impl IMidiSongSelectMessageFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateMidiSongSelectMessage(this: *mut core::ffi::c_void, song: u8, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiSongSelectMessageFactory_Impl::CreateMidiSongSelectMessage(this, song) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateMidiSongSelectMessage: CreateMidiSongSelectMessage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiSongSelectMessageFactory_Vtbl { @@ -6605,6 +20366,61 @@ windows_core::imp::define_interface!(IMidiSynthesizer, IMidiSynthesizer_Vtbl, 0x impl windows_core::RuntimeType for IMidiSynthesizer { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(all(feature = "Devices_Enumeration", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IMidiSynthesizer { + const NAME: &'static str = "Windows.Devices.Midi.IMidiSynthesizer"; +} +#[cfg(all(feature = "Devices_Enumeration", feature = "Storage_Streams"))] +pub trait IMidiSynthesizer_Impl: super::super::Foundation::IClosable_Impl + IMidiOutPort_Impl { + fn AudioDevice(&self) -> windows_core::Result; + fn Volume(&self) -> windows_core::Result; + fn SetVolume(&self, value: f64) -> windows_core::Result<()>; +} +#[cfg(all(feature = "Devices_Enumeration", feature = "Storage_Streams"))] +impl IMidiSynthesizer_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AudioDevice(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiSynthesizer_Impl::AudioDevice(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Volume(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiSynthesizer_Impl::Volume(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetVolume(this: *mut core::ffi::c_void, value: f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMidiSynthesizer_Impl::SetVolume(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AudioDevice: AudioDevice::, + Volume: Volume::, + SetVolume: SetVolume::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiSynthesizer_Vtbl { @@ -6620,6 +20436,68 @@ windows_core::imp::define_interface!(IMidiSynthesizerStatics, IMidiSynthesizerSt impl windows_core::RuntimeType for IMidiSynthesizerStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Devices_Enumeration")] +impl windows_core::RuntimeName for IMidiSynthesizerStatics { + const NAME: &'static str = "Windows.Devices.Midi.IMidiSynthesizerStatics"; +} +#[cfg(feature = "Devices_Enumeration")] +pub trait IMidiSynthesizerStatics_Impl: windows_core::IUnknownImpl { + fn CreateAsync(&self) -> windows_core::Result>; + fn CreateFromAudioDeviceAsync(&self, audioDevice: windows_core::Ref<'_, super::Enumeration::DeviceInformation>) -> windows_core::Result>; + fn IsSynthesizer(&self, midiDevice: windows_core::Ref<'_, super::Enumeration::DeviceInformation>) -> windows_core::Result; +} +#[cfg(feature = "Devices_Enumeration")] +impl IMidiSynthesizerStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiSynthesizerStatics_Impl::CreateAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromAudioDeviceAsync(this: *mut core::ffi::c_void, audiodevice: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiSynthesizerStatics_Impl::CreateFromAudioDeviceAsync(this, core::mem::transmute_copy(&audiodevice)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsSynthesizer(this: *mut core::ffi::c_void, mididevice: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiSynthesizerStatics_Impl::IsSynthesizer(this, core::mem::transmute_copy(&mididevice)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateAsync: CreateAsync::, + CreateFromAudioDeviceAsync: CreateFromAudioDeviceAsync::, + IsSynthesizer: IsSynthesizer::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiSynthesizerStatics_Vtbl { @@ -6638,6 +20516,39 @@ windows_core::imp::define_interface!(IMidiSystemExclusiveMessageFactory, IMidiSy impl windows_core::RuntimeType for IMidiSystemExclusiveMessageFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMidiSystemExclusiveMessageFactory { + const NAME: &'static str = "Windows.Devices.Midi.IMidiSystemExclusiveMessageFactory"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMidiSystemExclusiveMessageFactory_Impl: windows_core::IUnknownImpl { + fn CreateMidiSystemExclusiveMessage(&self, rawData: windows_core::Ref<'_, super::super::Storage::Streams::IBuffer>) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IMidiSystemExclusiveMessageFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateMidiSystemExclusiveMessage(this: *mut core::ffi::c_void, rawdata: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiSystemExclusiveMessageFactory_Impl::CreateMidiSystemExclusiveMessage(this, core::mem::transmute_copy(&rawdata)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateMidiSystemExclusiveMessage: CreateMidiSystemExclusiveMessage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiSystemExclusiveMessageFactory_Vtbl { @@ -6651,6 +20562,52 @@ windows_core::imp::define_interface!(IMidiTimeCodeMessage, IMidiTimeCodeMessage_ impl windows_core::RuntimeType for IMidiTimeCodeMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMidiTimeCodeMessage { + const NAME: &'static str = "Windows.Devices.Midi.IMidiTimeCodeMessage"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMidiTimeCodeMessage_Impl: IMidiMessage_Impl { + fn FrameType(&self) -> windows_core::Result; + fn Values(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IMidiTimeCodeMessage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FrameType(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiTimeCodeMessage_Impl::FrameType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Values(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiTimeCodeMessage_Impl::Values(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FrameType: FrameType::, + Values: Values::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiTimeCodeMessage_Vtbl { @@ -6662,6 +20619,36 @@ windows_core::imp::define_interface!(IMidiTimeCodeMessageFactory, IMidiTimeCodeM impl windows_core::RuntimeType for IMidiTimeCodeMessageFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMidiTimeCodeMessageFactory { + const NAME: &'static str = "Windows.Devices.Midi.IMidiTimeCodeMessageFactory"; +} +pub trait IMidiTimeCodeMessageFactory_Impl: windows_core::IUnknownImpl { + fn CreateMidiTimeCodeMessage(&self, frameType: u8, values: u8) -> windows_core::Result; +} +impl IMidiTimeCodeMessageFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateMidiTimeCodeMessage(this: *mut core::ffi::c_void, frametype: u8, values: u8, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMidiTimeCodeMessageFactory_Impl::CreateMidiTimeCodeMessage(this, frametype, values) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateMidiTimeCodeMessage: CreateMidiTimeCodeMessage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMidiTimeCodeMessageFactory_Vtbl { @@ -6680,6 +20667,13 @@ impl MidiActiveSensingMessage { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = self; @@ -6688,7 +20682,14 @@ impl MidiActiveSensingMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } +} impl windows_core::RuntimeType for MidiActiveSensingMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -6707,6 +20708,33 @@ pub struct MidiChannelPressureMessage(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(MidiChannelPressureMessage, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(MidiChannelPressureMessage, IMidiMessage); impl MidiChannelPressureMessage { + pub fn Channel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Channel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Pressure(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Pressure)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CreateMidiChannelPressureMessage(channel: u8, pressure: u8) -> windows_core::Result { + Self::IMidiChannelPressureMessageFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateMidiChannelPressureMessage)(windows_core::Interface::as_raw(this), channel, pressure, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Timestamp(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; @@ -6715,6 +20743,13 @@ impl MidiChannelPressureMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } fn IMidiChannelPressureMessageFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -6744,6 +20779,13 @@ impl MidiContinueMessage { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = self; @@ -6752,7 +20794,14 @@ impl MidiContinueMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } +} impl windows_core::RuntimeType for MidiContinueMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -6771,6 +20820,40 @@ pub struct MidiControlChangeMessage(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(MidiControlChangeMessage, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(MidiControlChangeMessage, IMidiMessage); impl MidiControlChangeMessage { + pub fn Channel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Channel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Controller(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Controller)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ControlValue(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ControlValue)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CreateMidiControlChangeMessage(channel: u8, controller: u8, controlvalue: u8) -> windows_core::Result { + Self::IMidiControlChangeMessageFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateMidiControlChangeMessage)(windows_core::Interface::as_raw(this), channel, controller, controlvalue, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Timestamp(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; @@ -6779,6 +20862,13 @@ impl MidiControlChangeMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } fn IMidiControlChangeMessageFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -6820,6 +20910,13 @@ impl MidiInPort { let this = self; unsafe { (windows_core::Interface::vtable(this).RemoveMessageReceived)(windows_core::Interface::as_raw(this), token).ok() } } + pub fn DeviceId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } pub fn FromIdAsync(deviceid: &windows_core::HSTRING) -> windows_core::Result> { Self::IMidiInPortStatics(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -6911,6 +21008,13 @@ pub struct MidiNoteOffMessage(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(MidiNoteOffMessage, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(MidiNoteOffMessage, IMidiMessage); impl MidiNoteOffMessage { + pub fn Timestamp(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; @@ -6919,6 +21023,40 @@ impl MidiNoteOffMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Channel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Channel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Note(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Note)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Velocity(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Velocity)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CreateMidiNoteOffMessage(channel: u8, note: u8, velocity: u8) -> windows_core::Result { + Self::IMidiNoteOffMessageFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateMidiNoteOffMessage)(windows_core::Interface::as_raw(this), channel, note, velocity, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IMidiNoteOffMessageFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -6942,6 +21080,13 @@ pub struct MidiNoteOnMessage(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(MidiNoteOnMessage, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(MidiNoteOnMessage, IMidiMessage); impl MidiNoteOnMessage { + pub fn Timestamp(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; @@ -6950,6 +21095,40 @@ impl MidiNoteOnMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Channel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Channel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Note(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Note)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Velocity(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Velocity)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CreateMidiNoteOnMessage(channel: u8, note: u8, velocity: u8) -> windows_core::Result { + Self::IMidiNoteOnMessageFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateMidiNoteOnMessage)(windows_core::Interface::as_raw(this), channel, note, velocity, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IMidiNoteOnMessageFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -6977,6 +21156,13 @@ impl MidiOutPort { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn SendMessage(&self, midimessage: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SendMessage)(windows_core::Interface::as_raw(this), midimessage.param().abi()).ok() } + } #[cfg(feature = "Storage_Streams")] pub fn SendBuffer(&self, mididata: P0) -> windows_core::Result<()> where @@ -6985,6 +21171,13 @@ impl MidiOutPort { let this = self; unsafe { (windows_core::Interface::vtable(this).SendBuffer)(windows_core::Interface::as_raw(this), mididata.param().abi()).ok() } } + pub fn DeviceId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } pub fn FromIdAsync(deviceid: &windows_core::HSTRING) -> windows_core::Result> { Self::IMidiOutPortStatics(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -7020,6 +21213,13 @@ pub struct MidiPitchBendChangeMessage(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(MidiPitchBendChangeMessage, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(MidiPitchBendChangeMessage, IMidiMessage); impl MidiPitchBendChangeMessage { + pub fn Timestamp(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; @@ -7028,6 +21228,33 @@ impl MidiPitchBendChangeMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Channel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Channel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Bend(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Bend)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CreateMidiPitchBendChangeMessage(channel: u8, bend: u16) -> windows_core::Result { + Self::IMidiPitchBendChangeMessageFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateMidiPitchBendChangeMessage)(windows_core::Interface::as_raw(this), channel, bend, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IMidiPitchBendChangeMessageFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -7051,6 +21278,13 @@ pub struct MidiPolyphonicKeyPressureMessage(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(MidiPolyphonicKeyPressureMessage, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(MidiPolyphonicKeyPressureMessage, IMidiMessage); impl MidiPolyphonicKeyPressureMessage { + pub fn Timestamp(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; @@ -7059,6 +21293,40 @@ impl MidiPolyphonicKeyPressureMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Channel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Channel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Note(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Note)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Pressure(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Pressure)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CreateMidiPolyphonicKeyPressureMessage(channel: u8, note: u8, pressure: u8) -> windows_core::Result { + Self::IMidiPolyphonicKeyPressureMessageFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateMidiPolyphonicKeyPressureMessage)(windows_core::Interface::as_raw(this), channel, note, pressure, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IMidiPolyphonicKeyPressureMessageFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -7082,6 +21350,13 @@ pub struct MidiProgramChangeMessage(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(MidiProgramChangeMessage, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(MidiProgramChangeMessage, IMidiMessage); impl MidiProgramChangeMessage { + pub fn Timestamp(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; @@ -7090,6 +21365,33 @@ impl MidiProgramChangeMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Channel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Channel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Program(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Program)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CreateMidiProgramChangeMessage(channel: u8, program: u8) -> windows_core::Result { + Self::IMidiProgramChangeMessageFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateMidiProgramChangeMessage)(windows_core::Interface::as_raw(this), channel, program, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IMidiProgramChangeMessageFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -7113,6 +21415,13 @@ pub struct MidiSongPositionPointerMessage(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(MidiSongPositionPointerMessage, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(MidiSongPositionPointerMessage, IMidiMessage); impl MidiSongPositionPointerMessage { + pub fn Timestamp(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; @@ -7121,6 +21430,26 @@ impl MidiSongPositionPointerMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Beats(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Beats)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CreateMidiSongPositionPointerMessage(beats: u16) -> windows_core::Result { + Self::IMidiSongPositionPointerMessageFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateMidiSongPositionPointerMessage)(windows_core::Interface::as_raw(this), beats, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IMidiSongPositionPointerMessageFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -7144,6 +21473,13 @@ pub struct MidiSongSelectMessage(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(MidiSongSelectMessage, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(MidiSongSelectMessage, IMidiMessage); impl MidiSongSelectMessage { + pub fn Timestamp(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; @@ -7152,6 +21488,26 @@ impl MidiSongSelectMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Song(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Song)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CreateMidiSongSelectMessage(song: u8) -> windows_core::Result { + Self::IMidiSongSelectMessageFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateMidiSongSelectMessage)(windows_core::Interface::as_raw(this), song, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IMidiSongSelectMessageFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -7181,6 +21537,13 @@ impl MidiStartMessage { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = self; @@ -7189,7 +21552,14 @@ impl MidiStartMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } +} impl windows_core::RuntimeType for MidiStartMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7214,6 +21584,13 @@ impl MidiStopMessage { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = self; @@ -7222,7 +21599,14 @@ impl MidiStopMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } +} impl windows_core::RuntimeType for MidiStopMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7245,6 +21629,13 @@ impl MidiSynthesizer { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn SendMessage(&self, midimessage: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SendMessage)(windows_core::Interface::as_raw(this), midimessage.param().abi()).ok() } + } #[cfg(feature = "Storage_Streams")] pub fn SendBuffer(&self, mididata: P0) -> windows_core::Result<()> where @@ -7253,10 +21644,58 @@ impl MidiSynthesizer { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).SendBuffer)(windows_core::Interface::as_raw(this), mididata.param().abi()).ok() } } + pub fn DeviceId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(feature = "Devices_Enumeration")] + pub fn AudioDevice(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AudioDevice)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Volume(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Volume)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn SetVolume(&self, value: f64) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).SetVolume)(windows_core::Interface::as_raw(this), value).ok() } } + pub fn CreateAsync() -> windows_core::Result> { + Self::IMidiSynthesizerStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Devices_Enumeration")] + pub fn CreateFromAudioDeviceAsync(audiodevice: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::IMidiSynthesizerStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromAudioDeviceAsync)(windows_core::Interface::as_raw(this), audiodevice.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Devices_Enumeration")] + pub fn IsSynthesizer(mididevice: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMidiSynthesizerStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsSynthesizer)(windows_core::Interface::as_raw(this), mididevice.param().abi(), &mut result__).map(|| result__) + }) + } fn IMidiSynthesizerStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -7279,6 +21718,13 @@ unsafe impl Sync for MidiSynthesizer {} pub struct MidiSystemExclusiveMessage(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(MidiSystemExclusiveMessage, windows_core::IUnknown, windows_core::IInspectable, IMidiMessage); impl MidiSystemExclusiveMessage { + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = self; @@ -7287,6 +21733,23 @@ impl MidiSystemExclusiveMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateMidiSystemExclusiveMessage(rawdata: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMidiSystemExclusiveMessageFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateMidiSystemExclusiveMessage)(windows_core::Interface::as_raw(this), rawdata.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IMidiSystemExclusiveMessageFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -7316,6 +21779,13 @@ impl MidiSystemResetMessage { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = self; @@ -7324,7 +21794,14 @@ impl MidiSystemResetMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } +} impl windows_core::RuntimeType for MidiSystemResetMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7343,6 +21820,13 @@ pub struct MidiTimeCodeMessage(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(MidiTimeCodeMessage, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(MidiTimeCodeMessage, IMidiMessage); impl MidiTimeCodeMessage { + pub fn Timestamp(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; @@ -7351,6 +21835,33 @@ impl MidiTimeCodeMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn FrameType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FrameType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Values(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Values)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CreateMidiTimeCodeMessage(frametype: u8, values: u8) -> windows_core::Result { + Self::IMidiTimeCodeMessageFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateMidiTimeCodeMessage)(windows_core::Interface::as_raw(this), frametype, values, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IMidiTimeCodeMessageFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -7380,6 +21891,13 @@ impl MidiTimingClockMessage { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = self; @@ -7388,7 +21906,14 @@ impl MidiTimingClockMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } +} impl windows_core::RuntimeType for MidiTimingClockMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7413,6 +21938,13 @@ impl MidiTuneRequestMessage { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } #[cfg(feature = "Storage_Streams")] pub fn RawData(&self) -> windows_core::Result { let this = self; @@ -7421,7 +21953,14 @@ impl MidiTuneRequestMessage { (windows_core::Interface::vtable(this).RawData)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } +} impl windows_core::RuntimeType for MidiTuneRequestMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7435,12 +21974,130 @@ impl windows_core::RuntimeName for MidiTuneRequestMessage { unsafe impl Send for MidiTuneRequestMessage {} unsafe impl Sync for MidiTuneRequestMessage {} } +#[cfg(feature = "Devices_Sensors")] pub mod Sensors{ #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] pub struct Accelerometer(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(Accelerometer, windows_core::IUnknown, windows_core::IInspectable); impl Accelerometer { + pub fn GetCurrentReading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentReading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MinimumReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinimumReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetReportInterval(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetReportInterval)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadingChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveReadingChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn Shaken(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Shaken)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveShaken(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveShaken)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Graphics_Display")] + pub fn SetReadingTransform(&self, value: super::super::Graphics::Display::DisplayOrientations) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetReadingTransform)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Graphics_Display")] + pub fn ReadingTransform(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingTransform)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetReportLatency(&self, value: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetReportLatency)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ReportLatency(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportLatency)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaxBatchSize(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxBatchSize)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadingType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReportThreshold(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportThreshold)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeviceId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetDefault() -> windows_core::Result { + Self::IAccelerometerStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetDefaultWithAccelerometerReadingType(readingtype: AccelerometerReadingType) -> windows_core::Result { + Self::IAccelerometerStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefaultWithAccelerometerReadingType)(windows_core::Interface::as_raw(this), readingtype, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn FromIdAsync(deviceid: &windows_core::HSTRING) -> windows_core::Result> { Self::IAccelerometerStatics3(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -7482,6 +22139,41 @@ unsafe impl Sync for Accelerometer {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct AccelerometerDataThreshold(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(AccelerometerDataThreshold, windows_core::IUnknown, windows_core::IInspectable); +impl AccelerometerDataThreshold { + pub fn XAxisInGForce(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).XAxisInGForce)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetXAxisInGForce(&self, value: f64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetXAxisInGForce)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn YAxisInGForce(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).YAxisInGForce)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetYAxisInGForce(&self, value: f64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetYAxisInGForce)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ZAxisInGForce(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ZAxisInGForce)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetZAxisInGForce(&self, value: f64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetZAxisInGForce)(windows_core::Interface::as_raw(this), value).ok() } + } +} impl windows_core::RuntimeType for AccelerometerDataThreshold { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7498,6 +22190,50 @@ unsafe impl Sync for AccelerometerDataThreshold {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct AccelerometerReading(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(AccelerometerReading, windows_core::IUnknown, windows_core::IInspectable); +impl AccelerometerReading { + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AccelerationX(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AccelerationX)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AccelerationY(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AccelerationY)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AccelerationZ(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AccelerationZ)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PerformanceCount(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PerformanceCount)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Properties(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for AccelerometerReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7514,6 +22250,15 @@ unsafe impl Sync for AccelerometerReading {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct AccelerometerReadingChangedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(AccelerometerReadingChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl AccelerometerReadingChangedEventArgs { + pub fn Reading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Reading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for AccelerometerReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7544,6 +22289,15 @@ impl windows_core::RuntimeType for AccelerometerReadingType { #[derive(Clone, Debug, Eq, PartialEq)] pub struct AccelerometerShakenEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(AccelerometerShakenEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl AccelerometerShakenEventArgs { + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for AccelerometerShakenEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7561,6 +22315,68 @@ unsafe impl Sync for AccelerometerShakenEventArgs {} pub struct ActivitySensor(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(ActivitySensor, windows_core::IUnknown, windows_core::IInspectable); impl ActivitySensor { + pub fn GetCurrentReadingAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentReadingAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SubscribedActivities(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SubscribedActivities)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PowerInMilliwatts(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PowerInMilliwatts)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DeviceId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SupportedActivities(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedActivities)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MinimumReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinimumReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadingChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveReadingChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn GetDefaultAsync() -> windows_core::Result> { + Self::IActivitySensorStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefaultAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn GetDeviceSelector() -> windows_core::Result { Self::IActivitySensorStatics(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -7573,6 +22389,18 @@ impl ActivitySensor { (windows_core::Interface::vtable(this).FromIdAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn GetSystemHistoryAsync(fromtime: super::super::Foundation::DateTime) -> windows_core::Result>> { + Self::IActivitySensorStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetSystemHistoryAsync)(windows_core::Interface::as_raw(this), fromtime, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetSystemHistoryWithDurationAsync(fromtime: super::super::Foundation::DateTime, duration: super::super::Foundation::TimeSpan) -> windows_core::Result>> { + Self::IActivitySensorStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetSystemHistoryWithDurationAsync)(windows_core::Interface::as_raw(this), fromtime, duration, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IActivitySensorStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -7594,6 +22422,29 @@ unsafe impl Sync for ActivitySensor {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct ActivitySensorReading(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(ActivitySensorReading, windows_core::IUnknown, windows_core::IInspectable); +impl ActivitySensorReading { + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Activity(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Activity)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Confidence(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Confidence)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for ActivitySensorReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7610,6 +22461,15 @@ unsafe impl Sync for ActivitySensorReading {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct ActivitySensorReadingChangedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(ActivitySensorReadingChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl ActivitySensorReadingChangedEventArgs { + pub fn Reading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Reading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for ActivitySensorReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7659,6 +22519,83 @@ impl windows_core::RuntimeType for ActivityType { pub struct Barometer(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(Barometer, windows_core::IUnknown, windows_core::IInspectable); impl Barometer { + pub fn GetCurrentReading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentReading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeviceId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn MinimumReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinimumReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetReportInterval(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetReportInterval)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadingChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveReadingChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn SetReportLatency(&self, value: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetReportLatency)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ReportLatency(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportLatency)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaxBatchSize(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxBatchSize)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReportThreshold(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportThreshold)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetDefault() -> windows_core::Result { + Self::IBarometerStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn FromIdAsync(deviceid: &windows_core::HSTRING) -> windows_core::Result> { Self::IBarometerStatics2(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -7696,6 +22633,19 @@ unsafe impl Sync for Barometer {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct BarometerDataThreshold(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(BarometerDataThreshold, windows_core::IUnknown, windows_core::IInspectable); +impl BarometerDataThreshold { + pub fn Hectopascals(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Hectopascals)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetHectopascals(&self, value: f64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetHectopascals)(windows_core::Interface::as_raw(this), value).ok() } + } +} impl windows_core::RuntimeType for BarometerDataThreshold { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7712,6 +22662,36 @@ unsafe impl Sync for BarometerDataThreshold {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct BarometerReading(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(BarometerReading, windows_core::IUnknown, windows_core::IInspectable); +impl BarometerReading { + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn StationPressureInHectopascals(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StationPressureInHectopascals)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PerformanceCount(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PerformanceCount)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Properties(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for BarometerReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7728,6 +22708,15 @@ unsafe impl Sync for BarometerReading {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct BarometerReadingChangedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(BarometerReadingChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl BarometerReadingChangedEventArgs { + pub fn Reading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Reading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for BarometerReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7745,6 +22734,96 @@ unsafe impl Sync for BarometerReadingChangedEventArgs {} pub struct Compass(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(Compass, windows_core::IUnknown, windows_core::IInspectable); impl Compass { + pub fn GetCurrentReading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentReading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MinimumReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinimumReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetReportInterval(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetReportInterval)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadingChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveReadingChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Graphics_Display")] + pub fn SetReadingTransform(&self, value: super::super::Graphics::Display::DisplayOrientations) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetReadingTransform)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Graphics_Display")] + pub fn ReadingTransform(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingTransform)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetReportLatency(&self, value: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetReportLatency)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ReportLatency(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportLatency)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaxBatchSize(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxBatchSize)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReportThreshold(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportThreshold)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeviceId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetDefault() -> windows_core::Result { + Self::ICompassStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn GetDeviceSelector() -> windows_core::Result { Self::ICompassStatics2(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -7782,6 +22861,19 @@ unsafe impl Sync for Compass {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct CompassDataThreshold(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(CompassDataThreshold, windows_core::IUnknown, windows_core::IInspectable); +impl CompassDataThreshold { + pub fn Degrees(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Degrees)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetDegrees(&self, value: f64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDegrees)(windows_core::Interface::as_raw(this), value).ok() } + } +} impl windows_core::RuntimeType for CompassDataThreshold { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7798,6 +22890,50 @@ unsafe impl Sync for CompassDataThreshold {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct CompassReading(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(CompassReading, windows_core::IUnknown, windows_core::IInspectable); +impl CompassReading { + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn HeadingMagneticNorth(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HeadingMagneticNorth)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn HeadingTrueNorth(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HeadingTrueNorth)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PerformanceCount(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PerformanceCount)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Properties(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn HeadingAccuracy(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HeadingAccuracy)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for CompassReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7814,6 +22950,15 @@ unsafe impl Sync for CompassReading {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct CompassReadingChangedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(CompassReadingChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl CompassReadingChangedEventArgs { + pub fn Reading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Reading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for CompassReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -7830,6 +22975,116 @@ windows_core::imp::define_interface!(IAccelerometer, IAccelerometer_Vtbl, 0xdf18 impl windows_core::RuntimeType for IAccelerometer { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAccelerometer { + const NAME: &'static str = "Windows.Devices.Sensors.IAccelerometer"; +} +pub trait IAccelerometer_Impl: windows_core::IUnknownImpl { + fn GetCurrentReading(&self) -> windows_core::Result; + fn MinimumReportInterval(&self) -> windows_core::Result; + fn SetReportInterval(&self, value: u32) -> windows_core::Result<()>; + fn ReportInterval(&self) -> windows_core::Result; + fn ReadingChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()>; + fn Shaken(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveShaken(&self, token: i64) -> windows_core::Result<()>; +} +impl IAccelerometer_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetCurrentReading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometer_Impl::GetCurrentReading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MinimumReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometer_Impl::MinimumReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetReportInterval(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAccelerometer_Impl::SetReportInterval(this, value).into() + } + } + unsafe extern "system" fn ReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometer_Impl::ReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadingChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometer_Impl::ReadingChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveReadingChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAccelerometer_Impl::RemoveReadingChanged(this, token).into() + } + } + unsafe extern "system" fn Shaken(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometer_Impl::Shaken(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveShaken(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAccelerometer_Impl::RemoveShaken(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetCurrentReading: GetCurrentReading::, + MinimumReportInterval: MinimumReportInterval::, + SetReportInterval: SetReportInterval::, + ReportInterval: ReportInterval::, + ReadingChanged: ReadingChanged::, + RemoveReadingChanged: RemoveReadingChanged::, + Shaken: Shaken::, + RemoveShaken: RemoveShaken::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAccelerometer_Vtbl { @@ -7847,6 +23102,46 @@ windows_core::imp::define_interface!(IAccelerometer2, IAccelerometer2_Vtbl, 0xe8 impl windows_core::RuntimeType for IAccelerometer2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Graphics_Display")] +impl windows_core::RuntimeName for IAccelerometer2 { + const NAME: &'static str = "Windows.Devices.Sensors.IAccelerometer2"; +} +#[cfg(feature = "Graphics_Display")] +pub trait IAccelerometer2_Impl: windows_core::IUnknownImpl { + fn SetReadingTransform(&self, value: super::super::Graphics::Display::DisplayOrientations) -> windows_core::Result<()>; + fn ReadingTransform(&self) -> windows_core::Result; +} +#[cfg(feature = "Graphics_Display")] +impl IAccelerometer2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetReadingTransform(this: *mut core::ffi::c_void, value: super::super::Graphics::Display::DisplayOrientations) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAccelerometer2_Impl::SetReadingTransform(this, value).into() + } + } + unsafe extern "system" fn ReadingTransform(this: *mut core::ffi::c_void, result__: *mut super::super::Graphics::Display::DisplayOrientations) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometer2_Impl::ReadingTransform(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetReadingTransform: SetReadingTransform::, + ReadingTransform: ReadingTransform::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAccelerometer2_Vtbl { @@ -7864,6 +23159,57 @@ windows_core::imp::define_interface!(IAccelerometer3, IAccelerometer3_Vtbl, 0x87 impl windows_core::RuntimeType for IAccelerometer3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAccelerometer3 { + const NAME: &'static str = "Windows.Devices.Sensors.IAccelerometer3"; +} +pub trait IAccelerometer3_Impl: windows_core::IUnknownImpl { + fn SetReportLatency(&self, value: u32) -> windows_core::Result<()>; + fn ReportLatency(&self) -> windows_core::Result; + fn MaxBatchSize(&self) -> windows_core::Result; +} +impl IAccelerometer3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetReportLatency(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAccelerometer3_Impl::SetReportLatency(this, value).into() + } + } + unsafe extern "system" fn ReportLatency(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometer3_Impl::ReportLatency(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxBatchSize(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometer3_Impl::MaxBatchSize(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetReportLatency: SetReportLatency::, + ReportLatency: ReportLatency::, + MaxBatchSize: MaxBatchSize::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAccelerometer3_Vtbl { @@ -7876,6 +23222,32 @@ windows_core::imp::define_interface!(IAccelerometer4, IAccelerometer4_Vtbl, 0x1d impl windows_core::RuntimeType for IAccelerometer4 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAccelerometer4 { + const NAME: &'static str = "Windows.Devices.Sensors.IAccelerometer4"; +} +pub trait IAccelerometer4_Impl: windows_core::IUnknownImpl { + fn ReadingType(&self) -> windows_core::Result; +} +impl IAccelerometer4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ReadingType(this: *mut core::ffi::c_void, result__: *mut AccelerometerReadingType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometer4_Impl::ReadingType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), ReadingType: ReadingType:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAccelerometer4_Vtbl { @@ -7886,6 +23258,33 @@ windows_core::imp::define_interface!(IAccelerometer5, IAccelerometer5_Vtbl, 0x7e impl windows_core::RuntimeType for IAccelerometer5 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAccelerometer5 { + const NAME: &'static str = "Windows.Devices.Sensors.IAccelerometer5"; +} +pub trait IAccelerometer5_Impl: windows_core::IUnknownImpl { + fn ReportThreshold(&self) -> windows_core::Result; +} +impl IAccelerometer5_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ReportThreshold(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometer5_Impl::ReportThreshold(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), ReportThreshold: ReportThreshold:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAccelerometer5_Vtbl { @@ -7896,6 +23295,87 @@ windows_core::imp::define_interface!(IAccelerometerDataThreshold, IAccelerometer impl windows_core::RuntimeType for IAccelerometerDataThreshold { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAccelerometerDataThreshold { + const NAME: &'static str = "Windows.Devices.Sensors.IAccelerometerDataThreshold"; +} +pub trait IAccelerometerDataThreshold_Impl: windows_core::IUnknownImpl { + fn XAxisInGForce(&self) -> windows_core::Result; + fn SetXAxisInGForce(&self, value: f64) -> windows_core::Result<()>; + fn YAxisInGForce(&self) -> windows_core::Result; + fn SetYAxisInGForce(&self, value: f64) -> windows_core::Result<()>; + fn ZAxisInGForce(&self) -> windows_core::Result; + fn SetZAxisInGForce(&self, value: f64) -> windows_core::Result<()>; +} +impl IAccelerometerDataThreshold_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn XAxisInGForce(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerDataThreshold_Impl::XAxisInGForce(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetXAxisInGForce(this: *mut core::ffi::c_void, value: f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAccelerometerDataThreshold_Impl::SetXAxisInGForce(this, value).into() + } + } + unsafe extern "system" fn YAxisInGForce(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerDataThreshold_Impl::YAxisInGForce(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetYAxisInGForce(this: *mut core::ffi::c_void, value: f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAccelerometerDataThreshold_Impl::SetYAxisInGForce(this, value).into() + } + } + unsafe extern "system" fn ZAxisInGForce(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerDataThreshold_Impl::ZAxisInGForce(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetZAxisInGForce(this: *mut core::ffi::c_void, value: f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAccelerometerDataThreshold_Impl::SetZAxisInGForce(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + XAxisInGForce: XAxisInGForce::, + SetXAxisInGForce: SetXAxisInGForce::, + YAxisInGForce: YAxisInGForce::, + SetYAxisInGForce: SetYAxisInGForce::, + ZAxisInGForce: ZAxisInGForce::, + SetZAxisInGForce: SetZAxisInGForce::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAccelerometerDataThreshold_Vtbl { @@ -7911,6 +23391,33 @@ windows_core::imp::define_interface!(IAccelerometerDeviceId, IAccelerometerDevic impl windows_core::RuntimeType for IAccelerometerDeviceId { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAccelerometerDeviceId { + const NAME: &'static str = "Windows.Devices.Sensors.IAccelerometerDeviceId"; +} +pub trait IAccelerometerDeviceId_Impl: windows_core::IUnknownImpl { + fn DeviceId(&self) -> windows_core::Result; +} +impl IAccelerometerDeviceId_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerDeviceId_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), DeviceId: DeviceId:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAccelerometerDeviceId_Vtbl { @@ -7921,6 +23428,77 @@ windows_core::imp::define_interface!(IAccelerometerReading, IAccelerometerReadin impl windows_core::RuntimeType for IAccelerometerReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAccelerometerReading { + const NAME: &'static str = "Windows.Devices.Sensors.IAccelerometerReading"; +} +pub trait IAccelerometerReading_Impl: windows_core::IUnknownImpl { + fn Timestamp(&self) -> windows_core::Result; + fn AccelerationX(&self) -> windows_core::Result; + fn AccelerationY(&self) -> windows_core::Result; + fn AccelerationZ(&self) -> windows_core::Result; +} +impl IAccelerometerReading_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Timestamp(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerReading_Impl::Timestamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AccelerationX(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerReading_Impl::AccelerationX(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AccelerationY(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerReading_Impl::AccelerationY(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AccelerationZ(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerReading_Impl::AccelerationZ(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Timestamp: Timestamp::, + AccelerationX: AccelerationX::, + AccelerationY: AccelerationY::, + AccelerationZ: AccelerationZ::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAccelerometerReading_Vtbl { @@ -7934,6 +23512,51 @@ windows_core::imp::define_interface!(IAccelerometerReading2, IAccelerometerReadi impl windows_core::RuntimeType for IAccelerometerReading2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAccelerometerReading2 { + const NAME: &'static str = "Windows.Devices.Sensors.IAccelerometerReading2"; +} +pub trait IAccelerometerReading2_Impl: windows_core::IUnknownImpl { + fn PerformanceCount(&self) -> windows_core::Result>; + fn Properties(&self) -> windows_core::Result>; +} +impl IAccelerometerReading2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn PerformanceCount(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerReading2_Impl::PerformanceCount(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerReading2_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + PerformanceCount: PerformanceCount::, + Properties: Properties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAccelerometerReading2_Vtbl { @@ -7945,6 +23568,33 @@ windows_core::imp::define_interface!(IAccelerometerReadingChangedEventArgs, IAcc impl windows_core::RuntimeType for IAccelerometerReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAccelerometerReadingChangedEventArgs { + const NAME: &'static str = "Windows.Devices.Sensors.IAccelerometerReadingChangedEventArgs"; +} +pub trait IAccelerometerReadingChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn Reading(&self) -> windows_core::Result; +} +impl IAccelerometerReadingChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Reading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerReadingChangedEventArgs_Impl::Reading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Reading: Reading:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAccelerometerReadingChangedEventArgs_Vtbl { @@ -7955,6 +23605,32 @@ windows_core::imp::define_interface!(IAccelerometerShakenEventArgs, IAcceleromet impl windows_core::RuntimeType for IAccelerometerShakenEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAccelerometerShakenEventArgs { + const NAME: &'static str = "Windows.Devices.Sensors.IAccelerometerShakenEventArgs"; +} +pub trait IAccelerometerShakenEventArgs_Impl: windows_core::IUnknownImpl { + fn Timestamp(&self) -> windows_core::Result; +} +impl IAccelerometerShakenEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Timestamp(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerShakenEventArgs_Impl::Timestamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Timestamp: Timestamp:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAccelerometerShakenEventArgs_Vtbl { @@ -7965,6 +23641,33 @@ windows_core::imp::define_interface!(IAccelerometerStatics, IAccelerometerStatic impl windows_core::RuntimeType for IAccelerometerStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAccelerometerStatics { + const NAME: &'static str = "Windows.Devices.Sensors.IAccelerometerStatics"; +} +pub trait IAccelerometerStatics_Impl: windows_core::IUnknownImpl { + fn GetDefault(&self) -> windows_core::Result; +} +impl IAccelerometerStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDefault(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerStatics_Impl::GetDefault(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), GetDefault: GetDefault:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAccelerometerStatics_Vtbl { @@ -7975,6 +23678,36 @@ windows_core::imp::define_interface!(IAccelerometerStatics2, IAccelerometerStati impl windows_core::RuntimeType for IAccelerometerStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAccelerometerStatics2 { + const NAME: &'static str = "Windows.Devices.Sensors.IAccelerometerStatics2"; +} +pub trait IAccelerometerStatics2_Impl: windows_core::IUnknownImpl { + fn GetDefaultWithAccelerometerReadingType(&self, readingType: AccelerometerReadingType) -> windows_core::Result; +} +impl IAccelerometerStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDefaultWithAccelerometerReadingType(this: *mut core::ffi::c_void, readingtype: AccelerometerReadingType, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerStatics2_Impl::GetDefaultWithAccelerometerReadingType(this, readingtype) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDefaultWithAccelerometerReadingType: GetDefaultWithAccelerometerReadingType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAccelerometerStatics2_Vtbl { @@ -7985,6 +23718,51 @@ windows_core::imp::define_interface!(IAccelerometerStatics3, IAccelerometerStati impl windows_core::RuntimeType for IAccelerometerStatics3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IAccelerometerStatics3 { + const NAME: &'static str = "Windows.Devices.Sensors.IAccelerometerStatics3"; +} +pub trait IAccelerometerStatics3_Impl: windows_core::IUnknownImpl { + fn FromIdAsync(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; + fn GetDeviceSelector(&self, readingType: AccelerometerReadingType) -> windows_core::Result; +} +impl IAccelerometerStatics3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FromIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerStatics3_Impl::FromIdAsync(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelector(this: *mut core::ffi::c_void, readingtype: AccelerometerReadingType, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAccelerometerStatics3_Impl::GetDeviceSelector(this, readingtype) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FromIdAsync: FromIdAsync::, + GetDeviceSelector: GetDeviceSelector::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAccelerometerStatics3_Vtbl { @@ -7996,6 +23774,131 @@ windows_core::imp::define_interface!(IActivitySensor, IActivitySensor_Vtbl, 0xcd impl windows_core::RuntimeType for IActivitySensor { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IActivitySensor { + const NAME: &'static str = "Windows.Devices.Sensors.IActivitySensor"; +} +pub trait IActivitySensor_Impl: windows_core::IUnknownImpl { + fn GetCurrentReadingAsync(&self) -> windows_core::Result>; + fn SubscribedActivities(&self) -> windows_core::Result>; + fn PowerInMilliwatts(&self) -> windows_core::Result; + fn DeviceId(&self) -> windows_core::Result; + fn SupportedActivities(&self) -> windows_core::Result>; + fn MinimumReportInterval(&self) -> windows_core::Result; + fn ReadingChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()>; +} +impl IActivitySensor_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetCurrentReadingAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensor_Impl::GetCurrentReadingAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SubscribedActivities(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensor_Impl::SubscribedActivities(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PowerInMilliwatts(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensor_Impl::PowerInMilliwatts(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensor_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedActivities(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensor_Impl::SupportedActivities(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MinimumReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensor_Impl::MinimumReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadingChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensor_Impl::ReadingChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveReadingChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IActivitySensor_Impl::RemoveReadingChanged(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetCurrentReadingAsync: GetCurrentReadingAsync::, + SubscribedActivities: SubscribedActivities::, + PowerInMilliwatts: PowerInMilliwatts::, + DeviceId: DeviceId::, + SupportedActivities: SupportedActivities::, + MinimumReportInterval: MinimumReportInterval::, + ReadingChanged: ReadingChanged::, + RemoveReadingChanged: RemoveReadingChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IActivitySensor_Vtbl { @@ -8013,6 +23916,63 @@ windows_core::imp::define_interface!(IActivitySensorReading, IActivitySensorRead impl windows_core::RuntimeType for IActivitySensorReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IActivitySensorReading { + const NAME: &'static str = "Windows.Devices.Sensors.IActivitySensorReading"; +} +pub trait IActivitySensorReading_Impl: windows_core::IUnknownImpl { + fn Timestamp(&self) -> windows_core::Result; + fn Activity(&self) -> windows_core::Result; + fn Confidence(&self) -> windows_core::Result; +} +impl IActivitySensorReading_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Timestamp(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensorReading_Impl::Timestamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Activity(this: *mut core::ffi::c_void, result__: *mut ActivityType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensorReading_Impl::Activity(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Confidence(this: *mut core::ffi::c_void, result__: *mut ActivitySensorReadingConfidence) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensorReading_Impl::Confidence(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Timestamp: Timestamp::, + Activity: Activity::, + Confidence: Confidence::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IActivitySensorReading_Vtbl { @@ -8025,6 +23985,33 @@ windows_core::imp::define_interface!(IActivitySensorReadingChangedEventArgs, IAc impl windows_core::RuntimeType for IActivitySensorReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IActivitySensorReadingChangedEventArgs { + const NAME: &'static str = "Windows.Devices.Sensors.IActivitySensorReadingChangedEventArgs"; +} +pub trait IActivitySensorReadingChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn Reading(&self) -> windows_core::Result; +} +impl IActivitySensorReadingChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Reading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensorReadingChangedEventArgs_Impl::Reading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Reading: Reading:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IActivitySensorReadingChangedEventArgs_Vtbl { @@ -8035,6 +24022,96 @@ windows_core::imp::define_interface!(IActivitySensorStatics, IActivitySensorStat impl windows_core::RuntimeType for IActivitySensorStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IActivitySensorStatics { + const NAME: &'static str = "Windows.Devices.Sensors.IActivitySensorStatics"; +} +pub trait IActivitySensorStatics_Impl: windows_core::IUnknownImpl { + fn GetDefaultAsync(&self) -> windows_core::Result>; + fn GetDeviceSelector(&self) -> windows_core::Result; + fn FromIdAsync(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; + fn GetSystemHistoryAsync(&self, fromTime: &super::super::Foundation::DateTime) -> windows_core::Result>>; + fn GetSystemHistoryWithDurationAsync(&self, fromTime: &super::super::Foundation::DateTime, duration: &super::super::Foundation::TimeSpan) -> windows_core::Result>>; +} +impl IActivitySensorStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDefaultAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensorStatics_Impl::GetDefaultAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelector(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensorStatics_Impl::GetDeviceSelector(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FromIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensorStatics_Impl::FromIdAsync(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetSystemHistoryAsync(this: *mut core::ffi::c_void, fromtime: super::super::Foundation::DateTime, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensorStatics_Impl::GetSystemHistoryAsync(this, core::mem::transmute(&fromtime)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetSystemHistoryWithDurationAsync(this: *mut core::ffi::c_void, fromtime: super::super::Foundation::DateTime, duration: super::super::Foundation::TimeSpan, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IActivitySensorStatics_Impl::GetSystemHistoryWithDurationAsync(this, core::mem::transmute(&fromtime), core::mem::transmute(&duration)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDefaultAsync: GetDefaultAsync::, + GetDeviceSelector: GetDeviceSelector::, + FromIdAsync: FromIdAsync::, + GetSystemHistoryAsync: GetSystemHistoryAsync::, + GetSystemHistoryWithDurationAsync: GetSystemHistoryWithDurationAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IActivitySensorStatics_Vtbl { @@ -8049,6 +24126,109 @@ windows_core::imp::define_interface!(IBarometer, IBarometer_Vtbl, 0x934475a8_78b impl windows_core::RuntimeType for IBarometer { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBarometer { + const NAME: &'static str = "Windows.Devices.Sensors.IBarometer"; +} +pub trait IBarometer_Impl: windows_core::IUnknownImpl { + fn GetCurrentReading(&self) -> windows_core::Result; + fn DeviceId(&self) -> windows_core::Result; + fn MinimumReportInterval(&self) -> windows_core::Result; + fn SetReportInterval(&self, value: u32) -> windows_core::Result<()>; + fn ReportInterval(&self) -> windows_core::Result; + fn ReadingChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()>; +} +impl IBarometer_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetCurrentReading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometer_Impl::GetCurrentReading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometer_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MinimumReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometer_Impl::MinimumReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetReportInterval(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBarometer_Impl::SetReportInterval(this, value).into() + } + } + unsafe extern "system" fn ReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometer_Impl::ReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadingChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometer_Impl::ReadingChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveReadingChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBarometer_Impl::RemoveReadingChanged(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetCurrentReading: GetCurrentReading::, + DeviceId: DeviceId::, + MinimumReportInterval: MinimumReportInterval::, + SetReportInterval: SetReportInterval::, + ReportInterval: ReportInterval::, + ReadingChanged: ReadingChanged::, + RemoveReadingChanged: RemoveReadingChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBarometer_Vtbl { @@ -8065,6 +24245,57 @@ windows_core::imp::define_interface!(IBarometer2, IBarometer2_Vtbl, 0x32bcc418_3 impl windows_core::RuntimeType for IBarometer2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBarometer2 { + const NAME: &'static str = "Windows.Devices.Sensors.IBarometer2"; +} +pub trait IBarometer2_Impl: windows_core::IUnknownImpl { + fn SetReportLatency(&self, value: u32) -> windows_core::Result<()>; + fn ReportLatency(&self) -> windows_core::Result; + fn MaxBatchSize(&self) -> windows_core::Result; +} +impl IBarometer2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetReportLatency(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBarometer2_Impl::SetReportLatency(this, value).into() + } + } + unsafe extern "system" fn ReportLatency(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometer2_Impl::ReportLatency(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxBatchSize(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometer2_Impl::MaxBatchSize(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetReportLatency: SetReportLatency::, + ReportLatency: ReportLatency::, + MaxBatchSize: MaxBatchSize::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBarometer2_Vtbl { @@ -8077,6 +24308,33 @@ windows_core::imp::define_interface!(IBarometer3, IBarometer3_Vtbl, 0x0e35f0ea_0 impl windows_core::RuntimeType for IBarometer3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBarometer3 { + const NAME: &'static str = "Windows.Devices.Sensors.IBarometer3"; +} +pub trait IBarometer3_Impl: windows_core::IUnknownImpl { + fn ReportThreshold(&self) -> windows_core::Result; +} +impl IBarometer3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ReportThreshold(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometer3_Impl::ReportThreshold(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), ReportThreshold: ReportThreshold:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBarometer3_Vtbl { @@ -8087,6 +24345,43 @@ windows_core::imp::define_interface!(IBarometerDataThreshold, IBarometerDataThre impl windows_core::RuntimeType for IBarometerDataThreshold { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBarometerDataThreshold { + const NAME: &'static str = "Windows.Devices.Sensors.IBarometerDataThreshold"; +} +pub trait IBarometerDataThreshold_Impl: windows_core::IUnknownImpl { + fn Hectopascals(&self) -> windows_core::Result; + fn SetHectopascals(&self, value: f64) -> windows_core::Result<()>; +} +impl IBarometerDataThreshold_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Hectopascals(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometerDataThreshold_Impl::Hectopascals(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetHectopascals(this: *mut core::ffi::c_void, value: f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBarometerDataThreshold_Impl::SetHectopascals(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Hectopascals: Hectopascals::, + SetHectopascals: SetHectopascals::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBarometerDataThreshold_Vtbl { @@ -8098,6 +24393,49 @@ windows_core::imp::define_interface!(IBarometerReading, IBarometerReading_Vtbl, impl windows_core::RuntimeType for IBarometerReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBarometerReading { + const NAME: &'static str = "Windows.Devices.Sensors.IBarometerReading"; +} +pub trait IBarometerReading_Impl: windows_core::IUnknownImpl { + fn Timestamp(&self) -> windows_core::Result; + fn StationPressureInHectopascals(&self) -> windows_core::Result; +} +impl IBarometerReading_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Timestamp(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometerReading_Impl::Timestamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StationPressureInHectopascals(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometerReading_Impl::StationPressureInHectopascals(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Timestamp: Timestamp::, + StationPressureInHectopascals: StationPressureInHectopascals::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBarometerReading_Vtbl { @@ -8109,6 +24447,51 @@ windows_core::imp::define_interface!(IBarometerReading2, IBarometerReading2_Vtbl impl windows_core::RuntimeType for IBarometerReading2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBarometerReading2 { + const NAME: &'static str = "Windows.Devices.Sensors.IBarometerReading2"; +} +pub trait IBarometerReading2_Impl: windows_core::IUnknownImpl { + fn PerformanceCount(&self) -> windows_core::Result>; + fn Properties(&self) -> windows_core::Result>; +} +impl IBarometerReading2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn PerformanceCount(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometerReading2_Impl::PerformanceCount(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometerReading2_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + PerformanceCount: PerformanceCount::, + Properties: Properties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBarometerReading2_Vtbl { @@ -8120,6 +24503,33 @@ windows_core::imp::define_interface!(IBarometerReadingChangedEventArgs, IBaromet impl windows_core::RuntimeType for IBarometerReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBarometerReadingChangedEventArgs { + const NAME: &'static str = "Windows.Devices.Sensors.IBarometerReadingChangedEventArgs"; +} +pub trait IBarometerReadingChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn Reading(&self) -> windows_core::Result; +} +impl IBarometerReadingChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Reading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometerReadingChangedEventArgs_Impl::Reading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Reading: Reading:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBarometerReadingChangedEventArgs_Vtbl { @@ -8130,6 +24540,33 @@ windows_core::imp::define_interface!(IBarometerStatics, IBarometerStatics_Vtbl, impl windows_core::RuntimeType for IBarometerStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBarometerStatics { + const NAME: &'static str = "Windows.Devices.Sensors.IBarometerStatics"; +} +pub trait IBarometerStatics_Impl: windows_core::IUnknownImpl { + fn GetDefault(&self) -> windows_core::Result; +} +impl IBarometerStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDefault(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometerStatics_Impl::GetDefault(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), GetDefault: GetDefault:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBarometerStatics_Vtbl { @@ -8140,6 +24577,51 @@ windows_core::imp::define_interface!(IBarometerStatics2, IBarometerStatics2_Vtbl impl windows_core::RuntimeType for IBarometerStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBarometerStatics2 { + const NAME: &'static str = "Windows.Devices.Sensors.IBarometerStatics2"; +} +pub trait IBarometerStatics2_Impl: windows_core::IUnknownImpl { + fn FromIdAsync(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; + fn GetDeviceSelector(&self) -> windows_core::Result; +} +impl IBarometerStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FromIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometerStatics2_Impl::FromIdAsync(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelector(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBarometerStatics2_Impl::GetDeviceSelector(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FromIdAsync: FromIdAsync::, + GetDeviceSelector: GetDeviceSelector::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBarometerStatics2_Vtbl { @@ -8151,6 +24633,94 @@ windows_core::imp::define_interface!(ICompass, ICompass_Vtbl, 0x292ffa94_1b45_40 impl windows_core::RuntimeType for ICompass { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICompass { + const NAME: &'static str = "Windows.Devices.Sensors.ICompass"; +} +pub trait ICompass_Impl: windows_core::IUnknownImpl { + fn GetCurrentReading(&self) -> windows_core::Result; + fn MinimumReportInterval(&self) -> windows_core::Result; + fn SetReportInterval(&self, value: u32) -> windows_core::Result<()>; + fn ReportInterval(&self) -> windows_core::Result; + fn ReadingChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()>; +} +impl ICompass_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetCurrentReading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompass_Impl::GetCurrentReading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MinimumReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompass_Impl::MinimumReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetReportInterval(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICompass_Impl::SetReportInterval(this, value).into() + } + } + unsafe extern "system" fn ReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompass_Impl::ReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadingChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompass_Impl::ReadingChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveReadingChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICompass_Impl::RemoveReadingChanged(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetCurrentReading: GetCurrentReading::, + MinimumReportInterval: MinimumReportInterval::, + SetReportInterval: SetReportInterval::, + ReportInterval: ReportInterval::, + ReadingChanged: ReadingChanged::, + RemoveReadingChanged: RemoveReadingChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICompass_Vtbl { @@ -8166,6 +24736,46 @@ windows_core::imp::define_interface!(ICompass2, ICompass2_Vtbl, 0x36f26d09_c7d7_ impl windows_core::RuntimeType for ICompass2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Graphics_Display")] +impl windows_core::RuntimeName for ICompass2 { + const NAME: &'static str = "Windows.Devices.Sensors.ICompass2"; +} +#[cfg(feature = "Graphics_Display")] +pub trait ICompass2_Impl: windows_core::IUnknownImpl { + fn SetReadingTransform(&self, value: super::super::Graphics::Display::DisplayOrientations) -> windows_core::Result<()>; + fn ReadingTransform(&self) -> windows_core::Result; +} +#[cfg(feature = "Graphics_Display")] +impl ICompass2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetReadingTransform(this: *mut core::ffi::c_void, value: super::super::Graphics::Display::DisplayOrientations) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICompass2_Impl::SetReadingTransform(this, value).into() + } + } + unsafe extern "system" fn ReadingTransform(this: *mut core::ffi::c_void, result__: *mut super::super::Graphics::Display::DisplayOrientations) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompass2_Impl::ReadingTransform(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetReadingTransform: SetReadingTransform::, + ReadingTransform: ReadingTransform::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICompass2_Vtbl { @@ -8183,6 +24793,57 @@ windows_core::imp::define_interface!(ICompass3, ICompass3_Vtbl, 0xa424801b_c5ea_ impl windows_core::RuntimeType for ICompass3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICompass3 { + const NAME: &'static str = "Windows.Devices.Sensors.ICompass3"; +} +pub trait ICompass3_Impl: windows_core::IUnknownImpl { + fn SetReportLatency(&self, value: u32) -> windows_core::Result<()>; + fn ReportLatency(&self) -> windows_core::Result; + fn MaxBatchSize(&self) -> windows_core::Result; +} +impl ICompass3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetReportLatency(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICompass3_Impl::SetReportLatency(this, value).into() + } + } + unsafe extern "system" fn ReportLatency(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompass3_Impl::ReportLatency(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxBatchSize(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompass3_Impl::MaxBatchSize(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetReportLatency: SetReportLatency::, + ReportLatency: ReportLatency::, + MaxBatchSize: MaxBatchSize::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICompass3_Vtbl { @@ -8195,6 +24856,33 @@ windows_core::imp::define_interface!(ICompass4, ICompass4_Vtbl, 0x291e7f11_ec32_ impl windows_core::RuntimeType for ICompass4 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICompass4 { + const NAME: &'static str = "Windows.Devices.Sensors.ICompass4"; +} +pub trait ICompass4_Impl: windows_core::IUnknownImpl { + fn ReportThreshold(&self) -> windows_core::Result; +} +impl ICompass4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ReportThreshold(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompass4_Impl::ReportThreshold(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), ReportThreshold: ReportThreshold:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICompass4_Vtbl { @@ -8205,6 +24893,43 @@ windows_core::imp::define_interface!(ICompassDataThreshold, ICompassDataThreshol impl windows_core::RuntimeType for ICompassDataThreshold { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICompassDataThreshold { + const NAME: &'static str = "Windows.Devices.Sensors.ICompassDataThreshold"; +} +pub trait ICompassDataThreshold_Impl: windows_core::IUnknownImpl { + fn Degrees(&self) -> windows_core::Result; + fn SetDegrees(&self, value: f64) -> windows_core::Result<()>; +} +impl ICompassDataThreshold_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Degrees(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompassDataThreshold_Impl::Degrees(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDegrees(this: *mut core::ffi::c_void, value: f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICompassDataThreshold_Impl::SetDegrees(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Degrees: Degrees::, + SetDegrees: SetDegrees::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICompassDataThreshold_Vtbl { @@ -8216,6 +24941,33 @@ windows_core::imp::define_interface!(ICompassDeviceId, ICompassDeviceId_Vtbl, 0x impl windows_core::RuntimeType for ICompassDeviceId { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICompassDeviceId { + const NAME: &'static str = "Windows.Devices.Sensors.ICompassDeviceId"; +} +pub trait ICompassDeviceId_Impl: windows_core::IUnknownImpl { + fn DeviceId(&self) -> windows_core::Result; +} +impl ICompassDeviceId_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompassDeviceId_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), DeviceId: DeviceId:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICompassDeviceId_Vtbl { @@ -8226,6 +24978,64 @@ windows_core::imp::define_interface!(ICompassReading, ICompassReading_Vtbl, 0x82 impl windows_core::RuntimeType for ICompassReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICompassReading { + const NAME: &'static str = "Windows.Devices.Sensors.ICompassReading"; +} +pub trait ICompassReading_Impl: windows_core::IUnknownImpl { + fn Timestamp(&self) -> windows_core::Result; + fn HeadingMagneticNorth(&self) -> windows_core::Result; + fn HeadingTrueNorth(&self) -> windows_core::Result>; +} +impl ICompassReading_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Timestamp(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompassReading_Impl::Timestamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn HeadingMagneticNorth(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompassReading_Impl::HeadingMagneticNorth(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn HeadingTrueNorth(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompassReading_Impl::HeadingTrueNorth(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Timestamp: Timestamp::, + HeadingMagneticNorth: HeadingMagneticNorth::, + HeadingTrueNorth: HeadingTrueNorth::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICompassReading_Vtbl { @@ -8238,6 +25048,51 @@ windows_core::imp::define_interface!(ICompassReading2, ICompassReading2_Vtbl, 0x impl windows_core::RuntimeType for ICompassReading2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICompassReading2 { + const NAME: &'static str = "Windows.Devices.Sensors.ICompassReading2"; +} +pub trait ICompassReading2_Impl: windows_core::IUnknownImpl { + fn PerformanceCount(&self) -> windows_core::Result>; + fn Properties(&self) -> windows_core::Result>; +} +impl ICompassReading2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn PerformanceCount(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompassReading2_Impl::PerformanceCount(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompassReading2_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + PerformanceCount: PerformanceCount::, + Properties: Properties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICompassReading2_Vtbl { @@ -8249,6 +25104,33 @@ windows_core::imp::define_interface!(ICompassReadingChangedEventArgs, ICompassRe impl windows_core::RuntimeType for ICompassReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICompassReadingChangedEventArgs { + const NAME: &'static str = "Windows.Devices.Sensors.ICompassReadingChangedEventArgs"; +} +pub trait ICompassReadingChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn Reading(&self) -> windows_core::Result; +} +impl ICompassReadingChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Reading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompassReadingChangedEventArgs_Impl::Reading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Reading: Reading:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICompassReadingChangedEventArgs_Vtbl { @@ -8259,6 +25141,35 @@ windows_core::imp::define_interface!(ICompassReadingHeadingAccuracy, ICompassRea impl windows_core::RuntimeType for ICompassReadingHeadingAccuracy { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICompassReadingHeadingAccuracy { + const NAME: &'static str = "Windows.Devices.Sensors.ICompassReadingHeadingAccuracy"; +} +pub trait ICompassReadingHeadingAccuracy_Impl: windows_core::IUnknownImpl { + fn HeadingAccuracy(&self) -> windows_core::Result; +} +impl ICompassReadingHeadingAccuracy_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn HeadingAccuracy(this: *mut core::ffi::c_void, result__: *mut MagnetometerAccuracy) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompassReadingHeadingAccuracy_Impl::HeadingAccuracy(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + HeadingAccuracy: HeadingAccuracy::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICompassReadingHeadingAccuracy_Vtbl { @@ -8269,6 +25180,33 @@ windows_core::imp::define_interface!(ICompassStatics, ICompassStatics_Vtbl, 0x9a impl windows_core::RuntimeType for ICompassStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICompassStatics { + const NAME: &'static str = "Windows.Devices.Sensors.ICompassStatics"; +} +pub trait ICompassStatics_Impl: windows_core::IUnknownImpl { + fn GetDefault(&self) -> windows_core::Result; +} +impl ICompassStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDefault(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompassStatics_Impl::GetDefault(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), GetDefault: GetDefault:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICompassStatics_Vtbl { @@ -8279,6 +25217,51 @@ windows_core::imp::define_interface!(ICompassStatics2, ICompassStatics2_Vtbl, 0x impl windows_core::RuntimeType for ICompassStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICompassStatics2 { + const NAME: &'static str = "Windows.Devices.Sensors.ICompassStatics2"; +} +pub trait ICompassStatics2_Impl: windows_core::IUnknownImpl { + fn GetDeviceSelector(&self) -> windows_core::Result; + fn FromIdAsync(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; +} +impl ICompassStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDeviceSelector(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompassStatics2_Impl::GetDeviceSelector(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FromIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICompassStatics2_Impl::FromIdAsync(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDeviceSelector: GetDeviceSelector::, + FromIdAsync: FromIdAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICompassStatics2_Vtbl { @@ -8290,6 +25273,94 @@ windows_core::imp::define_interface!(IInclinometer, IInclinometer_Vtbl, 0x2648ca impl windows_core::RuntimeType for IInclinometer { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IInclinometer { + const NAME: &'static str = "Windows.Devices.Sensors.IInclinometer"; +} +pub trait IInclinometer_Impl: windows_core::IUnknownImpl { + fn GetCurrentReading(&self) -> windows_core::Result; + fn MinimumReportInterval(&self) -> windows_core::Result; + fn SetReportInterval(&self, value: u32) -> windows_core::Result<()>; + fn ReportInterval(&self) -> windows_core::Result; + fn ReadingChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()>; +} +impl IInclinometer_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetCurrentReading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometer_Impl::GetCurrentReading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MinimumReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometer_Impl::MinimumReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetReportInterval(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IInclinometer_Impl::SetReportInterval(this, value).into() + } + } + unsafe extern "system" fn ReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometer_Impl::ReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadingChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometer_Impl::ReadingChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveReadingChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IInclinometer_Impl::RemoveReadingChanged(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetCurrentReading: GetCurrentReading::, + MinimumReportInterval: MinimumReportInterval::, + SetReportInterval: SetReportInterval::, + ReportInterval: ReportInterval::, + ReadingChanged: ReadingChanged::, + RemoveReadingChanged: RemoveReadingChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IInclinometer_Vtbl { @@ -8305,6 +25376,60 @@ windows_core::imp::define_interface!(IInclinometer2, IInclinometer2_Vtbl, 0x029f impl windows_core::RuntimeType for IInclinometer2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Graphics_Display")] +impl windows_core::RuntimeName for IInclinometer2 { + const NAME: &'static str = "Windows.Devices.Sensors.IInclinometer2"; +} +#[cfg(feature = "Graphics_Display")] +pub trait IInclinometer2_Impl: windows_core::IUnknownImpl { + fn SetReadingTransform(&self, value: super::super::Graphics::Display::DisplayOrientations) -> windows_core::Result<()>; + fn ReadingTransform(&self) -> windows_core::Result; + fn ReadingType(&self) -> windows_core::Result; +} +#[cfg(feature = "Graphics_Display")] +impl IInclinometer2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetReadingTransform(this: *mut core::ffi::c_void, value: super::super::Graphics::Display::DisplayOrientations) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IInclinometer2_Impl::SetReadingTransform(this, value).into() + } + } + unsafe extern "system" fn ReadingTransform(this: *mut core::ffi::c_void, result__: *mut super::super::Graphics::Display::DisplayOrientations) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometer2_Impl::ReadingTransform(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadingType(this: *mut core::ffi::c_void, result__: *mut SensorReadingType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometer2_Impl::ReadingType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetReadingTransform: SetReadingTransform::, + ReadingTransform: ReadingTransform::, + ReadingType: ReadingType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IInclinometer2_Vtbl { @@ -8323,6 +25448,57 @@ windows_core::imp::define_interface!(IInclinometer3, IInclinometer3_Vtbl, 0x3a09 impl windows_core::RuntimeType for IInclinometer3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IInclinometer3 { + const NAME: &'static str = "Windows.Devices.Sensors.IInclinometer3"; +} +pub trait IInclinometer3_Impl: windows_core::IUnknownImpl { + fn SetReportLatency(&self, value: u32) -> windows_core::Result<()>; + fn ReportLatency(&self) -> windows_core::Result; + fn MaxBatchSize(&self) -> windows_core::Result; +} +impl IInclinometer3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetReportLatency(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IInclinometer3_Impl::SetReportLatency(this, value).into() + } + } + unsafe extern "system" fn ReportLatency(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometer3_Impl::ReportLatency(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxBatchSize(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometer3_Impl::MaxBatchSize(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetReportLatency: SetReportLatency::, + ReportLatency: ReportLatency::, + MaxBatchSize: MaxBatchSize::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IInclinometer3_Vtbl { @@ -8335,6 +25511,33 @@ windows_core::imp::define_interface!(IInclinometer4, IInclinometer4_Vtbl, 0x4385 impl windows_core::RuntimeType for IInclinometer4 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IInclinometer4 { + const NAME: &'static str = "Windows.Devices.Sensors.IInclinometer4"; +} +pub trait IInclinometer4_Impl: windows_core::IUnknownImpl { + fn ReportThreshold(&self) -> windows_core::Result; +} +impl IInclinometer4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ReportThreshold(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometer4_Impl::ReportThreshold(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), ReportThreshold: ReportThreshold:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IInclinometer4_Vtbl { @@ -8345,6 +25548,87 @@ windows_core::imp::define_interface!(IInclinometerDataThreshold, IInclinometerDa impl windows_core::RuntimeType for IInclinometerDataThreshold { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IInclinometerDataThreshold { + const NAME: &'static str = "Windows.Devices.Sensors.IInclinometerDataThreshold"; +} +pub trait IInclinometerDataThreshold_Impl: windows_core::IUnknownImpl { + fn PitchInDegrees(&self) -> windows_core::Result; + fn SetPitchInDegrees(&self, value: f32) -> windows_core::Result<()>; + fn RollInDegrees(&self) -> windows_core::Result; + fn SetRollInDegrees(&self, value: f32) -> windows_core::Result<()>; + fn YawInDegrees(&self) -> windows_core::Result; + fn SetYawInDegrees(&self, value: f32) -> windows_core::Result<()>; +} +impl IInclinometerDataThreshold_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn PitchInDegrees(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerDataThreshold_Impl::PitchInDegrees(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPitchInDegrees(this: *mut core::ffi::c_void, value: f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IInclinometerDataThreshold_Impl::SetPitchInDegrees(this, value).into() + } + } + unsafe extern "system" fn RollInDegrees(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerDataThreshold_Impl::RollInDegrees(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRollInDegrees(this: *mut core::ffi::c_void, value: f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IInclinometerDataThreshold_Impl::SetRollInDegrees(this, value).into() + } + } + unsafe extern "system" fn YawInDegrees(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerDataThreshold_Impl::YawInDegrees(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetYawInDegrees(this: *mut core::ffi::c_void, value: f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IInclinometerDataThreshold_Impl::SetYawInDegrees(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + PitchInDegrees: PitchInDegrees::, + SetPitchInDegrees: SetPitchInDegrees::, + RollInDegrees: RollInDegrees::, + SetRollInDegrees: SetRollInDegrees::, + YawInDegrees: YawInDegrees::, + SetYawInDegrees: SetYawInDegrees::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IInclinometerDataThreshold_Vtbl { @@ -8360,6 +25644,33 @@ windows_core::imp::define_interface!(IInclinometerDeviceId, IInclinometerDeviceI impl windows_core::RuntimeType for IInclinometerDeviceId { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IInclinometerDeviceId { + const NAME: &'static str = "Windows.Devices.Sensors.IInclinometerDeviceId"; +} +pub trait IInclinometerDeviceId_Impl: windows_core::IUnknownImpl { + fn DeviceId(&self) -> windows_core::Result; +} +impl IInclinometerDeviceId_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerDeviceId_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), DeviceId: DeviceId:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IInclinometerDeviceId_Vtbl { @@ -8370,6 +25681,77 @@ windows_core::imp::define_interface!(IInclinometerReading, IInclinometerReading_ impl windows_core::RuntimeType for IInclinometerReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IInclinometerReading { + const NAME: &'static str = "Windows.Devices.Sensors.IInclinometerReading"; +} +pub trait IInclinometerReading_Impl: windows_core::IUnknownImpl { + fn Timestamp(&self) -> windows_core::Result; + fn PitchDegrees(&self) -> windows_core::Result; + fn RollDegrees(&self) -> windows_core::Result; + fn YawDegrees(&self) -> windows_core::Result; +} +impl IInclinometerReading_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Timestamp(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerReading_Impl::Timestamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PitchDegrees(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerReading_Impl::PitchDegrees(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RollDegrees(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerReading_Impl::RollDegrees(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn YawDegrees(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerReading_Impl::YawDegrees(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Timestamp: Timestamp::, + PitchDegrees: PitchDegrees::, + RollDegrees: RollDegrees::, + YawDegrees: YawDegrees::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IInclinometerReading_Vtbl { @@ -8383,6 +25765,51 @@ windows_core::imp::define_interface!(IInclinometerReading2, IInclinometerReading impl windows_core::RuntimeType for IInclinometerReading2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IInclinometerReading2 { + const NAME: &'static str = "Windows.Devices.Sensors.IInclinometerReading2"; +} +pub trait IInclinometerReading2_Impl: windows_core::IUnknownImpl { + fn PerformanceCount(&self) -> windows_core::Result>; + fn Properties(&self) -> windows_core::Result>; +} +impl IInclinometerReading2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn PerformanceCount(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerReading2_Impl::PerformanceCount(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerReading2_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + PerformanceCount: PerformanceCount::, + Properties: Properties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IInclinometerReading2_Vtbl { @@ -8394,6 +25821,33 @@ windows_core::imp::define_interface!(IInclinometerReadingChangedEventArgs, IIncl impl windows_core::RuntimeType for IInclinometerReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IInclinometerReadingChangedEventArgs { + const NAME: &'static str = "Windows.Devices.Sensors.IInclinometerReadingChangedEventArgs"; +} +pub trait IInclinometerReadingChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn Reading(&self) -> windows_core::Result; +} +impl IInclinometerReadingChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Reading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerReadingChangedEventArgs_Impl::Reading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Reading: Reading:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IInclinometerReadingChangedEventArgs_Vtbl { @@ -8404,6 +25858,35 @@ windows_core::imp::define_interface!(IInclinometerReadingYawAccuracy, IInclinome impl windows_core::RuntimeType for IInclinometerReadingYawAccuracy { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IInclinometerReadingYawAccuracy { + const NAME: &'static str = "Windows.Devices.Sensors.IInclinometerReadingYawAccuracy"; +} +pub trait IInclinometerReadingYawAccuracy_Impl: windows_core::IUnknownImpl { + fn YawAccuracy(&self) -> windows_core::Result; +} +impl IInclinometerReadingYawAccuracy_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn YawAccuracy(this: *mut core::ffi::c_void, result__: *mut MagnetometerAccuracy) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerReadingYawAccuracy_Impl::YawAccuracy(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + YawAccuracy: YawAccuracy::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IInclinometerReadingYawAccuracy_Vtbl { @@ -8414,6 +25897,33 @@ windows_core::imp::define_interface!(IInclinometerStatics, IInclinometerStatics_ impl windows_core::RuntimeType for IInclinometerStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IInclinometerStatics { + const NAME: &'static str = "Windows.Devices.Sensors.IInclinometerStatics"; +} +pub trait IInclinometerStatics_Impl: windows_core::IUnknownImpl { + fn GetDefault(&self) -> windows_core::Result; +} +impl IInclinometerStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDefault(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerStatics_Impl::GetDefault(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), GetDefault: GetDefault:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IInclinometerStatics_Vtbl { @@ -8424,6 +25934,36 @@ windows_core::imp::define_interface!(IInclinometerStatics2, IInclinometerStatics impl windows_core::RuntimeType for IInclinometerStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IInclinometerStatics2 { + const NAME: &'static str = "Windows.Devices.Sensors.IInclinometerStatics2"; +} +pub trait IInclinometerStatics2_Impl: windows_core::IUnknownImpl { + fn GetDefaultForRelativeReadings(&self) -> windows_core::Result; +} +impl IInclinometerStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDefaultForRelativeReadings(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerStatics2_Impl::GetDefaultForRelativeReadings(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDefaultForRelativeReadings: GetDefaultForRelativeReadings::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IInclinometerStatics2_Vtbl { @@ -8434,6 +25974,36 @@ windows_core::imp::define_interface!(IInclinometerStatics3, IInclinometerStatics impl windows_core::RuntimeType for IInclinometerStatics3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IInclinometerStatics3 { + const NAME: &'static str = "Windows.Devices.Sensors.IInclinometerStatics3"; +} +pub trait IInclinometerStatics3_Impl: windows_core::IUnknownImpl { + fn GetDefaultWithSensorReadingType(&self, sensorReadingtype: SensorReadingType) -> windows_core::Result; +} +impl IInclinometerStatics3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDefaultWithSensorReadingType(this: *mut core::ffi::c_void, sensorreadingtype: SensorReadingType, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerStatics3_Impl::GetDefaultWithSensorReadingType(this, sensorreadingtype) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDefaultWithSensorReadingType: GetDefaultWithSensorReadingType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IInclinometerStatics3_Vtbl { @@ -8444,6 +26014,51 @@ windows_core::imp::define_interface!(IInclinometerStatics4, IInclinometerStatics impl windows_core::RuntimeType for IInclinometerStatics4 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IInclinometerStatics4 { + const NAME: &'static str = "Windows.Devices.Sensors.IInclinometerStatics4"; +} +pub trait IInclinometerStatics4_Impl: windows_core::IUnknownImpl { + fn GetDeviceSelector(&self, readingType: SensorReadingType) -> windows_core::Result; + fn FromIdAsync(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; +} +impl IInclinometerStatics4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDeviceSelector(this: *mut core::ffi::c_void, readingtype: SensorReadingType, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerStatics4_Impl::GetDeviceSelector(this, readingtype) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FromIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInclinometerStatics4_Impl::FromIdAsync(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDeviceSelector: GetDeviceSelector::, + FromIdAsync: FromIdAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IInclinometerStatics4_Vtbl { @@ -8455,6 +26070,94 @@ windows_core::imp::define_interface!(ILightSensor, ILightSensor_Vtbl, 0xf84c0718 impl windows_core::RuntimeType for ILightSensor { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ILightSensor { + const NAME: &'static str = "Windows.Devices.Sensors.ILightSensor"; +} +pub trait ILightSensor_Impl: windows_core::IUnknownImpl { + fn GetCurrentReading(&self) -> windows_core::Result; + fn MinimumReportInterval(&self) -> windows_core::Result; + fn SetReportInterval(&self, value: u32) -> windows_core::Result<()>; + fn ReportInterval(&self) -> windows_core::Result; + fn ReadingChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()>; +} +impl ILightSensor_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetCurrentReading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensor_Impl::GetCurrentReading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MinimumReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensor_Impl::MinimumReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetReportInterval(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ILightSensor_Impl::SetReportInterval(this, value).into() + } + } + unsafe extern "system" fn ReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensor_Impl::ReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadingChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensor_Impl::ReadingChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveReadingChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ILightSensor_Impl::RemoveReadingChanged(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetCurrentReading: GetCurrentReading::, + MinimumReportInterval: MinimumReportInterval::, + SetReportInterval: SetReportInterval::, + ReportInterval: ReportInterval::, + ReadingChanged: ReadingChanged::, + RemoveReadingChanged: RemoveReadingChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ILightSensor_Vtbl { @@ -8470,6 +26173,57 @@ windows_core::imp::define_interface!(ILightSensor2, ILightSensor2_Vtbl, 0x486b24 impl windows_core::RuntimeType for ILightSensor2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ILightSensor2 { + const NAME: &'static str = "Windows.Devices.Sensors.ILightSensor2"; +} +pub trait ILightSensor2_Impl: windows_core::IUnknownImpl { + fn SetReportLatency(&self, value: u32) -> windows_core::Result<()>; + fn ReportLatency(&self) -> windows_core::Result; + fn MaxBatchSize(&self) -> windows_core::Result; +} +impl ILightSensor2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetReportLatency(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ILightSensor2_Impl::SetReportLatency(this, value).into() + } + } + unsafe extern "system" fn ReportLatency(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensor2_Impl::ReportLatency(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxBatchSize(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensor2_Impl::MaxBatchSize(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetReportLatency: SetReportLatency::, + ReportLatency: ReportLatency::, + MaxBatchSize: MaxBatchSize::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ILightSensor2_Vtbl { @@ -8482,26 +26236,102 @@ windows_core::imp::define_interface!(ILightSensor3, ILightSensor3_Vtbl, 0x4876d0 impl windows_core::RuntimeType for ILightSensor3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ILightSensor3 { + const NAME: &'static str = "Windows.Devices.Sensors.ILightSensor3"; +} +pub trait ILightSensor3_Impl: windows_core::IUnknownImpl { + fn ReportThreshold(&self) -> windows_core::Result; +} +impl ILightSensor3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ReportThreshold(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensor3_Impl::ReportThreshold(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), ReportThreshold: ReportThreshold:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ILightSensor3_Vtbl { pub base__: windows_core::IInspectable_Vtbl, pub ReportThreshold: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, } -windows_core::imp::define_interface!(ILightSensor4, ILightSensor4_Vtbl, 0x6167be97_6390_404c_9c19_445311c6a1d3); -impl windows_core::RuntimeType for ILightSensor4 { - const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); -} -#[repr(C)] -#[doc(hidden)] -pub struct ILightSensor4_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub IsChromaticitySupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, -} windows_core::imp::define_interface!(ILightSensorDataThreshold, ILightSensorDataThreshold_Vtbl, 0xb160afd1_878f_5492_9f2c_33dc3ae584a3); impl windows_core::RuntimeType for ILightSensorDataThreshold { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ILightSensorDataThreshold { + const NAME: &'static str = "Windows.Devices.Sensors.ILightSensorDataThreshold"; +} +pub trait ILightSensorDataThreshold_Impl: windows_core::IUnknownImpl { + fn LuxPercentage(&self) -> windows_core::Result; + fn SetLuxPercentage(&self, value: f32) -> windows_core::Result<()>; + fn AbsoluteLux(&self) -> windows_core::Result; + fn SetAbsoluteLux(&self, value: f32) -> windows_core::Result<()>; +} +impl ILightSensorDataThreshold_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn LuxPercentage(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensorDataThreshold_Impl::LuxPercentage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetLuxPercentage(this: *mut core::ffi::c_void, value: f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ILightSensorDataThreshold_Impl::SetLuxPercentage(this, value).into() + } + } + unsafe extern "system" fn AbsoluteLux(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensorDataThreshold_Impl::AbsoluteLux(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAbsoluteLux(this: *mut core::ffi::c_void, value: f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ILightSensorDataThreshold_Impl::SetAbsoluteLux(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + LuxPercentage: LuxPercentage::, + SetLuxPercentage: SetLuxPercentage::, + AbsoluteLux: AbsoluteLux::, + SetAbsoluteLux: SetAbsoluteLux::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ILightSensorDataThreshold_Vtbl { @@ -8511,21 +26341,37 @@ pub struct ILightSensorDataThreshold_Vtbl { pub AbsoluteLux: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, pub SetAbsoluteLux: unsafe extern "system" fn(*mut core::ffi::c_void, f32) -> windows_core::HRESULT, } -windows_core::imp::define_interface!(ILightSensorDataThreshold2, ILightSensorDataThreshold2_Vtbl, 0x6f040fbd_e08b_5b97_8f61_dd4ee66b1733); -impl windows_core::RuntimeType for ILightSensorDataThreshold2 { - const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); -} -#[repr(C)] -#[doc(hidden)] -pub struct ILightSensorDataThreshold2_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub Chromaticity: unsafe extern "system" fn(*mut core::ffi::c_void, *mut LightSensorChromaticity) -> windows_core::HRESULT, - pub SetChromaticity: unsafe extern "system" fn(*mut core::ffi::c_void, LightSensorChromaticity) -> windows_core::HRESULT, -} windows_core::imp::define_interface!(ILightSensorDeviceId, ILightSensorDeviceId_Vtbl, 0x7fee49f8_0afb_4f51_87f0_6c26375ce94f); impl windows_core::RuntimeType for ILightSensorDeviceId { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ILightSensorDeviceId { + const NAME: &'static str = "Windows.Devices.Sensors.ILightSensorDeviceId"; +} +pub trait ILightSensorDeviceId_Impl: windows_core::IUnknownImpl { + fn DeviceId(&self) -> windows_core::Result; +} +impl ILightSensorDeviceId_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensorDeviceId_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), DeviceId: DeviceId:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ILightSensorDeviceId_Vtbl { @@ -8536,6 +26382,49 @@ windows_core::imp::define_interface!(ILightSensorReading, ILightSensorReading_Vt impl windows_core::RuntimeType for ILightSensorReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ILightSensorReading { + const NAME: &'static str = "Windows.Devices.Sensors.ILightSensorReading"; +} +pub trait ILightSensorReading_Impl: windows_core::IUnknownImpl { + fn Timestamp(&self) -> windows_core::Result; + fn IlluminanceInLux(&self) -> windows_core::Result; +} +impl ILightSensorReading_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Timestamp(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensorReading_Impl::Timestamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IlluminanceInLux(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensorReading_Impl::IlluminanceInLux(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Timestamp: Timestamp::, + IlluminanceInLux: IlluminanceInLux::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ILightSensorReading_Vtbl { @@ -8547,6 +26436,51 @@ windows_core::imp::define_interface!(ILightSensorReading2, ILightSensorReading2_ impl windows_core::RuntimeType for ILightSensorReading2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ILightSensorReading2 { + const NAME: &'static str = "Windows.Devices.Sensors.ILightSensorReading2"; +} +pub trait ILightSensorReading2_Impl: windows_core::IUnknownImpl { + fn PerformanceCount(&self) -> windows_core::Result>; + fn Properties(&self) -> windows_core::Result>; +} +impl ILightSensorReading2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn PerformanceCount(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensorReading2_Impl::PerformanceCount(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensorReading2_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + PerformanceCount: PerformanceCount::, + Properties: Properties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ILightSensorReading2_Vtbl { @@ -8554,20 +26488,37 @@ pub struct ILightSensorReading2_Vtbl { pub PerformanceCount: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, pub Properties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, } -windows_core::imp::define_interface!(ILightSensorReading3, ILightSensorReading3_Vtbl, 0xf338ee06_96af_4029_b530_61acc05b7cfe); -impl windows_core::RuntimeType for ILightSensorReading3 { - const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); -} -#[repr(C)] -#[doc(hidden)] -pub struct ILightSensorReading3_Vtbl { - pub base__: windows_core::IInspectable_Vtbl, - pub Chromaticity: unsafe extern "system" fn(*mut core::ffi::c_void, *mut LightSensorChromaticity) -> windows_core::HRESULT, -} windows_core::imp::define_interface!(ILightSensorReadingChangedEventArgs, ILightSensorReadingChangedEventArgs_Vtbl, 0xa3a2f4cf_258b_420c_b8ab_8edd601ecf50); impl windows_core::RuntimeType for ILightSensorReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ILightSensorReadingChangedEventArgs { + const NAME: &'static str = "Windows.Devices.Sensors.ILightSensorReadingChangedEventArgs"; +} +pub trait ILightSensorReadingChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn Reading(&self) -> windows_core::Result; +} +impl ILightSensorReadingChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Reading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensorReadingChangedEventArgs_Impl::Reading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Reading: Reading:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ILightSensorReadingChangedEventArgs_Vtbl { @@ -8578,6 +26529,33 @@ windows_core::imp::define_interface!(ILightSensorStatics, ILightSensorStatics_Vt impl windows_core::RuntimeType for ILightSensorStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ILightSensorStatics { + const NAME: &'static str = "Windows.Devices.Sensors.ILightSensorStatics"; +} +pub trait ILightSensorStatics_Impl: windows_core::IUnknownImpl { + fn GetDefault(&self) -> windows_core::Result; +} +impl ILightSensorStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDefault(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensorStatics_Impl::GetDefault(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), GetDefault: GetDefault:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ILightSensorStatics_Vtbl { @@ -8588,6 +26566,51 @@ windows_core::imp::define_interface!(ILightSensorStatics2, ILightSensorStatics2_ impl windows_core::RuntimeType for ILightSensorStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ILightSensorStatics2 { + const NAME: &'static str = "Windows.Devices.Sensors.ILightSensorStatics2"; +} +pub trait ILightSensorStatics2_Impl: windows_core::IUnknownImpl { + fn GetDeviceSelector(&self) -> windows_core::Result; + fn FromIdAsync(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; +} +impl ILightSensorStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDeviceSelector(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensorStatics2_Impl::GetDeviceSelector(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FromIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILightSensorStatics2_Impl::FromIdAsync(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDeviceSelector: GetDeviceSelector::, + FromIdAsync: FromIdAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ILightSensorStatics2_Vtbl { @@ -8599,6 +26622,94 @@ windows_core::imp::define_interface!(IOrientationSensor, IOrientationSensor_Vtbl impl windows_core::RuntimeType for IOrientationSensor { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IOrientationSensor { + const NAME: &'static str = "Windows.Devices.Sensors.IOrientationSensor"; +} +pub trait IOrientationSensor_Impl: windows_core::IUnknownImpl { + fn GetCurrentReading(&self) -> windows_core::Result; + fn MinimumReportInterval(&self) -> windows_core::Result; + fn SetReportInterval(&self, value: u32) -> windows_core::Result<()>; + fn ReportInterval(&self) -> windows_core::Result; + fn ReadingChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()>; +} +impl IOrientationSensor_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetCurrentReading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensor_Impl::GetCurrentReading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MinimumReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensor_Impl::MinimumReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetReportInterval(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IOrientationSensor_Impl::SetReportInterval(this, value).into() + } + } + unsafe extern "system" fn ReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensor_Impl::ReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadingChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensor_Impl::ReadingChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveReadingChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IOrientationSensor_Impl::RemoveReadingChanged(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetCurrentReading: GetCurrentReading::, + MinimumReportInterval: MinimumReportInterval::, + SetReportInterval: SetReportInterval::, + ReportInterval: ReportInterval::, + ReadingChanged: ReadingChanged::, + RemoveReadingChanged: RemoveReadingChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IOrientationSensor_Vtbl { @@ -8614,6 +26725,60 @@ windows_core::imp::define_interface!(IOrientationSensor2, IOrientationSensor2_Vt impl windows_core::RuntimeType for IOrientationSensor2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Graphics_Display")] +impl windows_core::RuntimeName for IOrientationSensor2 { + const NAME: &'static str = "Windows.Devices.Sensors.IOrientationSensor2"; +} +#[cfg(feature = "Graphics_Display")] +pub trait IOrientationSensor2_Impl: windows_core::IUnknownImpl { + fn SetReadingTransform(&self, value: super::super::Graphics::Display::DisplayOrientations) -> windows_core::Result<()>; + fn ReadingTransform(&self) -> windows_core::Result; + fn ReadingType(&self) -> windows_core::Result; +} +#[cfg(feature = "Graphics_Display")] +impl IOrientationSensor2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetReadingTransform(this: *mut core::ffi::c_void, value: super::super::Graphics::Display::DisplayOrientations) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IOrientationSensor2_Impl::SetReadingTransform(this, value).into() + } + } + unsafe extern "system" fn ReadingTransform(this: *mut core::ffi::c_void, result__: *mut super::super::Graphics::Display::DisplayOrientations) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensor2_Impl::ReadingTransform(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadingType(this: *mut core::ffi::c_void, result__: *mut SensorReadingType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensor2_Impl::ReadingType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetReadingTransform: SetReadingTransform::, + ReadingTransform: ReadingTransform::, + ReadingType: ReadingType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IOrientationSensor2_Vtbl { @@ -8632,6 +26797,57 @@ windows_core::imp::define_interface!(IOrientationSensor3, IOrientationSensor3_Vt impl windows_core::RuntimeType for IOrientationSensor3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IOrientationSensor3 { + const NAME: &'static str = "Windows.Devices.Sensors.IOrientationSensor3"; +} +pub trait IOrientationSensor3_Impl: windows_core::IUnknownImpl { + fn SetReportLatency(&self, value: u32) -> windows_core::Result<()>; + fn ReportLatency(&self) -> windows_core::Result; + fn MaxBatchSize(&self) -> windows_core::Result; +} +impl IOrientationSensor3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetReportLatency(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IOrientationSensor3_Impl::SetReportLatency(this, value).into() + } + } + unsafe extern "system" fn ReportLatency(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensor3_Impl::ReportLatency(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxBatchSize(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensor3_Impl::MaxBatchSize(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetReportLatency: SetReportLatency::, + ReportLatency: ReportLatency::, + MaxBatchSize: MaxBatchSize::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IOrientationSensor3_Vtbl { @@ -8644,6 +26860,33 @@ windows_core::imp::define_interface!(IOrientationSensorDeviceId, IOrientationSen impl windows_core::RuntimeType for IOrientationSensorDeviceId { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IOrientationSensorDeviceId { + const NAME: &'static str = "Windows.Devices.Sensors.IOrientationSensorDeviceId"; +} +pub trait IOrientationSensorDeviceId_Impl: windows_core::IUnknownImpl { + fn DeviceId(&self) -> windows_core::Result; +} +impl IOrientationSensorDeviceId_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensorDeviceId_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), DeviceId: DeviceId:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IOrientationSensorDeviceId_Vtbl { @@ -8654,6 +26897,65 @@ windows_core::imp::define_interface!(IOrientationSensorReading, IOrientationSens impl windows_core::RuntimeType for IOrientationSensorReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IOrientationSensorReading { + const NAME: &'static str = "Windows.Devices.Sensors.IOrientationSensorReading"; +} +pub trait IOrientationSensorReading_Impl: windows_core::IUnknownImpl { + fn Timestamp(&self) -> windows_core::Result; + fn RotationMatrix(&self) -> windows_core::Result; + fn Quaternion(&self) -> windows_core::Result; +} +impl IOrientationSensorReading_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Timestamp(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensorReading_Impl::Timestamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RotationMatrix(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensorReading_Impl::RotationMatrix(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Quaternion(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensorReading_Impl::Quaternion(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Timestamp: Timestamp::, + RotationMatrix: RotationMatrix::, + Quaternion: Quaternion::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IOrientationSensorReading_Vtbl { @@ -8666,6 +26968,51 @@ windows_core::imp::define_interface!(IOrientationSensorReading2, IOrientationSen impl windows_core::RuntimeType for IOrientationSensorReading2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IOrientationSensorReading2 { + const NAME: &'static str = "Windows.Devices.Sensors.IOrientationSensorReading2"; +} +pub trait IOrientationSensorReading2_Impl: windows_core::IUnknownImpl { + fn PerformanceCount(&self) -> windows_core::Result>; + fn Properties(&self) -> windows_core::Result>; +} +impl IOrientationSensorReading2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn PerformanceCount(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensorReading2_Impl::PerformanceCount(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensorReading2_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + PerformanceCount: PerformanceCount::, + Properties: Properties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IOrientationSensorReading2_Vtbl { @@ -8677,6 +27024,36 @@ windows_core::imp::define_interface!(IOrientationSensorReadingChangedEventArgs, impl windows_core::RuntimeType for IOrientationSensorReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IOrientationSensorReadingChangedEventArgs { + const NAME: &'static str = "Windows.Devices.Sensors.IOrientationSensorReadingChangedEventArgs"; +} +pub trait IOrientationSensorReadingChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn Reading(&self) -> windows_core::Result; +} +impl IOrientationSensorReadingChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Reading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensorReadingChangedEventArgs_Impl::Reading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Reading: Reading::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IOrientationSensorReadingChangedEventArgs_Vtbl { @@ -8687,6 +27064,35 @@ windows_core::imp::define_interface!(IOrientationSensorReadingYawAccuracy, IOrie impl windows_core::RuntimeType for IOrientationSensorReadingYawAccuracy { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IOrientationSensorReadingYawAccuracy { + const NAME: &'static str = "Windows.Devices.Sensors.IOrientationSensorReadingYawAccuracy"; +} +pub trait IOrientationSensorReadingYawAccuracy_Impl: windows_core::IUnknownImpl { + fn YawAccuracy(&self) -> windows_core::Result; +} +impl IOrientationSensorReadingYawAccuracy_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn YawAccuracy(this: *mut core::ffi::c_void, result__: *mut MagnetometerAccuracy) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensorReadingYawAccuracy_Impl::YawAccuracy(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + YawAccuracy: YawAccuracy::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IOrientationSensorReadingYawAccuracy_Vtbl { @@ -8697,6 +27103,33 @@ windows_core::imp::define_interface!(IOrientationSensorStatics, IOrientationSens impl windows_core::RuntimeType for IOrientationSensorStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IOrientationSensorStatics { + const NAME: &'static str = "Windows.Devices.Sensors.IOrientationSensorStatics"; +} +pub trait IOrientationSensorStatics_Impl: windows_core::IUnknownImpl { + fn GetDefault(&self) -> windows_core::Result; +} +impl IOrientationSensorStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDefault(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensorStatics_Impl::GetDefault(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), GetDefault: GetDefault:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IOrientationSensorStatics_Vtbl { @@ -8707,6 +27140,36 @@ windows_core::imp::define_interface!(IOrientationSensorStatics2, IOrientationSen impl windows_core::RuntimeType for IOrientationSensorStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IOrientationSensorStatics2 { + const NAME: &'static str = "Windows.Devices.Sensors.IOrientationSensorStatics2"; +} +pub trait IOrientationSensorStatics2_Impl: windows_core::IUnknownImpl { + fn GetDefaultForRelativeReadings(&self) -> windows_core::Result; +} +impl IOrientationSensorStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDefaultForRelativeReadings(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensorStatics2_Impl::GetDefaultForRelativeReadings(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDefaultForRelativeReadings: GetDefaultForRelativeReadings::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IOrientationSensorStatics2_Vtbl { @@ -8717,6 +27180,51 @@ windows_core::imp::define_interface!(IOrientationSensorStatics3, IOrientationSen impl windows_core::RuntimeType for IOrientationSensorStatics3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IOrientationSensorStatics3 { + const NAME: &'static str = "Windows.Devices.Sensors.IOrientationSensorStatics3"; +} +pub trait IOrientationSensorStatics3_Impl: windows_core::IUnknownImpl { + fn GetDefaultWithSensorReadingType(&self, sensorReadingtype: SensorReadingType) -> windows_core::Result; + fn GetDefaultWithSensorReadingTypeAndSensorOptimizationGoal(&self, sensorReadingType: SensorReadingType, optimizationGoal: SensorOptimizationGoal) -> windows_core::Result; +} +impl IOrientationSensorStatics3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDefaultWithSensorReadingType(this: *mut core::ffi::c_void, sensorreadingtype: SensorReadingType, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensorStatics3_Impl::GetDefaultWithSensorReadingType(this, sensorreadingtype) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDefaultWithSensorReadingTypeAndSensorOptimizationGoal(this: *mut core::ffi::c_void, sensorreadingtype: SensorReadingType, optimizationgoal: SensorOptimizationGoal, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensorStatics3_Impl::GetDefaultWithSensorReadingTypeAndSensorOptimizationGoal(this, sensorreadingtype, optimizationgoal) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDefaultWithSensorReadingType: GetDefaultWithSensorReadingType::, + GetDefaultWithSensorReadingTypeAndSensorOptimizationGoal: GetDefaultWithSensorReadingTypeAndSensorOptimizationGoal::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IOrientationSensorStatics3_Vtbl { @@ -8728,6 +27236,66 @@ windows_core::imp::define_interface!(IOrientationSensorStatics4, IOrientationSen impl windows_core::RuntimeType for IOrientationSensorStatics4 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IOrientationSensorStatics4 { + const NAME: &'static str = "Windows.Devices.Sensors.IOrientationSensorStatics4"; +} +pub trait IOrientationSensorStatics4_Impl: windows_core::IUnknownImpl { + fn GetDeviceSelector(&self, readingType: SensorReadingType) -> windows_core::Result; + fn GetDeviceSelectorWithSensorReadingTypeAndSensorOptimizationGoal(&self, readingType: SensorReadingType, optimizationGoal: SensorOptimizationGoal) -> windows_core::Result; + fn FromIdAsync(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; +} +impl IOrientationSensorStatics4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDeviceSelector(this: *mut core::ffi::c_void, readingtype: SensorReadingType, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensorStatics4_Impl::GetDeviceSelector(this, readingtype) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelectorWithSensorReadingTypeAndSensorOptimizationGoal(this: *mut core::ffi::c_void, readingtype: SensorReadingType, optimizationgoal: SensorOptimizationGoal, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensorStatics4_Impl::GetDeviceSelectorWithSensorReadingTypeAndSensorOptimizationGoal(this, readingtype, optimizationgoal) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FromIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOrientationSensorStatics4_Impl::FromIdAsync(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDeviceSelector: GetDeviceSelector::, + GetDeviceSelectorWithSensorReadingTypeAndSensorOptimizationGoal: GetDeviceSelectorWithSensorReadingTypeAndSensorOptimizationGoal::, + FromIdAsync: FromIdAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IOrientationSensorStatics4_Vtbl { @@ -8740,6 +27308,108 @@ windows_core::imp::define_interface!(IPedometer, IPedometer_Vtbl, 0x9a1e013d_3d9 impl windows_core::RuntimeType for IPedometer { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IPedometer { + const NAME: &'static str = "Windows.Devices.Sensors.IPedometer"; +} +pub trait IPedometer_Impl: windows_core::IUnknownImpl { + fn DeviceId(&self) -> windows_core::Result; + fn PowerInMilliwatts(&self) -> windows_core::Result; + fn MinimumReportInterval(&self) -> windows_core::Result; + fn SetReportInterval(&self, value: u32) -> windows_core::Result<()>; + fn ReportInterval(&self) -> windows_core::Result; + fn ReadingChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()>; +} +impl IPedometer_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometer_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PowerInMilliwatts(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometer_Impl::PowerInMilliwatts(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MinimumReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometer_Impl::MinimumReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetReportInterval(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IPedometer_Impl::SetReportInterval(this, value).into() + } + } + unsafe extern "system" fn ReportInterval(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometer_Impl::ReportInterval(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadingChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometer_Impl::ReadingChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveReadingChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IPedometer_Impl::RemoveReadingChanged(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DeviceId: DeviceId::, + PowerInMilliwatts: PowerInMilliwatts::, + MinimumReportInterval: MinimumReportInterval::, + SetReportInterval: SetReportInterval::, + ReportInterval: ReportInterval::, + ReadingChanged: ReadingChanged::, + RemoveReadingChanged: RemoveReadingChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IPedometer_Vtbl { @@ -8756,6 +27426,33 @@ windows_core::imp::define_interface!(IPedometer2, IPedometer2_Vtbl, 0xe5a406df_2 impl windows_core::RuntimeType for IPedometer2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IPedometer2 { + const NAME: &'static str = "Windows.Devices.Sensors.IPedometer2"; +} +pub trait IPedometer2_Impl: windows_core::IUnknownImpl { + fn GetCurrentReadings(&self) -> windows_core::Result>; +} +impl IPedometer2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetCurrentReadings(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometer2_Impl::GetCurrentReadings(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), GetCurrentReadings: GetCurrentReadings:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IPedometer2_Vtbl { @@ -8766,6 +27463,33 @@ windows_core::imp::define_interface!(IPedometerDataThresholdFactory, IPedometerD impl windows_core::RuntimeType for IPedometerDataThresholdFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IPedometerDataThresholdFactory { + const NAME: &'static str = "Windows.Devices.Sensors.IPedometerDataThresholdFactory"; +} +pub trait IPedometerDataThresholdFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, sensor: windows_core::Ref<'_, Pedometer>, stepGoal: i32) -> windows_core::Result; +} +impl IPedometerDataThresholdFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, sensor: *mut core::ffi::c_void, stepgoal: i32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometerDataThresholdFactory_Impl::Create(this, core::mem::transmute_copy(&sensor), stepgoal) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IPedometerDataThresholdFactory_Vtbl { @@ -8776,6 +27500,77 @@ windows_core::imp::define_interface!(IPedometerReading, IPedometerReading_Vtbl, impl windows_core::RuntimeType for IPedometerReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IPedometerReading { + const NAME: &'static str = "Windows.Devices.Sensors.IPedometerReading"; +} +pub trait IPedometerReading_Impl: windows_core::IUnknownImpl { + fn StepKind(&self) -> windows_core::Result; + fn CumulativeSteps(&self) -> windows_core::Result; + fn Timestamp(&self) -> windows_core::Result; + fn CumulativeStepsDuration(&self) -> windows_core::Result; +} +impl IPedometerReading_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn StepKind(this: *mut core::ffi::c_void, result__: *mut PedometerStepKind) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometerReading_Impl::StepKind(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CumulativeSteps(this: *mut core::ffi::c_void, result__: *mut i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometerReading_Impl::CumulativeSteps(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Timestamp(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometerReading_Impl::Timestamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CumulativeStepsDuration(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometerReading_Impl::CumulativeStepsDuration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + StepKind: StepKind::, + CumulativeSteps: CumulativeSteps::, + Timestamp: Timestamp::, + CumulativeStepsDuration: CumulativeStepsDuration::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IPedometerReading_Vtbl { @@ -8789,6 +27584,33 @@ windows_core::imp::define_interface!(IPedometerReadingChangedEventArgs, IPedomet impl windows_core::RuntimeType for IPedometerReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IPedometerReadingChangedEventArgs { + const NAME: &'static str = "Windows.Devices.Sensors.IPedometerReadingChangedEventArgs"; +} +pub trait IPedometerReadingChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn Reading(&self) -> windows_core::Result; +} +impl IPedometerReadingChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Reading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometerReadingChangedEventArgs_Impl::Reading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Reading: Reading:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IPedometerReadingChangedEventArgs_Vtbl { @@ -8799,6 +27621,96 @@ windows_core::imp::define_interface!(IPedometerStatics, IPedometerStatics_Vtbl, impl windows_core::RuntimeType for IPedometerStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IPedometerStatics { + const NAME: &'static str = "Windows.Devices.Sensors.IPedometerStatics"; +} +pub trait IPedometerStatics_Impl: windows_core::IUnknownImpl { + fn FromIdAsync(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; + fn GetDefaultAsync(&self) -> windows_core::Result>; + fn GetDeviceSelector(&self) -> windows_core::Result; + fn GetSystemHistoryAsync(&self, fromTime: &super::super::Foundation::DateTime) -> windows_core::Result>>; + fn GetSystemHistoryWithDurationAsync(&self, fromTime: &super::super::Foundation::DateTime, duration: &super::super::Foundation::TimeSpan) -> windows_core::Result>>; +} +impl IPedometerStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FromIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometerStatics_Impl::FromIdAsync(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDefaultAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometerStatics_Impl::GetDefaultAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelector(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometerStatics_Impl::GetDeviceSelector(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetSystemHistoryAsync(this: *mut core::ffi::c_void, fromtime: super::super::Foundation::DateTime, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometerStatics_Impl::GetSystemHistoryAsync(this, core::mem::transmute(&fromtime)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetSystemHistoryWithDurationAsync(this: *mut core::ffi::c_void, fromtime: super::super::Foundation::DateTime, duration: super::super::Foundation::TimeSpan, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometerStatics_Impl::GetSystemHistoryWithDurationAsync(this, core::mem::transmute(&fromtime), core::mem::transmute(&duration)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FromIdAsync: FromIdAsync::, + GetDefaultAsync: GetDefaultAsync::, + GetDeviceSelector: GetDeviceSelector::, + GetSystemHistoryAsync: GetSystemHistoryAsync::, + GetSystemHistoryWithDurationAsync: GetSystemHistoryWithDurationAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IPedometerStatics_Vtbl { @@ -8813,6 +27725,36 @@ windows_core::imp::define_interface!(IPedometerStatics2, IPedometerStatics2_Vtbl impl windows_core::RuntimeType for IPedometerStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IPedometerStatics2 { + const NAME: &'static str = "Windows.Devices.Sensors.IPedometerStatics2"; +} +pub trait IPedometerStatics2_Impl: windows_core::IUnknownImpl { + fn GetReadingsFromTriggerDetails(&self, triggerDetails: windows_core::Ref<'_, SensorDataThresholdTriggerDetails>) -> windows_core::Result>; +} +impl IPedometerStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetReadingsFromTriggerDetails(this: *mut core::ffi::c_void, triggerdetails: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPedometerStatics2_Impl::GetReadingsFromTriggerDetails(this, core::mem::transmute_copy(&triggerdetails)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetReadingsFromTriggerDetails: GetReadingsFromTriggerDetails::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IPedometerStatics2_Vtbl { @@ -8823,6 +27765,118 @@ windows_core::imp::define_interface!(IProximitySensor, IProximitySensor_Vtbl, 0x impl windows_core::RuntimeType for IProximitySensor { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IProximitySensor { + const NAME: &'static str = "Windows.Devices.Sensors.IProximitySensor"; +} +pub trait IProximitySensor_Impl: windows_core::IUnknownImpl { + fn DeviceId(&self) -> windows_core::Result; + fn MaxDistanceInMillimeters(&self) -> windows_core::Result>; + fn MinDistanceInMillimeters(&self) -> windows_core::Result>; + fn GetCurrentReading(&self) -> windows_core::Result; + fn ReadingChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()>; + fn CreateDisplayOnOffController(&self) -> windows_core::Result; +} +impl IProximitySensor_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProximitySensor_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxDistanceInMillimeters(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProximitySensor_Impl::MaxDistanceInMillimeters(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MinDistanceInMillimeters(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProximitySensor_Impl::MinDistanceInMillimeters(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetCurrentReading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProximitySensor_Impl::GetCurrentReading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadingChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProximitySensor_Impl::ReadingChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveReadingChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IProximitySensor_Impl::RemoveReadingChanged(this, token).into() + } + } + unsafe extern "system" fn CreateDisplayOnOffController(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProximitySensor_Impl::CreateDisplayOnOffController(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DeviceId: DeviceId::, + MaxDistanceInMillimeters: MaxDistanceInMillimeters::, + MinDistanceInMillimeters: MinDistanceInMillimeters::, + GetCurrentReading: GetCurrentReading::, + ReadingChanged: ReadingChanged::, + RemoveReadingChanged: RemoveReadingChanged::, + CreateDisplayOnOffController: CreateDisplayOnOffController::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IProximitySensor_Vtbl { @@ -8839,6 +27893,33 @@ windows_core::imp::define_interface!(IProximitySensorDataThresholdFactory, IProx impl windows_core::RuntimeType for IProximitySensorDataThresholdFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IProximitySensorDataThresholdFactory { + const NAME: &'static str = "Windows.Devices.Sensors.IProximitySensorDataThresholdFactory"; +} +pub trait IProximitySensorDataThresholdFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, sensor: windows_core::Ref<'_, ProximitySensor>) -> windows_core::Result; +} +impl IProximitySensorDataThresholdFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, sensor: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProximitySensorDataThresholdFactory_Impl::Create(this, core::mem::transmute_copy(&sensor)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IProximitySensorDataThresholdFactory_Vtbl { @@ -8849,6 +27930,64 @@ windows_core::imp::define_interface!(IProximitySensorReading, IProximitySensorRe impl windows_core::RuntimeType for IProximitySensorReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IProximitySensorReading { + const NAME: &'static str = "Windows.Devices.Sensors.IProximitySensorReading"; +} +pub trait IProximitySensorReading_Impl: windows_core::IUnknownImpl { + fn Timestamp(&self) -> windows_core::Result; + fn IsDetected(&self) -> windows_core::Result; + fn DistanceInMillimeters(&self) -> windows_core::Result>; +} +impl IProximitySensorReading_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Timestamp(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProximitySensorReading_Impl::Timestamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsDetected(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProximitySensorReading_Impl::IsDetected(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DistanceInMillimeters(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProximitySensorReading_Impl::DistanceInMillimeters(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Timestamp: Timestamp::, + IsDetected: IsDetected::, + DistanceInMillimeters: DistanceInMillimeters::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IProximitySensorReading_Vtbl { @@ -8861,6 +28000,36 @@ windows_core::imp::define_interface!(IProximitySensorReadingChangedEventArgs, IP impl windows_core::RuntimeType for IProximitySensorReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IProximitySensorReadingChangedEventArgs { + const NAME: &'static str = "Windows.Devices.Sensors.IProximitySensorReadingChangedEventArgs"; +} +pub trait IProximitySensorReadingChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn Reading(&self) -> windows_core::Result; +} +impl IProximitySensorReadingChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Reading(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProximitySensorReadingChangedEventArgs_Impl::Reading(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Reading: Reading::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IProximitySensorReadingChangedEventArgs_Vtbl { @@ -8871,6 +28040,51 @@ windows_core::imp::define_interface!(IProximitySensorStatics, IProximitySensorSt impl windows_core::RuntimeType for IProximitySensorStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IProximitySensorStatics { + const NAME: &'static str = "Windows.Devices.Sensors.IProximitySensorStatics"; +} +pub trait IProximitySensorStatics_Impl: windows_core::IUnknownImpl { + fn GetDeviceSelector(&self) -> windows_core::Result; + fn FromId(&self, sensorId: &windows_core::HSTRING) -> windows_core::Result; +} +impl IProximitySensorStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDeviceSelector(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProximitySensorStatics_Impl::GetDeviceSelector(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FromId(this: *mut core::ffi::c_void, sensorid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProximitySensorStatics_Impl::FromId(this, core::mem::transmute(&sensorid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDeviceSelector: GetDeviceSelector::, + FromId: FromId::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IProximitySensorStatics_Vtbl { @@ -8882,6 +28096,36 @@ windows_core::imp::define_interface!(IProximitySensorStatics2, IProximitySensorS impl windows_core::RuntimeType for IProximitySensorStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IProximitySensorStatics2 { + const NAME: &'static str = "Windows.Devices.Sensors.IProximitySensorStatics2"; +} +pub trait IProximitySensorStatics2_Impl: windows_core::IUnknownImpl { + fn GetReadingsFromTriggerDetails(&self, triggerDetails: windows_core::Ref<'_, SensorDataThresholdTriggerDetails>) -> windows_core::Result>; +} +impl IProximitySensorStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetReadingsFromTriggerDetails(this: *mut core::ffi::c_void, triggerdetails: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProximitySensorStatics2_Impl::GetReadingsFromTriggerDetails(this, core::mem::transmute_copy(&triggerdetails)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetReadingsFromTriggerDetails: GetReadingsFromTriggerDetails::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IProximitySensorStatics2_Vtbl { @@ -8914,6 +28158,50 @@ windows_core::imp::define_interface!(ISensorDataThresholdTriggerDetails, ISensor impl windows_core::RuntimeType for ISensorDataThresholdTriggerDetails { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISensorDataThresholdTriggerDetails { + const NAME: &'static str = "Windows.Devices.Sensors.ISensorDataThresholdTriggerDetails"; +} +pub trait ISensorDataThresholdTriggerDetails_Impl: windows_core::IUnknownImpl { + fn DeviceId(&self) -> windows_core::Result; + fn SensorType(&self) -> windows_core::Result; +} +impl ISensorDataThresholdTriggerDetails_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorDataThresholdTriggerDetails_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SensorType(this: *mut core::ffi::c_void, result__: *mut SensorType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorDataThresholdTriggerDetails_Impl::SensorType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DeviceId: DeviceId::, + SensorType: SensorType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISensorDataThresholdTriggerDetails_Vtbl { @@ -8925,6 +28213,77 @@ windows_core::imp::define_interface!(ISensorQuaternion, ISensorQuaternion_Vtbl, impl windows_core::RuntimeType for ISensorQuaternion { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISensorQuaternion { + const NAME: &'static str = "Windows.Devices.Sensors.ISensorQuaternion"; +} +pub trait ISensorQuaternion_Impl: windows_core::IUnknownImpl { + fn W(&self) -> windows_core::Result; + fn X(&self) -> windows_core::Result; + fn Y(&self) -> windows_core::Result; + fn Z(&self) -> windows_core::Result; +} +impl ISensorQuaternion_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn W(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorQuaternion_Impl::W(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn X(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorQuaternion_Impl::X(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Y(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorQuaternion_Impl::Y(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Z(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorQuaternion_Impl::Z(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + W: W::, + X: X::, + Y: Y::, + Z: Z::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISensorQuaternion_Vtbl { @@ -8938,6 +28297,147 @@ windows_core::imp::define_interface!(ISensorRotationMatrix, ISensorRotationMatri impl windows_core::RuntimeType for ISensorRotationMatrix { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISensorRotationMatrix { + const NAME: &'static str = "Windows.Devices.Sensors.ISensorRotationMatrix"; +} +pub trait ISensorRotationMatrix_Impl: windows_core::IUnknownImpl { + fn M11(&self) -> windows_core::Result; + fn M12(&self) -> windows_core::Result; + fn M13(&self) -> windows_core::Result; + fn M21(&self) -> windows_core::Result; + fn M22(&self) -> windows_core::Result; + fn M23(&self) -> windows_core::Result; + fn M31(&self) -> windows_core::Result; + fn M32(&self) -> windows_core::Result; + fn M33(&self) -> windows_core::Result; +} +impl ISensorRotationMatrix_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn M11(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorRotationMatrix_Impl::M11(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn M12(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorRotationMatrix_Impl::M12(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn M13(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorRotationMatrix_Impl::M13(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn M21(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorRotationMatrix_Impl::M21(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn M22(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorRotationMatrix_Impl::M22(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn M23(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorRotationMatrix_Impl::M23(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn M31(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorRotationMatrix_Impl::M31(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn M32(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorRotationMatrix_Impl::M32(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn M33(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISensorRotationMatrix_Impl::M33(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + M11: M11::, + M12: M12::, + M13: M13::, + M21: M21::, + M22: M22::, + M23: M23::, + M31: M31::, + M32: M32::, + M33: M33::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISensorRotationMatrix_Vtbl { @@ -8956,6 +28456,57 @@ windows_core::imp::define_interface!(ISimpleOrientationSensor, ISimpleOrientatio impl windows_core::RuntimeType for ISimpleOrientationSensor { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISimpleOrientationSensor { + const NAME: &'static str = "Windows.Devices.Sensors.ISimpleOrientationSensor"; +} +pub trait ISimpleOrientationSensor_Impl: windows_core::IUnknownImpl { + fn GetCurrentOrientation(&self) -> windows_core::Result; + fn OrientationChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveOrientationChanged(&self, token: i64) -> windows_core::Result<()>; +} +impl ISimpleOrientationSensor_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetCurrentOrientation(this: *mut core::ffi::c_void, result__: *mut SimpleOrientation) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISimpleOrientationSensor_Impl::GetCurrentOrientation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OrientationChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISimpleOrientationSensor_Impl::OrientationChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveOrientationChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISimpleOrientationSensor_Impl::RemoveOrientationChanged(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetCurrentOrientation: GetCurrentOrientation::, + OrientationChanged: OrientationChanged::, + RemoveOrientationChanged: RemoveOrientationChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISimpleOrientationSensor_Vtbl { @@ -8968,6 +28519,46 @@ windows_core::imp::define_interface!(ISimpleOrientationSensor2, ISimpleOrientati impl windows_core::RuntimeType for ISimpleOrientationSensor2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Graphics_Display")] +impl windows_core::RuntimeName for ISimpleOrientationSensor2 { + const NAME: &'static str = "Windows.Devices.Sensors.ISimpleOrientationSensor2"; +} +#[cfg(feature = "Graphics_Display")] +pub trait ISimpleOrientationSensor2_Impl: windows_core::IUnknownImpl { + fn SetReadingTransform(&self, value: super::super::Graphics::Display::DisplayOrientations) -> windows_core::Result<()>; + fn ReadingTransform(&self) -> windows_core::Result; +} +#[cfg(feature = "Graphics_Display")] +impl ISimpleOrientationSensor2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetReadingTransform(this: *mut core::ffi::c_void, value: super::super::Graphics::Display::DisplayOrientations) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISimpleOrientationSensor2_Impl::SetReadingTransform(this, value).into() + } + } + unsafe extern "system" fn ReadingTransform(this: *mut core::ffi::c_void, result__: *mut super::super::Graphics::Display::DisplayOrientations) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISimpleOrientationSensor2_Impl::ReadingTransform(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetReadingTransform: SetReadingTransform::, + ReadingTransform: ReadingTransform::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISimpleOrientationSensor2_Vtbl { @@ -8985,6 +28576,33 @@ windows_core::imp::define_interface!(ISimpleOrientationSensorDeviceId, ISimpleOr impl windows_core::RuntimeType for ISimpleOrientationSensorDeviceId { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISimpleOrientationSensorDeviceId { + const NAME: &'static str = "Windows.Devices.Sensors.ISimpleOrientationSensorDeviceId"; +} +pub trait ISimpleOrientationSensorDeviceId_Impl: windows_core::IUnknownImpl { + fn DeviceId(&self) -> windows_core::Result; +} +impl ISimpleOrientationSensorDeviceId_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISimpleOrientationSensorDeviceId_Impl::DeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), DeviceId: DeviceId:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISimpleOrientationSensorDeviceId_Vtbl { @@ -8995,6 +28613,49 @@ windows_core::imp::define_interface!(ISimpleOrientationSensorOrientationChangedE impl windows_core::RuntimeType for ISimpleOrientationSensorOrientationChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISimpleOrientationSensorOrientationChangedEventArgs { + const NAME: &'static str = "Windows.Devices.Sensors.ISimpleOrientationSensorOrientationChangedEventArgs"; +} +pub trait ISimpleOrientationSensorOrientationChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn Timestamp(&self) -> windows_core::Result; + fn Orientation(&self) -> windows_core::Result; +} +impl ISimpleOrientationSensorOrientationChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Timestamp(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISimpleOrientationSensorOrientationChangedEventArgs_Impl::Timestamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Orientation(this: *mut core::ffi::c_void, result__: *mut SimpleOrientation) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISimpleOrientationSensorOrientationChangedEventArgs_Impl::Orientation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Timestamp: Timestamp::, + Orientation: Orientation::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISimpleOrientationSensorOrientationChangedEventArgs_Vtbl { @@ -9006,6 +28667,33 @@ windows_core::imp::define_interface!(ISimpleOrientationSensorStatics, ISimpleOri impl windows_core::RuntimeType for ISimpleOrientationSensorStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISimpleOrientationSensorStatics { + const NAME: &'static str = "Windows.Devices.Sensors.ISimpleOrientationSensorStatics"; +} +pub trait ISimpleOrientationSensorStatics_Impl: windows_core::IUnknownImpl { + fn GetDefault(&self) -> windows_core::Result; +} +impl ISimpleOrientationSensorStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDefault(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISimpleOrientationSensorStatics_Impl::GetDefault(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), GetDefault: GetDefault:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISimpleOrientationSensorStatics_Vtbl { @@ -9016,6 +28704,51 @@ windows_core::imp::define_interface!(ISimpleOrientationSensorStatics2, ISimpleOr impl windows_core::RuntimeType for ISimpleOrientationSensorStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISimpleOrientationSensorStatics2 { + const NAME: &'static str = "Windows.Devices.Sensors.ISimpleOrientationSensorStatics2"; +} +pub trait ISimpleOrientationSensorStatics2_Impl: windows_core::IUnknownImpl { + fn GetDeviceSelector(&self) -> windows_core::Result; + fn FromIdAsync(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result>; +} +impl ISimpleOrientationSensorStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDeviceSelector(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISimpleOrientationSensorStatics2_Impl::GetDeviceSelector(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FromIdAsync(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISimpleOrientationSensorStatics2_Impl::FromIdAsync(this, core::mem::transmute(&deviceid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDeviceSelector: GetDeviceSelector::, + FromIdAsync: FromIdAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISimpleOrientationSensorStatics2_Vtbl { @@ -9028,6 +28761,115 @@ pub struct ISimpleOrientationSensorStatics2_Vtbl { pub struct Inclinometer(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(Inclinometer, windows_core::IUnknown, windows_core::IInspectable); impl Inclinometer { + pub fn GetCurrentReading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentReading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MinimumReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinimumReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetReportInterval(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetReportInterval)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadingChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveReadingChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Graphics_Display")] + pub fn SetReadingTransform(&self, value: super::super::Graphics::Display::DisplayOrientations) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetReadingTransform)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Graphics_Display")] + pub fn ReadingTransform(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingTransform)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadingType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetReportLatency(&self, value: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetReportLatency)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ReportLatency(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportLatency)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaxBatchSize(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxBatchSize)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReportThreshold(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportThreshold)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeviceId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetDefault() -> windows_core::Result { + Self::IInclinometerStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetDefaultForRelativeReadings() -> windows_core::Result { + Self::IInclinometerStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefaultForRelativeReadings)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetDefaultWithSensorReadingType(sensorreadingtype: SensorReadingType) -> windows_core::Result { + Self::IInclinometerStatics3(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefaultWithSensorReadingType)(windows_core::Interface::as_raw(this), sensorreadingtype, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn GetDeviceSelector(readingtype: SensorReadingType) -> windows_core::Result { Self::IInclinometerStatics4(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -9073,6 +28915,41 @@ unsafe impl Sync for Inclinometer {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct InclinometerDataThreshold(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(InclinometerDataThreshold, windows_core::IUnknown, windows_core::IInspectable); +impl InclinometerDataThreshold { + pub fn PitchInDegrees(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PitchInDegrees)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetPitchInDegrees(&self, value: f32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPitchInDegrees)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn RollInDegrees(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RollInDegrees)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetRollInDegrees(&self, value: f32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetRollInDegrees)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn YawInDegrees(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).YawInDegrees)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetYawInDegrees(&self, value: f32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetYawInDegrees)(windows_core::Interface::as_raw(this), value).ok() } + } +} impl windows_core::RuntimeType for InclinometerDataThreshold { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9089,6 +28966,57 @@ unsafe impl Sync for InclinometerDataThreshold {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct InclinometerReading(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(InclinometerReading, windows_core::IUnknown, windows_core::IInspectable); +impl InclinometerReading { + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PitchDegrees(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PitchDegrees)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn RollDegrees(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RollDegrees)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn YawDegrees(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).YawDegrees)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PerformanceCount(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PerformanceCount)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Properties(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn YawAccuracy(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).YawAccuracy)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for InclinometerReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9105,6 +29033,15 @@ unsafe impl Sync for InclinometerReading {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct InclinometerReadingChangedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(InclinometerReadingChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl InclinometerReadingChangedEventArgs { + pub fn Reading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Reading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for InclinometerReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9122,6 +29059,83 @@ unsafe impl Sync for InclinometerReadingChangedEventArgs {} pub struct LightSensor(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(LightSensor, windows_core::IUnknown, windows_core::IInspectable); impl LightSensor { + pub fn GetCurrentReading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentReading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MinimumReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinimumReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetReportInterval(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetReportInterval)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadingChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveReadingChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn SetReportLatency(&self, value: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetReportLatency)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ReportLatency(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportLatency)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaxBatchSize(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxBatchSize)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReportThreshold(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportThreshold)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeviceId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetDefault() -> windows_core::Result { + Self::ILightSensorStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn GetDeviceSelector() -> windows_core::Result { Self::ILightSensorStatics2(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -9155,22 +29169,34 @@ impl windows_core::RuntimeName for LightSensor { } unsafe impl Send for LightSensor {} unsafe impl Sync for LightSensor {} -#[repr(C)] -#[derive(Clone, Copy, Debug, Default, PartialEq)] -pub struct LightSensorChromaticity { - pub X: f64, - pub Y: f64, -} -impl windows_core::TypeKind for LightSensorChromaticity { - type TypeKind = windows_core::CopyType; -} -impl windows_core::RuntimeType for LightSensorChromaticity { - const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"struct(Windows.Devices.Sensors.LightSensorChromaticity;f8;f8)"); -} #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] pub struct LightSensorDataThreshold(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(LightSensorDataThreshold, windows_core::IUnknown, windows_core::IInspectable); +impl LightSensorDataThreshold { + pub fn LuxPercentage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LuxPercentage)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetLuxPercentage(&self, value: f32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetLuxPercentage)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn AbsoluteLux(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AbsoluteLux)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAbsoluteLux(&self, value: f32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAbsoluteLux)(windows_core::Interface::as_raw(this), value).ok() } + } +} impl windows_core::RuntimeType for LightSensorDataThreshold { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9187,6 +29213,36 @@ unsafe impl Sync for LightSensorDataThreshold {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct LightSensorReading(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(LightSensorReading, windows_core::IUnknown, windows_core::IInspectable); +impl LightSensorReading { + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IlluminanceInLux(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IlluminanceInLux)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PerformanceCount(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PerformanceCount)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Properties(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for LightSensorReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9203,6 +29259,15 @@ unsafe impl Sync for LightSensorReading {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct LightSensorReadingChangedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(LightSensorReadingChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl LightSensorReadingChangedEventArgs { + pub fn Reading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Reading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for LightSensorReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9235,12 +29300,126 @@ impl windows_core::RuntimeType for MagnetometerAccuracy { pub struct OrientationSensor(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(OrientationSensor, windows_core::IUnknown, windows_core::IInspectable); impl OrientationSensor { + pub fn GetCurrentReading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentReading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MinimumReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinimumReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetReportInterval(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetReportInterval)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadingChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveReadingChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Graphics_Display")] + pub fn SetReadingTransform(&self, value: super::super::Graphics::Display::DisplayOrientations) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetReadingTransform)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Graphics_Display")] + pub fn ReadingTransform(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingTransform)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadingType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetReportLatency(&self, value: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetReportLatency)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ReportLatency(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportLatency)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaxBatchSize(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxBatchSize)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DeviceId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetDefault() -> windows_core::Result { + Self::IOrientationSensorStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetDefaultForRelativeReadings() -> windows_core::Result { + Self::IOrientationSensorStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefaultForRelativeReadings)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetDefaultWithSensorReadingType(sensorreadingtype: SensorReadingType) -> windows_core::Result { + Self::IOrientationSensorStatics3(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefaultWithSensorReadingType)(windows_core::Interface::as_raw(this), sensorreadingtype, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetDefaultWithSensorReadingTypeAndSensorOptimizationGoal(sensorreadingtype: SensorReadingType, optimizationgoal: SensorOptimizationGoal) -> windows_core::Result { + Self::IOrientationSensorStatics3(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefaultWithSensorReadingTypeAndSensorOptimizationGoal)(windows_core::Interface::as_raw(this), sensorreadingtype, optimizationgoal, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn GetDeviceSelector(readingtype: SensorReadingType) -> windows_core::Result { Self::IOrientationSensorStatics4(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).GetDeviceSelector)(windows_core::Interface::as_raw(this), readingtype, &mut result__).map(|| core::mem::transmute(result__)) }) } + pub fn GetDeviceSelectorWithSensorReadingTypeAndSensorOptimizationGoal(readingtype: SensorReadingType, optimizationgoal: SensorOptimizationGoal) -> windows_core::Result { + Self::IOrientationSensorStatics4(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeviceSelectorWithSensorReadingTypeAndSensorOptimizationGoal)(windows_core::Interface::as_raw(this), readingtype, optimizationgoal, &mut result__).map(|| core::mem::transmute(result__)) + }) + } pub fn FromIdAsync(deviceid: &windows_core::HSTRING) -> windows_core::Result> { Self::IOrientationSensorStatics4(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -9280,6 +29459,50 @@ unsafe impl Sync for OrientationSensor {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct OrientationSensorReading(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(OrientationSensorReading, windows_core::IUnknown, windows_core::IInspectable); +impl OrientationSensorReading { + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn RotationMatrix(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RotationMatrix)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Quaternion(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Quaternion)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PerformanceCount(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PerformanceCount)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Properties(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn YawAccuracy(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).YawAccuracy)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for OrientationSensorReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9296,6 +29519,15 @@ unsafe impl Sync for OrientationSensorReading {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct OrientationSensorReadingChangedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(OrientationSensorReadingChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl OrientationSensorReadingChangedEventArgs { + pub fn Reading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Reading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for OrientationSensorReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9313,18 +29545,98 @@ unsafe impl Sync for OrientationSensorReadingChangedEventArgs {} pub struct Pedometer(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(Pedometer, windows_core::IUnknown, windows_core::IInspectable); impl Pedometer { + pub fn DeviceId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn PowerInMilliwatts(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PowerInMilliwatts)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MinimumReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinimumReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetReportInterval(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetReportInterval)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ReportInterval(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReportInterval)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadingChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveReadingChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn GetCurrentReadings(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentReadings)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn FromIdAsync(deviceid: &windows_core::HSTRING) -> windows_core::Result> { Self::IPedometerStatics(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).FromIdAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn GetDefaultAsync() -> windows_core::Result> { + Self::IPedometerStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefaultAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn GetDeviceSelector() -> windows_core::Result { Self::IPedometerStatics(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).GetDeviceSelector)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) }) } + pub fn GetSystemHistoryAsync(fromtime: super::super::Foundation::DateTime) -> windows_core::Result>> { + Self::IPedometerStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetSystemHistoryAsync)(windows_core::Interface::as_raw(this), fromtime, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetSystemHistoryWithDurationAsync(fromtime: super::super::Foundation::DateTime, duration: super::super::Foundation::TimeSpan) -> windows_core::Result>> { + Self::IPedometerStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetSystemHistoryWithDurationAsync)(windows_core::Interface::as_raw(this), fromtime, duration, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetReadingsFromTriggerDetails(triggerdetails: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::IPedometerStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetReadingsFromTriggerDetails)(windows_core::Interface::as_raw(this), triggerdetails.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IPedometerStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -9381,6 +29693,36 @@ unsafe impl Sync for PedometerDataThreshold {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct PedometerReading(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(PedometerReading, windows_core::IUnknown, windows_core::IInspectable); +impl PedometerReading { + pub fn StepKind(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StepKind)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CumulativeSteps(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CumulativeSteps)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CumulativeStepsDuration(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CumulativeStepsDuration)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for PedometerReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9397,6 +29739,15 @@ unsafe impl Sync for PedometerReading {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct PedometerReadingChangedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(PedometerReadingChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl PedometerReadingChangedEventArgs { + pub fn Reading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Reading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for PedometerReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9428,12 +29779,76 @@ impl windows_core::RuntimeType for PedometerStepKind { pub struct ProximitySensor(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(ProximitySensor, windows_core::IUnknown, windows_core::IInspectable); impl ProximitySensor { + pub fn DeviceId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn MaxDistanceInMillimeters(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxDistanceInMillimeters)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MinDistanceInMillimeters(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinDistanceInMillimeters)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetCurrentReading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentReading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ReadingChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveReadingChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveReadingChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn CreateDisplayOnOffController(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateDisplayOnOffController)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn GetDeviceSelector() -> windows_core::Result { Self::IProximitySensorStatics(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).GetDeviceSelector)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) }) } + pub fn FromId(sensorid: &windows_core::HSTRING) -> windows_core::Result { + Self::IProximitySensorStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FromId)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(sensorid), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetReadingsFromTriggerDetails(triggerdetails: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::IProximitySensorStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetReadingsFromTriggerDetails)(windows_core::Interface::as_raw(this), triggerdetails.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IProximitySensorStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -9512,6 +29927,29 @@ unsafe impl Sync for ProximitySensorDisplayOnOffController {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct ProximitySensorReading(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(ProximitySensorReading, windows_core::IUnknown, windows_core::IInspectable); +impl ProximitySensorReading { + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsDetected(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsDetected)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DistanceInMillimeters(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DistanceInMillimeters)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for ProximitySensorReading { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9528,6 +29966,15 @@ unsafe impl Sync for ProximitySensorReading {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct ProximitySensorReadingChangedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(ProximitySensorReadingChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl ProximitySensorReadingChangedEventArgs { + pub fn Reading(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Reading)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for ProximitySensorReadingChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9544,6 +29991,22 @@ unsafe impl Sync for ProximitySensorReadingChangedEventArgs {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct SensorDataThresholdTriggerDetails(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(SensorDataThresholdTriggerDetails, windows_core::IUnknown, windows_core::IInspectable); +impl SensorDataThresholdTriggerDetails { + pub fn DeviceId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SensorType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SensorType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for SensorDataThresholdTriggerDetails { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9573,6 +30036,36 @@ impl windows_core::RuntimeType for SensorOptimizationGoal { #[derive(Clone, Debug, Eq, PartialEq)] pub struct SensorQuaternion(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(SensorQuaternion, windows_core::IUnknown, windows_core::IInspectable); +impl SensorQuaternion { + pub fn W(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).W)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn X(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).X)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Y(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Y)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Z(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Z)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for SensorQuaternion { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9602,6 +30095,71 @@ impl windows_core::RuntimeType for SensorReadingType { #[derive(Clone, Debug, Eq, PartialEq)] pub struct SensorRotationMatrix(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(SensorRotationMatrix, windows_core::IUnknown, windows_core::IInspectable); +impl SensorRotationMatrix { + pub fn M11(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).M11)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn M12(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).M12)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn M13(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).M13)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn M21(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).M21)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn M22(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).M22)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn M23(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).M23)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn M31(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).M31)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn M32(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).M32)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn M33(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).M33)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for SensorRotationMatrix { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9661,6 +30219,53 @@ impl windows_core::RuntimeType for SimpleOrientation { pub struct SimpleOrientationSensor(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(SimpleOrientationSensor, windows_core::IUnknown, windows_core::IInspectable); impl SimpleOrientationSensor { + pub fn GetCurrentOrientation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentOrientation)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn OrientationChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OrientationChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveOrientationChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveOrientationChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Graphics_Display")] + pub fn SetReadingTransform(&self, value: super::super::Graphics::Display::DisplayOrientations) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetReadingTransform)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Graphics_Display")] + pub fn ReadingTransform(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadingTransform)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DeviceId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetDefault() -> windows_core::Result { + Self::ISimpleOrientationSensorStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn GetDeviceSelector() -> windows_core::Result { Self::ISimpleOrientationSensorStatics2(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -9698,6 +30303,22 @@ unsafe impl Sync for SimpleOrientationSensor {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct SimpleOrientationSensorOrientationChangedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(SimpleOrientationSensorOrientationChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl SimpleOrientationSensorOrientationChangedEventArgs { + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Orientation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Orientation)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for SimpleOrientationSensorOrientationChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -9711,6 +30332,7 @@ impl windows_core::RuntimeName for SimpleOrientationSensorOrientationChangedEven unsafe impl Send for SimpleOrientationSensorOrientationChangedEventArgs {} unsafe impl Sync for SimpleOrientationSensorOrientationChangedEventArgs {} } +#[cfg(feature = "Devices_SmartCards")] pub mod SmartCards{ #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -9730,6 +30352,7 @@ impl windows_core::RuntimeType for SmartCardTriggerType { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Devices.SmartCards.SmartCardTriggerType;i4)"); } } +#[cfg(feature = "Devices_Sms")] pub mod Sms{ #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -9749,6 +30372,222 @@ windows_core::imp::define_interface!(ISmsFilterRule, ISmsFilterRule_Vtbl, 0x40e3 impl windows_core::RuntimeType for ISmsFilterRule { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISmsFilterRule { + const NAME: &'static str = "Windows.Devices.Sms.ISmsFilterRule"; +} +pub trait ISmsFilterRule_Impl: windows_core::IUnknownImpl { + fn MessageType(&self) -> windows_core::Result; + fn ImsiPrefixes(&self) -> windows_core::Result>; + fn DeviceIds(&self) -> windows_core::Result>; + fn SenderNumbers(&self) -> windows_core::Result>; + fn TextMessagePrefixes(&self) -> windows_core::Result>; + fn PortNumbers(&self) -> windows_core::Result>; + fn CellularClass(&self) -> windows_core::Result; + fn SetCellularClass(&self, value: CellularClass) -> windows_core::Result<()>; + fn ProtocolIds(&self) -> windows_core::Result>; + fn TeleserviceIds(&self) -> windows_core::Result>; + fn WapApplicationIds(&self) -> windows_core::Result>; + fn WapContentTypes(&self) -> windows_core::Result>; + fn BroadcastTypes(&self) -> windows_core::Result>; + fn BroadcastChannels(&self) -> windows_core::Result>; +} +impl ISmsFilterRule_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn MessageType(this: *mut core::ffi::c_void, result__: *mut SmsMessageType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRule_Impl::MessageType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ImsiPrefixes(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRule_Impl::ImsiPrefixes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DeviceIds(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRule_Impl::DeviceIds(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SenderNumbers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRule_Impl::SenderNumbers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TextMessagePrefixes(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRule_Impl::TextMessagePrefixes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PortNumbers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRule_Impl::PortNumbers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CellularClass(this: *mut core::ffi::c_void, result__: *mut CellularClass) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRule_Impl::CellularClass(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetCellularClass(this: *mut core::ffi::c_void, value: CellularClass) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISmsFilterRule_Impl::SetCellularClass(this, value).into() + } + } + unsafe extern "system" fn ProtocolIds(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRule_Impl::ProtocolIds(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TeleserviceIds(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRule_Impl::TeleserviceIds(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WapApplicationIds(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRule_Impl::WapApplicationIds(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WapContentTypes(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRule_Impl::WapContentTypes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn BroadcastTypes(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRule_Impl::BroadcastTypes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn BroadcastChannels(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRule_Impl::BroadcastChannels(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + MessageType: MessageType::, + ImsiPrefixes: ImsiPrefixes::, + DeviceIds: DeviceIds::, + SenderNumbers: SenderNumbers::, + TextMessagePrefixes: TextMessagePrefixes::, + PortNumbers: PortNumbers::, + CellularClass: CellularClass::, + SetCellularClass: SetCellularClass::, + ProtocolIds: ProtocolIds::, + TeleserviceIds: TeleserviceIds::, + WapApplicationIds: WapApplicationIds::, + WapContentTypes: WapContentTypes::, + BroadcastTypes: BroadcastTypes::, + BroadcastChannels: BroadcastChannels::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISmsFilterRule_Vtbl { @@ -9772,6 +30611,36 @@ windows_core::imp::define_interface!(ISmsFilterRuleFactory, ISmsFilterRuleFactor impl windows_core::RuntimeType for ISmsFilterRuleFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISmsFilterRuleFactory { + const NAME: &'static str = "Windows.Devices.Sms.ISmsFilterRuleFactory"; +} +pub trait ISmsFilterRuleFactory_Impl: windows_core::IUnknownImpl { + fn CreateFilterRule(&self, messageType: SmsMessageType) -> windows_core::Result; +} +impl ISmsFilterRuleFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFilterRule(this: *mut core::ffi::c_void, messagetype: SmsMessageType, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRuleFactory_Impl::CreateFilterRule(this, messagetype) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFilterRule: CreateFilterRule::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISmsFilterRuleFactory_Vtbl { @@ -9782,6 +30651,50 @@ windows_core::imp::define_interface!(ISmsFilterRules, ISmsFilterRules_Vtbl, 0x4e impl windows_core::RuntimeType for ISmsFilterRules { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISmsFilterRules { + const NAME: &'static str = "Windows.Devices.Sms.ISmsFilterRules"; +} +pub trait ISmsFilterRules_Impl: windows_core::IUnknownImpl { + fn ActionType(&self) -> windows_core::Result; + fn Rules(&self) -> windows_core::Result>; +} +impl ISmsFilterRules_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ActionType(this: *mut core::ffi::c_void, result__: *mut SmsFilterActionType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRules_Impl::ActionType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Rules(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRules_Impl::Rules(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ActionType: ActionType::, + Rules: Rules::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISmsFilterRules_Vtbl { @@ -9793,6 +30706,36 @@ windows_core::imp::define_interface!(ISmsFilterRulesFactory, ISmsFilterRulesFact impl windows_core::RuntimeType for ISmsFilterRulesFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISmsFilterRulesFactory { + const NAME: &'static str = "Windows.Devices.Sms.ISmsFilterRulesFactory"; +} +pub trait ISmsFilterRulesFactory_Impl: windows_core::IUnknownImpl { + fn CreateFilterRules(&self, actionType: SmsFilterActionType) -> windows_core::Result; +} +impl ISmsFilterRulesFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFilterRules(this: *mut core::ffi::c_void, actiontype: SmsFilterActionType, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISmsFilterRulesFactory_Impl::CreateFilterRules(this, actiontype) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFilterRules: CreateFilterRules::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISmsFilterRulesFactory_Vtbl { @@ -9845,6 +30788,107 @@ impl windows_core::RuntimeType for SmsFilterActionType { pub struct SmsFilterRule(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(SmsFilterRule, windows_core::IUnknown, windows_core::IInspectable); impl SmsFilterRule { + pub fn MessageType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MessageType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ImsiPrefixes(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ImsiPrefixes)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeviceIds(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceIds)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SenderNumbers(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SenderNumbers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TextMessagePrefixes(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TextMessagePrefixes)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PortNumbers(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PortNumbers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CellularClass(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CellularClass)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetCellularClass(&self, value: CellularClass) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetCellularClass)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ProtocolIds(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProtocolIds)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TeleserviceIds(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TeleserviceIds)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn WapApplicationIds(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WapApplicationIds)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn WapContentTypes(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WapContentTypes)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn BroadcastTypes(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BroadcastTypes)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn BroadcastChannels(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BroadcastChannels)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFilterRule(messagetype: SmsMessageType) -> windows_core::Result { + Self::ISmsFilterRuleFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFilterRule)(windows_core::Interface::as_raw(this), messagetype, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn ISmsFilterRuleFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -9867,6 +30911,26 @@ unsafe impl Sync for SmsFilterRule {} pub struct SmsFilterRules(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(SmsFilterRules, windows_core::IUnknown, windows_core::IInspectable); impl SmsFilterRules { + pub fn ActionType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ActionType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Rules(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Rules)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFilterRules(actiontype: SmsFilterActionType) -> windows_core::Result { + Self::ISmsFilterRulesFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFilterRules)(windows_core::Interface::as_raw(this), actiontype, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn ISmsFilterRulesFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -9904,6 +30968,7 @@ impl windows_core::RuntimeType for SmsMessageType { } } } +#[cfg(feature = "Foundation")] pub mod Foundation{ #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq)] @@ -9926,6 +30991,10 @@ impl Deferral { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn Complete(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Complete)(windows_core::Interface::as_raw(this)).ok() } + } pub fn Create(handler: P0) -> windows_core::Result where P0: windows_core::Param, @@ -9957,11 +31026,15 @@ impl windows_core::RuntimeType for DeferralCompletedHandler { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } impl DeferralCompletedHandler { - pub fn new windows_core::Result<()> + Send + 'static>(invoke: F) -> Self { + pub fn new windows_core::Result<()> + Send + 'static>(invoke: F) -> Self { let com = DeferralCompletedHandlerBox { vtable: &DeferralCompletedHandlerBox::::VTABLE, count: windows_core::imp::RefCount::new(1), invoke }; unsafe { core::mem::transmute(windows_core::imp::Box::new(com)) } } + pub fn Invoke(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Invoke)(windows_core::Interface::as_raw(this)).ok() } } +} #[repr(C)] #[doc(hidden)] pub struct DeferralCompletedHandler_Vtbl { @@ -9969,12 +31042,12 @@ pub struct DeferralCompletedHandler_Vtbl { Invoke: unsafe extern "system" fn(this: *mut core::ffi::c_void) -> windows_core::HRESULT, } #[repr(C)] -struct DeferralCompletedHandlerBox windows_core::Result<()> + Send + 'static> { +struct DeferralCompletedHandlerBox windows_core::Result<()> + Send + 'static> { vtable: *const DeferralCompletedHandler_Vtbl, invoke: F, count: windows_core::imp::RefCount, } -impl windows_core::Result<()> + Send + 'static> DeferralCompletedHandlerBox { +impl windows_core::Result<()> + Send + 'static> DeferralCompletedHandlerBox { const VTABLE: DeferralCompletedHandler_Vtbl = DeferralCompletedHandler_Vtbl { base__: windows_core::IUnknown_Vtbl { QueryInterface: Self::QueryInterface, AddRef: Self::AddRef, Release: Self::Release }, Invoke: Self::Invoke }; unsafe extern "system" fn QueryInterface(this: *mut core::ffi::c_void, iid: *const windows_core::GUID, interface: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { unsafe { @@ -10062,6 +31135,26 @@ windows_core::imp::define_interface!(IDeferral, IDeferral_Vtbl, 0xd6269732_3b7f_ impl windows_core::RuntimeType for IDeferral { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeferral { + const NAME: &'static str = "Windows.Foundation.IDeferral"; +} +pub trait IDeferral_Impl: IClosable_Impl { + fn Complete(&self) -> windows_core::Result<()>; +} +impl IDeferral_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Complete(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDeferral_Impl::Complete(this).into() + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Complete: Complete:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeferral_Vtbl { @@ -10072,6 +31165,33 @@ windows_core::imp::define_interface!(IDeferralFactory, IDeferralFactory_Vtbl, 0x impl windows_core::RuntimeType for IDeferralFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDeferralFactory { + const NAME: &'static str = "Windows.Foundation.IDeferralFactory"; +} +pub trait IDeferralFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, handler: windows_core::Ref<'_, DeferralCompletedHandler>) -> windows_core::Result; +} +impl IDeferralFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDeferralFactory_Impl::Create(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDeferralFactory_Vtbl { @@ -10085,6 +31205,13 @@ impl windows_core::RuntimeType for IMemoryBuffer { windows_core::imp::interface_hierarchy!(IMemoryBuffer, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(IMemoryBuffer, IClosable); impl IMemoryBuffer { + pub fn CreateReference(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateReference)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Close(&self) -> windows_core::Result<()> { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } @@ -10127,6 +31254,33 @@ windows_core::imp::define_interface!(IMemoryBufferFactory, IMemoryBufferFactory_ impl windows_core::RuntimeType for IMemoryBufferFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IMemoryBufferFactory { + const NAME: &'static str = "Windows.Foundation.IMemoryBufferFactory"; +} +pub trait IMemoryBufferFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, capacity: u32) -> windows_core::Result; +} +impl IMemoryBufferFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, capacity: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMemoryBufferFactory_Impl::Create(this, capacity) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IMemoryBufferFactory_Vtbl { @@ -10147,6 +31301,20 @@ impl IMemoryBufferReference { (windows_core::Interface::vtable(this).Capacity)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) } } + pub fn Closed(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Closed)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveClosed(&self, cookie: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveClosed)(windows_core::Interface::as_raw(this), cookie).ok() } + } pub fn Close(&self) -> windows_core::Result<()> { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } @@ -10157,7 +31325,7 @@ impl windows_core::RuntimeName for IMemoryBufferReference { } pub trait IMemoryBufferReference_Impl: IClosable_Impl { fn Capacity(&self) -> windows_core::Result; - fn Closed(&self, handler: windows_core::Ref>) -> windows_core::Result; + fn Closed(&self, handler: windows_core::Ref<'_, TypedEventHandler>) -> windows_core::Result; fn RemoveClosed(&self, cookie: i64) -> windows_core::Result<()>; } impl IMemoryBufferReference_Vtbl { @@ -10216,6 +31384,224 @@ impl windows_core::RuntimeType for IPropertyValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } windows_core::imp::interface_hierarchy!(IPropertyValue, windows_core::IUnknown, windows_core::IInspectable); +impl IPropertyValue { + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsNumericScalar(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsNumericScalar)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetUInt8(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetUInt8)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetInt16(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInt16)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetUInt16(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetUInt16)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetInt32(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInt32)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetUInt32(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetUInt32)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetInt64(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInt64)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetUInt64(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetUInt64)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetSingle(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetSingle)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetDouble(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDouble)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetChar16(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetChar16)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetBoolean(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetBoolean)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetString(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetGuid(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetGuid)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetDateTime(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDateTime)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetTimeSpan(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetTimeSpan)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetPoint(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetPoint)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetSize(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetSize)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetRect(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetRect)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetUInt8Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetUInt8Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetInt16Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetInt16Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetUInt16Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetUInt16Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetInt32Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetInt32Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetUInt32Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetUInt32Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetInt64Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetInt64Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetUInt64Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetUInt64Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetSingleArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetSingleArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetDoubleArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetDoubleArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetChar16Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetChar16Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetBooleanArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetBooleanArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetStringArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetStringArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetInspectableArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetInspectableArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetGuidArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetGuidArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetDateTimeArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetDateTimeArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetTimeSpanArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetTimeSpanArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetPointArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetPointArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetSizeArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetSizeArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetRectArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetRectArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } +} impl windows_core::RuntimeName for IPropertyValue { const NAME: &'static str = "Windows.Foundation.IPropertyValue"; } @@ -10725,6 +32111,231 @@ impl windows_core::RuntimeType for IRefe impl windows_core::imp::CanInto for IReference { const QUERY: bool = true; } +impl IReference { + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsNumericScalar(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsNumericScalar)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetUInt8(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetUInt8)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetInt16(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInt16)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetUInt16(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetUInt16)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetInt32(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInt32)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetUInt32(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetUInt32)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetInt64(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInt64)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetUInt64(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetUInt64)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetSingle(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetSingle)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetDouble(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDouble)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetChar16(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetChar16)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetBoolean(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetBoolean)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetGuid(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetGuid)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetDateTime(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDateTime)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetTimeSpan(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetTimeSpan)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetPoint(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetPoint)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetSize(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetSize)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetRect(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetRect)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetUInt8Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetUInt8Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetInt16Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetInt16Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetUInt16Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetUInt16Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetInt32Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetInt32Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetUInt32Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetUInt32Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetInt64Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetInt64Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetUInt64Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetUInt64Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetSingleArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetSingleArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetDoubleArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetDoubleArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetChar16Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetChar16Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetBooleanArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetBooleanArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetStringArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetStringArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetInspectableArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetInspectableArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetGuidArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetGuidArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetDateTimeArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetDateTimeArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetTimeSpanArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetTimeSpanArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetPointArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetPointArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetSizeArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetSizeArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetRectArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetRectArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } +} impl windows_core::RuntimeName for IReference { const NAME: &'static str = "Windows.Foundation.IReference"; } @@ -10786,6 +32397,231 @@ impl windows_core::RuntimeType for IRefe impl windows_core::imp::CanInto for IReferenceArray { const QUERY: bool = true; } +impl IReferenceArray { + pub fn Value(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::MaybeUninit::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), windows_core::Array::::set_abi_len(core::mem::transmute(&mut result__)), result__.as_mut_ptr() as *mut _ as _).map(|| result__.assume_init()) + } + } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsNumericScalar(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsNumericScalar)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetUInt8(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetUInt8)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetInt16(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInt16)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetUInt16(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetUInt16)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetInt32(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInt32)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetUInt32(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetUInt32)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetInt64(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInt64)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetUInt64(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetUInt64)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetSingle(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetSingle)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetDouble(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDouble)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetChar16(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetChar16)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetBoolean(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetBoolean)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetGuid(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetGuid)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetDateTime(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDateTime)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetTimeSpan(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetTimeSpan)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetPoint(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetPoint)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetSize(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetSize)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetRect(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetRect)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetUInt8Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetUInt8Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetInt16Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetInt16Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetUInt16Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetUInt16Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetInt32Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetInt32Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetUInt32Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetUInt32Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetInt64Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetInt64Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetUInt64Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetUInt64Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetSingleArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetSingleArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetDoubleArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetDoubleArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetChar16Array(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetChar16Array)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetBooleanArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetBooleanArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetStringArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetStringArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetInspectableArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetInspectableArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetGuidArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetGuidArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetDateTimeArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetDateTimeArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetTimeSpanArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetTimeSpanArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetPointArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetPointArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetSizeArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetSizeArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn GetRectArray(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetRectArray)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } +} impl windows_core::RuntimeName for IReferenceArray { const NAME: &'static str = "Windows.Foundation.IReferenceArray"; } @@ -10836,6 +32672,15 @@ impl windows_core::RuntimeType for IStringable { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } windows_core::imp::interface_hierarchy!(IStringable, windows_core::IUnknown, windows_core::IInspectable); +impl IStringable { + pub fn ToString(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} impl windows_core::RuntimeName for IStringable { const NAME: &'static str = "Windows.Foundation.IStringable"; } @@ -10873,6 +32718,51 @@ windows_core::imp::define_interface!(IUriEscapeStatics, IUriEscapeStatics_Vtbl, impl windows_core::RuntimeType for IUriEscapeStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IUriEscapeStatics { + const NAME: &'static str = "Windows.Foundation.IUriEscapeStatics"; +} +pub trait IUriEscapeStatics_Impl: windows_core::IUnknownImpl { + fn UnescapeComponent(&self, toUnescape: &windows_core::HSTRING) -> windows_core::Result; + fn EscapeComponent(&self, toEscape: &windows_core::HSTRING) -> windows_core::Result; +} +impl IUriEscapeStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn UnescapeComponent(this: *mut core::ffi::c_void, tounescape: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriEscapeStatics_Impl::UnescapeComponent(this, core::mem::transmute(&tounescape)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn EscapeComponent(this: *mut core::ffi::c_void, toescape: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriEscapeStatics_Impl::EscapeComponent(this, core::mem::transmute(&toescape)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + UnescapeComponent: UnescapeComponent::, + EscapeComponent: EscapeComponent::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IUriEscapeStatics_Vtbl { @@ -10884,6 +32774,273 @@ windows_core::imp::define_interface!(IUriRuntimeClass, IUriRuntimeClass_Vtbl, 0x impl windows_core::RuntimeType for IUriRuntimeClass { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IUriRuntimeClass { + const NAME: &'static str = "Windows.Foundation.IUriRuntimeClass"; +} +pub trait IUriRuntimeClass_Impl: windows_core::IUnknownImpl { + fn AbsoluteUri(&self) -> windows_core::Result; + fn DisplayUri(&self) -> windows_core::Result; + fn Domain(&self) -> windows_core::Result; + fn Extension(&self) -> windows_core::Result; + fn Fragment(&self) -> windows_core::Result; + fn Host(&self) -> windows_core::Result; + fn Password(&self) -> windows_core::Result; + fn Path(&self) -> windows_core::Result; + fn Query(&self) -> windows_core::Result; + fn QueryParsed(&self) -> windows_core::Result; + fn RawUri(&self) -> windows_core::Result; + fn SchemeName(&self) -> windows_core::Result; + fn UserName(&self) -> windows_core::Result; + fn Port(&self) -> windows_core::Result; + fn Suspicious(&self) -> windows_core::Result; + fn Equals(&self, pUri: windows_core::Ref<'_, Uri>) -> windows_core::Result; + fn CombineUri(&self, relativeUri: &windows_core::HSTRING) -> windows_core::Result; +} +impl IUriRuntimeClass_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AbsoluteUri(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::AbsoluteUri(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DisplayUri(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::DisplayUri(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Domain(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::Domain(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Extension(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::Extension(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Fragment(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::Fragment(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Host(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::Host(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Password(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::Password(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Path(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::Path(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Query(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::Query(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn QueryParsed(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::QueryParsed(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RawUri(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::RawUri(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SchemeName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::SchemeName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn UserName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::UserName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Port(this: *mut core::ffi::c_void, result__: *mut i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::Port(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Suspicious(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::Suspicious(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Equals(this: *mut core::ffi::c_void, puri: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::Equals(this, core::mem::transmute_copy(&puri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CombineUri(this: *mut core::ffi::c_void, relativeuri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClass_Impl::CombineUri(this, core::mem::transmute(&relativeuri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AbsoluteUri: AbsoluteUri::, + DisplayUri: DisplayUri::, + Domain: Domain::, + Extension: Extension::, + Fragment: Fragment::, + Host: Host::, + Password: Password::, + Path: Path::, + Query: Query::, + QueryParsed: QueryParsed::, + RawUri: RawUri::, + SchemeName: SchemeName::, + UserName: UserName::, + Port: Port::, + Suspicious: Suspicious::, + Equals: Equals::, + CombineUri: CombineUri::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IUriRuntimeClass_Vtbl { @@ -10910,6 +33067,51 @@ windows_core::imp::define_interface!(IUriRuntimeClassFactory, IUriRuntimeClassFa impl windows_core::RuntimeType for IUriRuntimeClassFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IUriRuntimeClassFactory { + const NAME: &'static str = "Windows.Foundation.IUriRuntimeClassFactory"; +} +pub trait IUriRuntimeClassFactory_Impl: windows_core::IUnknownImpl { + fn CreateUri(&self, uri: &windows_core::HSTRING) -> windows_core::Result; + fn CreateWithRelativeUri(&self, baseUri: &windows_core::HSTRING, relativeUri: &windows_core::HSTRING) -> windows_core::Result; +} +impl IUriRuntimeClassFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateUri(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClassFactory_Impl::CreateUri(this, core::mem::transmute(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateWithRelativeUri(this: *mut core::ffi::c_void, baseuri: *mut core::ffi::c_void, relativeuri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClassFactory_Impl::CreateWithRelativeUri(this, core::mem::transmute(&baseuri), core::mem::transmute(&relativeuri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateUri: CreateUri::, + CreateWithRelativeUri: CreateWithRelativeUri::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IUriRuntimeClassFactory_Vtbl { @@ -10921,6 +33123,51 @@ windows_core::imp::define_interface!(IUriRuntimeClassWithAbsoluteCanonicalUri, I impl windows_core::RuntimeType for IUriRuntimeClassWithAbsoluteCanonicalUri { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IUriRuntimeClassWithAbsoluteCanonicalUri { + const NAME: &'static str = "Windows.Foundation.IUriRuntimeClassWithAbsoluteCanonicalUri"; +} +pub trait IUriRuntimeClassWithAbsoluteCanonicalUri_Impl: windows_core::IUnknownImpl { + fn AbsoluteCanonicalUri(&self) -> windows_core::Result; + fn DisplayIri(&self) -> windows_core::Result; +} +impl IUriRuntimeClassWithAbsoluteCanonicalUri_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AbsoluteCanonicalUri(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClassWithAbsoluteCanonicalUri_Impl::AbsoluteCanonicalUri(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DisplayIri(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUriRuntimeClassWithAbsoluteCanonicalUri_Impl::DisplayIri(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AbsoluteCanonicalUri: AbsoluteCanonicalUri::, + DisplayIri: DisplayIri::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IUriRuntimeClassWithAbsoluteCanonicalUri_Vtbl { @@ -10941,7 +33188,14 @@ impl IWwwFormUrlDecoderEntry { (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } } +} impl windows_core::RuntimeName for IWwwFormUrlDecoderEntry { const NAME: &'static str = "Windows.Foundation.IWwwFormUrlDecoderEntry"; } @@ -10998,6 +33252,36 @@ windows_core::imp::define_interface!(IWwwFormUrlDecoderRuntimeClass, IWwwFormUrl impl windows_core::RuntimeType for IWwwFormUrlDecoderRuntimeClass { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IWwwFormUrlDecoderRuntimeClass { + const NAME: &'static str = "Windows.Foundation.IWwwFormUrlDecoderRuntimeClass"; +} +pub trait IWwwFormUrlDecoderRuntimeClass_Impl: windows_collections::IIterable_Impl + windows_collections::IVectorView_Impl { + fn GetFirstValueByName(&self, name: &windows_core::HSTRING) -> windows_core::Result; +} +impl IWwwFormUrlDecoderRuntimeClass_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetFirstValueByName(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWwwFormUrlDecoderRuntimeClass_Impl::GetFirstValueByName(this, core::mem::transmute(&name)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetFirstValueByName: GetFirstValueByName::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IWwwFormUrlDecoderRuntimeClass_Vtbl { @@ -11008,6 +33292,36 @@ windows_core::imp::define_interface!(IWwwFormUrlDecoderRuntimeClassFactory, IWww impl windows_core::RuntimeType for IWwwFormUrlDecoderRuntimeClassFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IWwwFormUrlDecoderRuntimeClassFactory { + const NAME: &'static str = "Windows.Foundation.IWwwFormUrlDecoderRuntimeClassFactory"; +} +pub trait IWwwFormUrlDecoderRuntimeClassFactory_Impl: windows_core::IUnknownImpl { + fn CreateWwwFormUrlDecoder(&self, query: &windows_core::HSTRING) -> windows_core::Result; +} +impl IWwwFormUrlDecoderRuntimeClassFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateWwwFormUrlDecoder(this: *mut core::ffi::c_void, query: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWwwFormUrlDecoderRuntimeClassFactory_Impl::CreateWwwFormUrlDecoder(this, core::mem::transmute(&query)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateWwwFormUrlDecoder: CreateWwwFormUrlDecoder::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IWwwFormUrlDecoderRuntimeClassFactory_Vtbl { @@ -11024,6 +33338,13 @@ impl MemoryBuffer { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn CreateReference(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateReference)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Create(capacity: u32) -> windows_core::Result { Self::IMemoryBufferFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); @@ -11162,11 +33483,19 @@ impl TypedEventHandler { - pub fn new, windows_core::Ref) -> windows_core::Result<()> + Send + 'static>(invoke: F) -> Self { + pub fn new, windows_core::Ref<'_, TResult>) -> windows_core::Result<()> + Send + 'static>(invoke: F) -> Self { let com = TypedEventHandlerBox { vtable: &TypedEventHandlerBox::::VTABLE, count: windows_core::imp::RefCount::new(1), invoke }; unsafe { core::mem::transmute(windows_core::imp::Box::new(com)) } } + pub fn Invoke(&self, sender: P0, args: P1) -> windows_core::Result<()> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Invoke)(windows_core::Interface::as_raw(this), sender.param().abi(), args.param().abi()).ok() } } +} #[repr(C)] #[doc(hidden)] pub struct TypedEventHandler_Vtbl @@ -11180,7 +33509,7 @@ where TResult: core::marker::PhantomData, } #[repr(C)] -struct TypedEventHandlerBox, windows_core::Ref) -> windows_core::Result<()> + Send + 'static> +struct TypedEventHandlerBox, windows_core::Ref<'_, TResult>) -> windows_core::Result<()> + Send + 'static> where TSender: windows_core::RuntimeType + 'static, TResult: windows_core::RuntimeType + 'static, @@ -11189,7 +33518,7 @@ where invoke: F, count: windows_core::imp::RefCount, } -impl, windows_core::Ref) -> windows_core::Result<()> + Send + 'static> TypedEventHandlerBox { +impl, windows_core::Ref<'_, TResult>) -> windows_core::Result<()> + Send + 'static> TypedEventHandlerBox { const VTABLE: TypedEventHandler_Vtbl = TypedEventHandler_Vtbl:: { base__: windows_core::IUnknown_Vtbl { QueryInterface: Self::QueryInterface, AddRef: Self::AddRef, Release: Self::Release }, Invoke: Self::Invoke, @@ -11247,12 +33576,173 @@ pub struct Uri(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(Uri, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(Uri, IStringable); impl Uri { + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn UnescapeComponent(tounescape: &windows_core::HSTRING) -> windows_core::Result { + Self::IUriEscapeStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UnescapeComponent)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(tounescape), &mut result__).map(|| core::mem::transmute(result__)) + }) + } + pub fn EscapeComponent(toescape: &windows_core::HSTRING) -> windows_core::Result { + Self::IUriEscapeStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).EscapeComponent)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(toescape), &mut result__).map(|| core::mem::transmute(result__)) + }) + } + pub fn AbsoluteUri(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AbsoluteUri)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn DisplayUri(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayUri)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Domain(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Domain)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Extension(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Extension)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Fragment(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Fragment)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Host(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Host)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Password(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Password)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Path(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Path)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Query(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Query)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn QueryParsed(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).QueryParsed)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RawUri(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RawUri)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SchemeName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SchemeName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn UserName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UserName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Port(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Port)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Suspicious(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Suspicious)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Equals(&self, puri: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Equals)(windows_core::Interface::as_raw(this), puri.param().abi(), &mut result__).map(|| result__) + } + } + pub fn CombineUri(&self, relativeuri: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CombineUri)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(relativeuri), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn CreateUri(uri: &windows_core::HSTRING) -> windows_core::Result { Self::IUriRuntimeClassFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).CreateUri)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(uri), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn CreateWithRelativeUri(baseuri: &windows_core::HSTRING, relativeuri: &windows_core::HSTRING) -> windows_core::Result { + Self::IUriRuntimeClassFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWithRelativeUri)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(baseuri), core::mem::transmute_copy(relativeuri), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn AbsoluteCanonicalUri(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AbsoluteCanonicalUri)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn DisplayIri(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayIri)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IUriEscapeStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -11287,6 +33777,50 @@ impl WwwFormUrlDecoder { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } + pub fn GetFirstValueByName(&self, name: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFirstValueByName)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn CreateWwwFormUrlDecoder(query: &windows_core::HSTRING) -> windows_core::Result { + Self::IWwwFormUrlDecoderRuntimeClassFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWwwFormUrlDecoder)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(query), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IWwwFormUrlDecoderRuntimeClassFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -11330,7 +33864,14 @@ impl WwwFormUrlDecoderEntry { (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } } +} impl windows_core::RuntimeType for WwwFormUrlDecoderEntry { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -11343,6 +33884,7 @@ impl windows_core::RuntimeName for WwwFormUrlDecoderEntry { } unsafe impl Send for WwwFormUrlDecoderEntry {} unsafe impl Sync for WwwFormUrlDecoderEntry {} +#[cfg(feature = "Foundation_Collections")] pub mod Collections{ #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -11373,6 +33915,22 @@ unsafe impl windows_core::Interface for impl windows_core::RuntimeType for IMapChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::new().push_slice(b"pinterface({9939f4df-050a-4c0f-aa60-77075f9c4777}").push_slice(b";").push_other(K::SIGNATURE).push_slice(b")"); } +impl IMapChangedEventArgs { + pub fn CollectionChange(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CollectionChange)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Key(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Key)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeName for IMapChangedEventArgs { const NAME: &'static str = "Windows.Foundation.Collections.IMapChangedEventArgs"; } @@ -11454,6 +34012,20 @@ impl IObservableMap { + pub fn MapChanged(&self, vhnd: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MapChanged)(windows_core::Interface::as_raw(this), vhnd.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveMapChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveMapChanged)(windows_core::Interface::as_raw(this), token).ok() } + } pub fn First(&self) -> windows_core::Result>> { let this = &windows_core::Interface::cast::>>(self)?; unsafe { @@ -11461,7 +34033,63 @@ impl(&self, key: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Lookup)(windows_core::Interface::as_raw(this), key.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn HasKey(&self, key: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HasKey)(windows_core::Interface::as_raw(this), key.param().abi(), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Insert(&self, key: P0, value: P1) -> windows_core::Result + where + P0: windows_core::Param, + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Insert)(windows_core::Interface::as_raw(this), key.param().abi(), value.param().abi(), &mut result__).map(|| result__) + } + } + pub fn Remove(&self, key: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Remove)(windows_core::Interface::as_raw(this), key.param().abi()).ok() } + } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } +} impl IntoIterator for IObservableMap { type Item = windows_collections::IKeyValuePair; type IntoIter = windows_collections::IIterator; @@ -11484,7 +34112,7 @@ where K: windows_core::RuntimeType + 'static, V: windows_core::RuntimeType + 'static, { - fn MapChanged(&self, vhnd: windows_core::Ref>) -> windows_core::Result; + fn MapChanged(&self, vhnd: windows_core::Ref<'_, MapChangedEventHandler>) -> windows_core::Result; fn RemoveMapChanged(&self, token: i64) -> windows_core::Result<()>; } impl IObservableMap_Vtbl { @@ -11553,6 +34181,20 @@ impl windows_core::imp::CanInto IObservableVector { + pub fn VectorChanged(&self, vhnd: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).VectorChanged)(windows_core::Interface::as_raw(this), vhnd.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveVectorChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveVectorChanged)(windows_core::Interface::as_raw(this), token).ok() } + } pub fn First(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::>(self)?; unsafe { @@ -11560,6 +34202,55 @@ impl IObservableVector { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn SetAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn InsertAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).InsertAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn RemoveAt(&self, index: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAt)(windows_core::Interface::as_raw(this), index).ok() } + } pub fn Append(&self, value: P0) -> windows_core::Result<()> where P0: windows_core::Param, @@ -11567,7 +34258,26 @@ impl IObservableVector { let this = &windows_core::Interface::cast::>(self)?; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } } + pub fn RemoveAtEnd(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAtEnd)(windows_core::Interface::as_raw(this)).ok() } } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn GetMany(&self, startindex: u32, items: &mut [>::Default]) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } + pub fn ReplaceAll(&self, items: &[>::Default]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).ReplaceAll)(windows_core::Interface::as_raw(this), items.len().try_into().unwrap(), core::mem::transmute(items.as_ptr())).ok() } + } +} impl IntoIterator for IObservableVector { type Item = T; type IntoIter = windows_collections::IIterator; @@ -11589,7 +34299,7 @@ pub trait IObservableVector_Impl: windows_collections::IIterable_Impl + wi where T: windows_core::RuntimeType + 'static, { - fn VectorChanged(&self, vhnd: windows_core::Ref>) -> windows_core::Result; + fn VectorChanged(&self, vhnd: windows_core::Ref<'_, VectorChangedEventHandler>) -> windows_core::Result; fn RemoveVectorChanged(&self, token: i64) -> windows_core::Result<()>; } impl IObservableVector_Vtbl { @@ -11648,7 +34358,67 @@ impl IPropertySet { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Lookup(&self, key: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Lookup)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn HasKey(&self, key: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HasKey)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Insert(&self, key: &windows_core::HSTRING, value: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Insert)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), value.param().abi(), &mut result__).map(|| result__) + } + } + pub fn Remove(&self, key: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Remove)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key)).ok() } + } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn MapChanged(&self, vhnd: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MapChanged)(windows_core::Interface::as_raw(this), vhnd.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveMapChanged(&self, token: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveMapChanged)(windows_core::Interface::as_raw(this), token).ok() } + } +} impl IntoIterator for IPropertySet { type Item = windows_collections::IKeyValuePair; type IntoIter = windows_collections::IIterator; @@ -11685,6 +34455,22 @@ impl windows_core::RuntimeType for IVectorChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } windows_core::imp::interface_hierarchy!(IVectorChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl IVectorChangedEventArgs { + pub fn CollectionChange(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CollectionChange)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Index(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Index)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeName for IVectorChangedEventArgs { const NAME: &'static str = "Windows.Foundation.Collections.IVectorChangedEventArgs"; } @@ -11749,11 +34535,19 @@ impl MapChangedEventHandler { - pub fn new>, windows_core::Ref>) -> windows_core::Result<()> + Send + 'static>(invoke: F) -> Self { + pub fn new>, windows_core::Ref<'_, IMapChangedEventArgs>) -> windows_core::Result<()> + Send + 'static>(invoke: F) -> Self { let com = MapChangedEventHandlerBox { vtable: &MapChangedEventHandlerBox::::VTABLE, count: windows_core::imp::RefCount::new(1), invoke }; unsafe { core::mem::transmute(windows_core::imp::Box::new(com)) } } + pub fn Invoke(&self, sender: P0, event: P1) -> windows_core::Result<()> + where + P0: windows_core::Param>, + P1: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Invoke)(windows_core::Interface::as_raw(this), sender.param().abi(), event.param().abi()).ok() } } +} #[repr(C)] #[doc(hidden)] pub struct MapChangedEventHandler_Vtbl @@ -11767,7 +34561,7 @@ where V: core::marker::PhantomData, } #[repr(C)] -struct MapChangedEventHandlerBox>, windows_core::Ref>) -> windows_core::Result<()> + Send + 'static> +struct MapChangedEventHandlerBox>, windows_core::Ref<'_, IMapChangedEventArgs>) -> windows_core::Result<()> + Send + 'static> where K: windows_core::RuntimeType + 'static, V: windows_core::RuntimeType + 'static, @@ -11776,7 +34570,7 @@ where invoke: F, count: windows_core::imp::RefCount, } -impl>, windows_core::Ref>) -> windows_core::Result<()> + Send + 'static> MapChangedEventHandlerBox { +impl>, windows_core::Ref<'_, IMapChangedEventArgs>) -> windows_core::Result<()> + Send + 'static> MapChangedEventHandlerBox { const VTABLE: MapChangedEventHandler_Vtbl = MapChangedEventHandler_Vtbl:: { base__: windows_core::IUnknown_Vtbl { QueryInterface: Self::QueryInterface, AddRef: Self::AddRef, Release: Self::Release }, Invoke: Self::Invoke, @@ -11848,7 +34642,67 @@ impl PropertySet { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Lookup(&self, key: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Lookup)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn HasKey(&self, key: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HasKey)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Insert(&self, key: &windows_core::HSTRING, value: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Insert)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), value.param().abi(), &mut result__).map(|| result__) + } + } + pub fn Remove(&self, key: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Remove)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key)).ok() } + } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn MapChanged(&self, vhnd: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MapChanged)(windows_core::Interface::as_raw(this), vhnd.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveMapChanged(&self, token: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveMapChanged)(windows_core::Interface::as_raw(this), token).ok() } + } +} impl windows_core::RuntimeType for PropertySet { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -11895,7 +34749,64 @@ impl StringMap { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Lookup(&self, key: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Lookup)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), &mut result__).map(|| core::mem::transmute(result__)) + } } + pub fn Size(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn HasKey(&self, key: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HasKey)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Insert(&self, key: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Insert)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), core::mem::transmute_copy(value), &mut result__).map(|| result__) + } + } + pub fn Remove(&self, key: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Remove)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key)).ok() } + } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn MapChanged(&self, vhnd: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MapChanged)(windows_core::Interface::as_raw(this), vhnd.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveMapChanged(&self, token: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveMapChanged)(windows_core::Interface::as_raw(this), token).ok() } + } +} impl windows_core::RuntimeType for StringMap { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::>(); } @@ -11942,7 +34853,67 @@ impl ValueSet { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Lookup(&self, key: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Lookup)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn HasKey(&self, key: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HasKey)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Insert(&self, key: &windows_core::HSTRING, value: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Insert)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), value.param().abi(), &mut result__).map(|| result__) + } + } + pub fn Remove(&self, key: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Remove)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key)).ok() } + } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn MapChanged(&self, vhnd: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MapChanged)(windows_core::Interface::as_raw(this), vhnd.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveMapChanged(&self, token: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveMapChanged)(windows_core::Interface::as_raw(this), token).ok() } + } +} impl windows_core::RuntimeType for ValueSet { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -11982,11 +34953,19 @@ impl windows_core::RuntimeType for Vecto const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::new().push_slice(b"pinterface({0c051752-9fbf-4c70-aa0c-0e4c82d9a761}").push_slice(b";").push_other(T::SIGNATURE).push_slice(b")"); } impl VectorChangedEventHandler { - pub fn new>, windows_core::Ref) -> windows_core::Result<()> + Send + 'static>(invoke: F) -> Self { + pub fn new>, windows_core::Ref<'_, IVectorChangedEventArgs>) -> windows_core::Result<()> + Send + 'static>(invoke: F) -> Self { let com = VectorChangedEventHandlerBox { vtable: &VectorChangedEventHandlerBox::::VTABLE, count: windows_core::imp::RefCount::new(1), invoke }; unsafe { core::mem::transmute(windows_core::imp::Box::new(com)) } } + pub fn Invoke(&self, sender: P0, event: P1) -> windows_core::Result<()> + where + P0: windows_core::Param>, + P1: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Invoke)(windows_core::Interface::as_raw(this), sender.param().abi(), event.param().abi()).ok() } } +} #[repr(C)] #[doc(hidden)] pub struct VectorChangedEventHandler_Vtbl @@ -11998,7 +34977,7 @@ where T: core::marker::PhantomData, } #[repr(C)] -struct VectorChangedEventHandlerBox>, windows_core::Ref) -> windows_core::Result<()> + Send + 'static> +struct VectorChangedEventHandlerBox>, windows_core::Ref<'_, IVectorChangedEventArgs>) -> windows_core::Result<()> + Send + 'static> where T: windows_core::RuntimeType + 'static, { @@ -12006,7 +34985,7 @@ where invoke: F, count: windows_core::imp::RefCount, } -impl>, windows_core::Ref) -> windows_core::Result<()> + Send + 'static> VectorChangedEventHandlerBox { +impl>, windows_core::Ref<'_, IVectorChangedEventArgs>) -> windows_core::Result<()> + Send + 'static> VectorChangedEventHandlerBox { const VTABLE: VectorChangedEventHandler_Vtbl = VectorChangedEventHandler_Vtbl:: { base__: windows_core::IUnknown_Vtbl { QueryInterface: Self::QueryInterface, AddRef: Self::AddRef, Release: Self::Release }, Invoke: Self::Invoke, @@ -12059,7 +35038,731 @@ impl(); +} +impl windows_core::RuntimeName for ILanguage { + const NAME: &'static str = "Windows.Globalization.ILanguage"; +} +pub trait ILanguage_Impl: windows_core::IUnknownImpl { + fn LanguageTag(&self) -> windows_core::Result; + fn DisplayName(&self) -> windows_core::Result; + fn NativeName(&self) -> windows_core::Result; + fn Script(&self) -> windows_core::Result; +} +impl ILanguage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn LanguageTag(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILanguage_Impl::LanguageTag(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DisplayName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILanguage_Impl::DisplayName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NativeName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILanguage_Impl::NativeName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Script(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILanguage_Impl::Script(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + LanguageTag: LanguageTag::, + DisplayName: DisplayName::, + NativeName: NativeName::, + Script: Script::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ILanguage_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub LanguageTag: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub DisplayName: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub NativeName: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Script: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ILanguage2, ILanguage2_Vtbl, 0x6a47e5b5_d94d_4886_a404_a5a5b9d5b494); +impl windows_core::RuntimeType for ILanguage2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ILanguage2 { + const NAME: &'static str = "Windows.Globalization.ILanguage2"; +} +pub trait ILanguage2_Impl: windows_core::IUnknownImpl { + fn LayoutDirection(&self) -> windows_core::Result; +} +impl ILanguage2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn LayoutDirection(this: *mut core::ffi::c_void, result__: *mut LanguageLayoutDirection) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILanguage2_Impl::LayoutDirection(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), LayoutDirection: LayoutDirection:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ILanguage2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub LayoutDirection: unsafe extern "system" fn(*mut core::ffi::c_void, *mut LanguageLayoutDirection) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ILanguage3, ILanguage3_Vtbl, 0xc6af3d10_641a_5ba4_bb43_5e12aed75954); +impl windows_core::RuntimeType for ILanguage3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ILanguage3 { + const NAME: &'static str = "Windows.Globalization.ILanguage3"; +} +pub trait ILanguage3_Impl: windows_core::IUnknownImpl { + fn AbbreviatedName(&self) -> windows_core::Result; +} +impl ILanguage3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AbbreviatedName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILanguage3_Impl::AbbreviatedName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), AbbreviatedName: AbbreviatedName:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ILanguage3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AbbreviatedName: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ILanguageExtensionSubtags, ILanguageExtensionSubtags_Vtbl, 0x7d7daf45_368d_4364_852b_dec927037b85); +impl windows_core::RuntimeType for ILanguageExtensionSubtags { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ILanguageExtensionSubtags { + const NAME: &'static str = "Windows.Globalization.ILanguageExtensionSubtags"; +} +pub trait ILanguageExtensionSubtags_Impl: windows_core::IUnknownImpl { + fn GetExtensionSubtags(&self, singleton: &windows_core::HSTRING) -> windows_core::Result>; +} +impl ILanguageExtensionSubtags_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetExtensionSubtags(this: *mut core::ffi::c_void, singleton: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILanguageExtensionSubtags_Impl::GetExtensionSubtags(this, core::mem::transmute(&singleton)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetExtensionSubtags: GetExtensionSubtags::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ILanguageExtensionSubtags_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub GetExtensionSubtags: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ILanguageFactory, ILanguageFactory_Vtbl, 0x9b0252ac_0c27_44f8_b792_9793fb66c63e); +impl windows_core::RuntimeType for ILanguageFactory { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ILanguageFactory { + const NAME: &'static str = "Windows.Globalization.ILanguageFactory"; +} +pub trait ILanguageFactory_Impl: windows_core::IUnknownImpl { + fn CreateLanguage(&self, languageTag: &windows_core::HSTRING) -> windows_core::Result; +} +impl ILanguageFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateLanguage(this: *mut core::ffi::c_void, languagetag: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILanguageFactory_Impl::CreateLanguage(this, core::mem::transmute(&languagetag)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), CreateLanguage: CreateLanguage:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ILanguageFactory_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub CreateLanguage: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ILanguageStatics, ILanguageStatics_Vtbl, 0xb23cd557_0865_46d4_89b8_d59be8990f0d); +impl windows_core::RuntimeType for ILanguageStatics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ILanguageStatics { + const NAME: &'static str = "Windows.Globalization.ILanguageStatics"; +} +pub trait ILanguageStatics_Impl: windows_core::IUnknownImpl { + fn IsWellFormed(&self, languageTag: &windows_core::HSTRING) -> windows_core::Result; + fn CurrentInputMethodLanguageTag(&self) -> windows_core::Result; +} +impl ILanguageStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsWellFormed(this: *mut core::ffi::c_void, languagetag: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILanguageStatics_Impl::IsWellFormed(this, core::mem::transmute(&languagetag)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CurrentInputMethodLanguageTag(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILanguageStatics_Impl::CurrentInputMethodLanguageTag(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsWellFormed: IsWellFormed::, + CurrentInputMethodLanguageTag: CurrentInputMethodLanguageTag::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ILanguageStatics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsWellFormed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub CurrentInputMethodLanguageTag: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ILanguageStatics2, ILanguageStatics2_Vtbl, 0x30199f6e_914b_4b2a_9d6e_e3b0e27dbe4f); +impl windows_core::RuntimeType for ILanguageStatics2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ILanguageStatics2 { + const NAME: &'static str = "Windows.Globalization.ILanguageStatics2"; +} +pub trait ILanguageStatics2_Impl: windows_core::IUnknownImpl { + fn TrySetInputMethodLanguageTag(&self, languageTag: &windows_core::HSTRING) -> windows_core::Result; +} +impl ILanguageStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TrySetInputMethodLanguageTag(this: *mut core::ffi::c_void, languagetag: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILanguageStatics2_Impl::TrySetInputMethodLanguageTag(this, core::mem::transmute(&languagetag)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + TrySetInputMethodLanguageTag: TrySetInputMethodLanguageTag::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ILanguageStatics2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub TrySetInputMethodLanguageTag: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ILanguageStatics3, ILanguageStatics3_Vtbl, 0xd15ecb5a_71de_5752_9542_fac5b4f27261); +impl windows_core::RuntimeType for ILanguageStatics3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ILanguageStatics3 { + const NAME: &'static str = "Windows.Globalization.ILanguageStatics3"; +} +pub trait ILanguageStatics3_Impl: windows_core::IUnknownImpl { + fn GetMuiCompatibleLanguageListFromLanguageTags(&self, languageTags: windows_core::Ref<'_, windows_collections::IIterable>) -> windows_core::Result>; +} +impl ILanguageStatics3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetMuiCompatibleLanguageListFromLanguageTags(this: *mut core::ffi::c_void, languagetags: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILanguageStatics3_Impl::GetMuiCompatibleLanguageListFromLanguageTags(this, core::mem::transmute_copy(&languagetags)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetMuiCompatibleLanguageListFromLanguageTags: GetMuiCompatibleLanguageListFromLanguageTags::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ILanguageStatics3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub GetMuiCompatibleLanguageListFromLanguageTags: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Language(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(Language, windows_core::IUnknown, windows_core::IInspectable); +impl Language { + pub fn LanguageTag(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LanguageTag)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn DisplayName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn NativeName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NativeName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Script(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Script)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn LayoutDirection(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LayoutDirection)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AbbreviatedName(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AbbreviatedName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetExtensionSubtags(&self, singleton: &windows_core::HSTRING) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetExtensionSubtags)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(singleton), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateLanguage(languagetag: &windows_core::HSTRING) -> windows_core::Result { + Self::ILanguageFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateLanguage)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(languagetag), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn IsWellFormed(languagetag: &windows_core::HSTRING) -> windows_core::Result { + Self::ILanguageStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsWellFormed)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(languagetag), &mut result__).map(|| result__) + }) + } + pub fn CurrentInputMethodLanguageTag() -> windows_core::Result { + Self::ILanguageStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CurrentInputMethodLanguageTag)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + }) + } + pub fn TrySetInputMethodLanguageTag(languagetag: &windows_core::HSTRING) -> windows_core::Result { + Self::ILanguageStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrySetInputMethodLanguageTag)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(languagetag), &mut result__).map(|| result__) + }) + } + pub fn GetMuiCompatibleLanguageListFromLanguageTags(languagetags: P0) -> windows_core::Result> + where + P0: windows_core::Param>, + { + Self::ILanguageStatics3(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMuiCompatibleLanguageListFromLanguageTags)(windows_core::Interface::as_raw(this), languagetags.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn ILanguageFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn ILanguageStatics windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn ILanguageStatics2 windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn ILanguageStatics3 windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for Language { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for Language { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for Language { + const NAME: &'static str = "Windows.Globalization.Language"; +} +unsafe impl Send for Language {} +unsafe impl Sync for Language {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct LanguageLayoutDirection(pub i32); +impl LanguageLayoutDirection { + pub const Ltr: Self = Self(0i32); + pub const Rtl: Self = Self(1i32); + pub const TtbLtr: Self = Self(2i32); + pub const TtbRtl: Self = Self(3i32); +} +impl windows_core::TypeKind for LanguageLayoutDirection { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for LanguageLayoutDirection { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Globalization.LanguageLayoutDirection;i4)"); +} +} +#[cfg(feature = "Graphics")] pub mod Graphics{ +#[cfg(feature = "Graphics_DirectX")] +pub mod DirectX{ +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct DirectXPixelFormat(pub i32); +impl DirectXPixelFormat { + pub const Unknown: Self = Self(0i32); + pub const R32G32B32A32Typeless: Self = Self(1i32); + pub const R32G32B32A32Float: Self = Self(2i32); + pub const R32G32B32A32UInt: Self = Self(3i32); + pub const R32G32B32A32Int: Self = Self(4i32); + pub const R32G32B32Typeless: Self = Self(5i32); + pub const R32G32B32Float: Self = Self(6i32); + pub const R32G32B32UInt: Self = Self(7i32); + pub const R32G32B32Int: Self = Self(8i32); + pub const R16G16B16A16Typeless: Self = Self(9i32); + pub const R16G16B16A16Float: Self = Self(10i32); + pub const R16G16B16A16UIntNormalized: Self = Self(11i32); + pub const R16G16B16A16UInt: Self = Self(12i32); + pub const R16G16B16A16IntNormalized: Self = Self(13i32); + pub const R16G16B16A16Int: Self = Self(14i32); + pub const R32G32Typeless: Self = Self(15i32); + pub const R32G32Float: Self = Self(16i32); + pub const R32G32UInt: Self = Self(17i32); + pub const R32G32Int: Self = Self(18i32); + pub const R32G8X24Typeless: Self = Self(19i32); + pub const D32FloatS8X24UInt: Self = Self(20i32); + pub const R32FloatX8X24Typeless: Self = Self(21i32); + pub const X32TypelessG8X24UInt: Self = Self(22i32); + pub const R10G10B10A2Typeless: Self = Self(23i32); + pub const R10G10B10A2UIntNormalized: Self = Self(24i32); + pub const R10G10B10A2UInt: Self = Self(25i32); + pub const R11G11B10Float: Self = Self(26i32); + pub const R8G8B8A8Typeless: Self = Self(27i32); + pub const R8G8B8A8UIntNormalized: Self = Self(28i32); + pub const R8G8B8A8UIntNormalizedSrgb: Self = Self(29i32); + pub const R8G8B8A8UInt: Self = Self(30i32); + pub const R8G8B8A8IntNormalized: Self = Self(31i32); + pub const R8G8B8A8Int: Self = Self(32i32); + pub const R16G16Typeless: Self = Self(33i32); + pub const R16G16Float: Self = Self(34i32); + pub const R16G16UIntNormalized: Self = Self(35i32); + pub const R16G16UInt: Self = Self(36i32); + pub const R16G16IntNormalized: Self = Self(37i32); + pub const R16G16Int: Self = Self(38i32); + pub const R32Typeless: Self = Self(39i32); + pub const D32Float: Self = Self(40i32); + pub const R32Float: Self = Self(41i32); + pub const R32UInt: Self = Self(42i32); + pub const R32Int: Self = Self(43i32); + pub const R24G8Typeless: Self = Self(44i32); + pub const D24UIntNormalizedS8UInt: Self = Self(45i32); + pub const R24UIntNormalizedX8Typeless: Self = Self(46i32); + pub const X24TypelessG8UInt: Self = Self(47i32); + pub const R8G8Typeless: Self = Self(48i32); + pub const R8G8UIntNormalized: Self = Self(49i32); + pub const R8G8UInt: Self = Self(50i32); + pub const R8G8IntNormalized: Self = Self(51i32); + pub const R8G8Int: Self = Self(52i32); + pub const R16Typeless: Self = Self(53i32); + pub const R16Float: Self = Self(54i32); + pub const D16UIntNormalized: Self = Self(55i32); + pub const R16UIntNormalized: Self = Self(56i32); + pub const R16UInt: Self = Self(57i32); + pub const R16IntNormalized: Self = Self(58i32); + pub const R16Int: Self = Self(59i32); + pub const R8Typeless: Self = Self(60i32); + pub const R8UIntNormalized: Self = Self(61i32); + pub const R8UInt: Self = Self(62i32); + pub const R8IntNormalized: Self = Self(63i32); + pub const R8Int: Self = Self(64i32); + pub const A8UIntNormalized: Self = Self(65i32); + pub const R1UIntNormalized: Self = Self(66i32); + pub const R9G9B9E5SharedExponent: Self = Self(67i32); + pub const R8G8B8G8UIntNormalized: Self = Self(68i32); + pub const G8R8G8B8UIntNormalized: Self = Self(69i32); + pub const BC1Typeless: Self = Self(70i32); + pub const BC1UIntNormalized: Self = Self(71i32); + pub const BC1UIntNormalizedSrgb: Self = Self(72i32); + pub const BC2Typeless: Self = Self(73i32); + pub const BC2UIntNormalized: Self = Self(74i32); + pub const BC2UIntNormalizedSrgb: Self = Self(75i32); + pub const BC3Typeless: Self = Self(76i32); + pub const BC3UIntNormalized: Self = Self(77i32); + pub const BC3UIntNormalizedSrgb: Self = Self(78i32); + pub const BC4Typeless: Self = Self(79i32); + pub const BC4UIntNormalized: Self = Self(80i32); + pub const BC4IntNormalized: Self = Self(81i32); + pub const BC5Typeless: Self = Self(82i32); + pub const BC5UIntNormalized: Self = Self(83i32); + pub const BC5IntNormalized: Self = Self(84i32); + pub const B5G6R5UIntNormalized: Self = Self(85i32); + pub const B5G5R5A1UIntNormalized: Self = Self(86i32); + pub const B8G8R8A8UIntNormalized: Self = Self(87i32); + pub const B8G8R8X8UIntNormalized: Self = Self(88i32); + pub const R10G10B10XRBiasA2UIntNormalized: Self = Self(89i32); + pub const B8G8R8A8Typeless: Self = Self(90i32); + pub const B8G8R8A8UIntNormalizedSrgb: Self = Self(91i32); + pub const B8G8R8X8Typeless: Self = Self(92i32); + pub const B8G8R8X8UIntNormalizedSrgb: Self = Self(93i32); + pub const BC6HTypeless: Self = Self(94i32); + pub const BC6H16UnsignedFloat: Self = Self(95i32); + pub const BC6H16Float: Self = Self(96i32); + pub const BC7Typeless: Self = Self(97i32); + pub const BC7UIntNormalized: Self = Self(98i32); + pub const BC7UIntNormalizedSrgb: Self = Self(99i32); + pub const Ayuv: Self = Self(100i32); + pub const Y410: Self = Self(101i32); + pub const Y416: Self = Self(102i32); + pub const NV12: Self = Self(103i32); + pub const P010: Self = Self(104i32); + pub const P016: Self = Self(105i32); + pub const Opaque420: Self = Self(106i32); + pub const Yuy2: Self = Self(107i32); + pub const Y210: Self = Self(108i32); + pub const Y216: Self = Self(109i32); + pub const NV11: Self = Self(110i32); + pub const AI44: Self = Self(111i32); + pub const IA44: Self = Self(112i32); + pub const P8: Self = Self(113i32); + pub const A8P8: Self = Self(114i32); + pub const B4G4R4A4UIntNormalized: Self = Self(115i32); + pub const P208: Self = Self(130i32); + pub const V208: Self = Self(131i32); + pub const V408: Self = Self(132i32); + pub const SamplerFeedbackMinMipOpaque: Self = Self(189i32); + pub const SamplerFeedbackMipRegionUsedOpaque: Self = Self(190i32); + pub const A4B4G4R4: Self = Self(191i32); +} +impl windows_core::TypeKind for DirectXPixelFormat { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for DirectXPixelFormat { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Graphics.DirectX.DirectXPixelFormat;i4)"); +} +#[cfg(feature = "Graphics_DirectX_Direct3D11")] +pub mod Direct3D11{ +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct Direct3DMultisampleDescription { + pub Count: i32, + pub Quality: i32, +} +impl windows_core::TypeKind for Direct3DMultisampleDescription { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for Direct3DMultisampleDescription { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"struct(Windows.Graphics.DirectX.Direct3D11.Direct3DMultisampleDescription;i4;i4)"); +} +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct Direct3DSurfaceDescription { + pub Width: i32, + pub Height: i32, + pub Format: super::DirectXPixelFormat, + pub MultisampleDescription: Direct3DMultisampleDescription, +} +impl windows_core::TypeKind for Direct3DSurfaceDescription { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for Direct3DSurfaceDescription { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"struct(Windows.Graphics.DirectX.Direct3D11.Direct3DSurfaceDescription;i4;i4;enum(Windows.Graphics.DirectX.DirectXPixelFormat;i4);struct(Windows.Graphics.DirectX.Direct3D11.Direct3DMultisampleDescription;i4;i4))"); +} +windows_core::imp::define_interface!(IDirect3DSurface, IDirect3DSurface_Vtbl, 0x0bf4a146_13c1_4694_bee3_7abf15eaf586); +impl windows_core::RuntimeType for IDirect3DSurface { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IDirect3DSurface, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(IDirect3DSurface, super::super::super::Foundation::IClosable); +impl IDirect3DSurface { + pub fn Description(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Description)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Close(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } + } +} +impl windows_core::RuntimeName for IDirect3DSurface { + const NAME: &'static str = "Windows.Graphics.DirectX.Direct3D11.IDirect3DSurface"; +} +pub trait IDirect3DSurface_Impl: super::super::super::Foundation::IClosable_Impl { + fn Description(&self) -> windows_core::Result; +} +impl IDirect3DSurface_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Description(this: *mut core::ffi::c_void, result__: *mut Direct3DSurfaceDescription) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDirect3DSurface_Impl::Description(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Description: Description:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IDirect3DSurface_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Description: unsafe extern "system" fn(*mut core::ffi::c_void, *mut Direct3DSurfaceDescription) -> windows_core::HRESULT, +} +} +} +#[cfg(feature = "Graphics_Display")] pub mod Display{ #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -12112,12 +35815,34860 @@ impl core::ops::Not for DisplayOrientations { } } } +#[cfg(feature = "Media")] +pub mod Media{ +windows_core::imp::define_interface!(IMediaMarker, IMediaMarker_Vtbl, 0x1803def8_dca5_4b6f_9c20_e3d3c0643625); +impl windows_core::RuntimeType for IMediaMarker { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IMediaMarker, windows_core::IUnknown, windows_core::IInspectable); +impl IMediaMarker { + pub fn Time(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Time)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MediaMarkerType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MediaMarkerType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Text(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Text)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} +impl windows_core::RuntimeName for IMediaMarker { + const NAME: &'static str = "Windows.Media.IMediaMarker"; +} +pub trait IMediaMarker_Impl: windows_core::IUnknownImpl { + fn Time(&self) -> windows_core::Result; + fn MediaMarkerType(&self) -> windows_core::Result; + fn Text(&self) -> windows_core::Result; +} +impl IMediaMarker_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Time(this: *mut core::ffi::c_void, result__: *mut super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaMarker_Impl::Time(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MediaMarkerType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaMarker_Impl::MediaMarkerType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Text(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaMarker_Impl::Text(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Time: Time::, + MediaMarkerType: MediaMarkerType::, + Text: Text::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaMarker_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Time: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub MediaMarkerType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Text: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMusicDisplayProperties, IMusicDisplayProperties_Vtbl, 0x6bbf0c59_d0a0_4d26_92a0_f978e1d18e7b); +impl windows_core::RuntimeType for IMusicDisplayProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMusicDisplayProperties { + const NAME: &'static str = "Windows.Media.IMusicDisplayProperties"; +} +pub trait IMusicDisplayProperties_Impl: windows_core::IUnknownImpl { + fn Title(&self) -> windows_core::Result; + fn SetTitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn AlbumArtist(&self) -> windows_core::Result; + fn SetAlbumArtist(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Artist(&self) -> windows_core::Result; + fn SetArtist(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; +} +impl IMusicDisplayProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Title(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicDisplayProperties_Impl::Title(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetTitle(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMusicDisplayProperties_Impl::SetTitle(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn AlbumArtist(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicDisplayProperties_Impl::AlbumArtist(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAlbumArtist(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMusicDisplayProperties_Impl::SetAlbumArtist(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Artist(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicDisplayProperties_Impl::Artist(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetArtist(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMusicDisplayProperties_Impl::SetArtist(this, core::mem::transmute(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Title: Title::, + SetTitle: SetTitle::, + AlbumArtist: AlbumArtist::, + SetAlbumArtist: SetAlbumArtist::, + Artist: Artist::, + SetArtist: SetArtist::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMusicDisplayProperties_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Title: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetTitle: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub AlbumArtist: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetAlbumArtist: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Artist: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetArtist: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMusicDisplayProperties2, IMusicDisplayProperties2_Vtbl, 0x00368462_97d3_44b9_b00f_008afcefaf18); +impl windows_core::RuntimeType for IMusicDisplayProperties2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMusicDisplayProperties2 { + const NAME: &'static str = "Windows.Media.IMusicDisplayProperties2"; +} +pub trait IMusicDisplayProperties2_Impl: windows_core::IUnknownImpl { + fn AlbumTitle(&self) -> windows_core::Result; + fn SetAlbumTitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TrackNumber(&self) -> windows_core::Result; + fn SetTrackNumber(&self, value: u32) -> windows_core::Result<()>; + fn Genres(&self) -> windows_core::Result>; +} +impl IMusicDisplayProperties2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AlbumTitle(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicDisplayProperties2_Impl::AlbumTitle(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAlbumTitle(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMusicDisplayProperties2_Impl::SetAlbumTitle(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn TrackNumber(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicDisplayProperties2_Impl::TrackNumber(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetTrackNumber(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMusicDisplayProperties2_Impl::SetTrackNumber(this, value).into() + } + } + unsafe extern "system" fn Genres(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicDisplayProperties2_Impl::Genres(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AlbumTitle: AlbumTitle::, + SetAlbumTitle: SetAlbumTitle::, + TrackNumber: TrackNumber::, + SetTrackNumber: SetTrackNumber::, + Genres: Genres::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMusicDisplayProperties2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AlbumTitle: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetAlbumTitle: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub TrackNumber: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetTrackNumber: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub Genres: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMusicDisplayProperties3, IMusicDisplayProperties3_Vtbl, 0x4db51ac1_0681_4e8c_9401_b8159d9eefc7); +impl windows_core::RuntimeType for IMusicDisplayProperties3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMusicDisplayProperties3 { + const NAME: &'static str = "Windows.Media.IMusicDisplayProperties3"; +} +pub trait IMusicDisplayProperties3_Impl: windows_core::IUnknownImpl { + fn AlbumTrackCount(&self) -> windows_core::Result; + fn SetAlbumTrackCount(&self, value: u32) -> windows_core::Result<()>; +} +impl IMusicDisplayProperties3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AlbumTrackCount(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicDisplayProperties3_Impl::AlbumTrackCount(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAlbumTrackCount(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMusicDisplayProperties3_Impl::SetAlbumTrackCount(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AlbumTrackCount: AlbumTrackCount::, + SetAlbumTrackCount: SetAlbumTrackCount::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMusicDisplayProperties3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AlbumTrackCount: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetAlbumTrackCount: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoDisplayProperties, IVideoDisplayProperties_Vtbl, 0x5609fdb1_5d2d_4872_8170_45dee5bc2f5c); +impl windows_core::RuntimeType for IVideoDisplayProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoDisplayProperties { + const NAME: &'static str = "Windows.Media.IVideoDisplayProperties"; +} +pub trait IVideoDisplayProperties_Impl: windows_core::IUnknownImpl { + fn Title(&self) -> windows_core::Result; + fn SetTitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Subtitle(&self) -> windows_core::Result; + fn SetSubtitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; +} +impl IVideoDisplayProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Title(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDisplayProperties_Impl::Title(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetTitle(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVideoDisplayProperties_Impl::SetTitle(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Subtitle(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDisplayProperties_Impl::Subtitle(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetSubtitle(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVideoDisplayProperties_Impl::SetSubtitle(this, core::mem::transmute(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Title: Title::, + SetTitle: SetTitle::, + Subtitle: Subtitle::, + SetSubtitle: SetSubtitle::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoDisplayProperties_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Title: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetTitle: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Subtitle: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetSubtitle: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoDisplayProperties2, IVideoDisplayProperties2_Vtbl, 0xb410e1ce_ab52_41ab_a486_cc10fab152f9); +impl windows_core::RuntimeType for IVideoDisplayProperties2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoDisplayProperties2 { + const NAME: &'static str = "Windows.Media.IVideoDisplayProperties2"; +} +pub trait IVideoDisplayProperties2_Impl: windows_core::IUnknownImpl { + fn Genres(&self) -> windows_core::Result>; +} +impl IVideoDisplayProperties2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Genres(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDisplayProperties2_Impl::Genres(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Genres: Genres:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoDisplayProperties2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Genres: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaPlaybackType(pub i32); +impl MediaPlaybackType { + pub const Unknown: Self = Self(0i32); + pub const Music: Self = Self(1i32); + pub const Video: Self = Self(2i32); + pub const Image: Self = Self(3i32); +} +impl windows_core::TypeKind for MediaPlaybackType { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaPlaybackType { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.MediaPlaybackType;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MusicDisplayProperties(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MusicDisplayProperties, windows_core::IUnknown, windows_core::IInspectable); +impl MusicDisplayProperties { + pub fn Title(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Title)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetTitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetTitle)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn AlbumArtist(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AlbumArtist)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetAlbumArtist(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAlbumArtist)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Artist(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Artist)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetArtist(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetArtist)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn AlbumTitle(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AlbumTitle)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetAlbumTitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAlbumTitle)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn TrackNumber(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrackNumber)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetTrackNumber(&self, value: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetTrackNumber)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Genres(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Genres)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn AlbumTrackCount(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AlbumTrackCount)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAlbumTrackCount(&self, value: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAlbumTrackCount)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for MusicDisplayProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MusicDisplayProperties { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MusicDisplayProperties { + const NAME: &'static str = "Windows.Media.MusicDisplayProperties"; +} +unsafe impl Send for MusicDisplayProperties {} +unsafe impl Sync for MusicDisplayProperties {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VideoDisplayProperties(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(VideoDisplayProperties, windows_core::IUnknown, windows_core::IInspectable); +impl VideoDisplayProperties { + pub fn Title(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Title)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetTitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetTitle)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Subtitle(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Subtitle)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetSubtitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSubtitle)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Genres(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Genres)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for VideoDisplayProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for VideoDisplayProperties { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for VideoDisplayProperties { + const NAME: &'static str = "Windows.Media.VideoDisplayProperties"; +} +unsafe impl Send for VideoDisplayProperties {} +unsafe impl Sync for VideoDisplayProperties {} +#[cfg(feature = "Media_Capture")] +pub mod Capture{ +windows_core::imp::define_interface!(IMediaCaptureVideoProfileMediaDescription, IMediaCaptureVideoProfileMediaDescription_Vtbl, 0x8012afef_b691_49ff_83f2_c1e76eaaea1b); +impl windows_core::RuntimeType for IMediaCaptureVideoProfileMediaDescription { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaCaptureVideoProfileMediaDescription { + const NAME: &'static str = "Windows.Media.Capture.IMediaCaptureVideoProfileMediaDescription"; +} +pub trait IMediaCaptureVideoProfileMediaDescription_Impl: windows_core::IUnknownImpl { + fn Width(&self) -> windows_core::Result; + fn Height(&self) -> windows_core::Result; + fn FrameRate(&self) -> windows_core::Result; + fn IsVariablePhotoSequenceSupported(&self) -> windows_core::Result; + fn IsHdrVideoSupported(&self) -> windows_core::Result; +} +impl IMediaCaptureVideoProfileMediaDescription_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Width(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaCaptureVideoProfileMediaDescription_Impl::Width(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Height(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaCaptureVideoProfileMediaDescription_Impl::Height(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FrameRate(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaCaptureVideoProfileMediaDescription_Impl::FrameRate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsVariablePhotoSequenceSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaCaptureVideoProfileMediaDescription_Impl::IsVariablePhotoSequenceSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsHdrVideoSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaCaptureVideoProfileMediaDescription_Impl::IsHdrVideoSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Width: Width::, + Height: Height::, + FrameRate: FrameRate::, + IsVariablePhotoSequenceSupported: IsVariablePhotoSequenceSupported::, + IsHdrVideoSupported: IsHdrVideoSupported::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaCaptureVideoProfileMediaDescription_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Width: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Height: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub FrameRate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, + #[cfg(feature = "deprecated")] + pub IsVariablePhotoSequenceSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + IsVariablePhotoSequenceSupported: usize, + #[cfg(feature = "deprecated")] + pub IsHdrVideoSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + IsHdrVideoSupported: usize, +} +windows_core::imp::define_interface!(IMediaCaptureVideoProfileMediaDescription2, IMediaCaptureVideoProfileMediaDescription2_Vtbl, 0xc6a6ef13_322d_413a_b85a_68a88e02f4e9); +impl windows_core::RuntimeType for IMediaCaptureVideoProfileMediaDescription2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaCaptureVideoProfileMediaDescription2 { + const NAME: &'static str = "Windows.Media.Capture.IMediaCaptureVideoProfileMediaDescription2"; +} +pub trait IMediaCaptureVideoProfileMediaDescription2_Impl: windows_core::IUnknownImpl { + fn Subtype(&self) -> windows_core::Result; + fn Properties(&self) -> windows_core::Result>; +} +impl IMediaCaptureVideoProfileMediaDescription2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Subtype(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaCaptureVideoProfileMediaDescription2_Impl::Subtype(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaCaptureVideoProfileMediaDescription2_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Subtype: Subtype::, + Properties: Properties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaCaptureVideoProfileMediaDescription2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Subtype: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Properties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaCaptureDeviceExclusiveControlReleaseMode(pub i32); +impl MediaCaptureDeviceExclusiveControlReleaseMode { + pub const OnDispose: Self = Self(0i32); + pub const OnAllStreamsStopped: Self = Self(1i32); +} +impl windows_core::TypeKind for MediaCaptureDeviceExclusiveControlReleaseMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaCaptureDeviceExclusiveControlReleaseMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Capture.MediaCaptureDeviceExclusiveControlReleaseMode;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaCaptureVideoProfileMediaDescription(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaCaptureVideoProfileMediaDescription, windows_core::IUnknown, windows_core::IInspectable); +impl MediaCaptureVideoProfileMediaDescription { + pub fn Width(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Width)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Height(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Height)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn FrameRate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FrameRate)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "deprecated")] + pub fn IsVariablePhotoSequenceSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsVariablePhotoSequenceSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "deprecated")] + pub fn IsHdrVideoSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsHdrVideoSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Subtype(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Subtype)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Properties(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaCaptureVideoProfileMediaDescription { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaCaptureVideoProfileMediaDescription { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaCaptureVideoProfileMediaDescription { + const NAME: &'static str = "Windows.Media.Capture.MediaCaptureVideoProfileMediaDescription"; +} +unsafe impl Send for MediaCaptureVideoProfileMediaDescription {} +unsafe impl Sync for MediaCaptureVideoProfileMediaDescription {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaStreamType(pub i32); +impl MediaStreamType { + pub const VideoPreview: Self = Self(0i32); + pub const VideoRecord: Self = Self(1i32); + pub const Audio: Self = Self(2i32); + pub const Photo: Self = Self(3i32); + pub const Metadata: Self = Self(4i32); +} +impl windows_core::TypeKind for MediaStreamType { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaStreamType { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Capture.MediaStreamType;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct PowerlineFrequency(pub i32); +impl PowerlineFrequency { + pub const Disabled: Self = Self(0i32); + pub const FiftyHertz: Self = Self(1i32); + pub const SixtyHertz: Self = Self(2i32); + pub const Auto: Self = Self(3i32); +} +impl windows_core::TypeKind for PowerlineFrequency { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for PowerlineFrequency { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Capture.PowerlineFrequency;i4)"); +} +#[cfg(feature = "Media_Capture_Frames")] +pub mod Frames{ +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct DepthMediaFrameFormat(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(DepthMediaFrameFormat, windows_core::IUnknown, windows_core::IInspectable); +impl DepthMediaFrameFormat { + pub fn VideoFormat(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).VideoFormat)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DepthScaleInMeters(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DepthScaleInMeters)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for DepthMediaFrameFormat { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for DepthMediaFrameFormat { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for DepthMediaFrameFormat { + const NAME: &'static str = "Windows.Media.Capture.Frames.DepthMediaFrameFormat"; +} +unsafe impl Send for DepthMediaFrameFormat {} +unsafe impl Sync for DepthMediaFrameFormat {} +windows_core::imp::define_interface!(IDepthMediaFrameFormat, IDepthMediaFrameFormat_Vtbl, 0xc312cf40_d729_453e_8780_2e04f140d28e); +impl windows_core::RuntimeType for IDepthMediaFrameFormat { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IDepthMediaFrameFormat { + const NAME: &'static str = "Windows.Media.Capture.Frames.IDepthMediaFrameFormat"; +} +pub trait IDepthMediaFrameFormat_Impl: windows_core::IUnknownImpl { + fn VideoFormat(&self) -> windows_core::Result; + fn DepthScaleInMeters(&self) -> windows_core::Result; +} +impl IDepthMediaFrameFormat_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn VideoFormat(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDepthMediaFrameFormat_Impl::VideoFormat(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DepthScaleInMeters(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDepthMediaFrameFormat_Impl::DepthScaleInMeters(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + VideoFormat: VideoFormat::, + DepthScaleInMeters: DepthScaleInMeters::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IDepthMediaFrameFormat_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub VideoFormat: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub DepthScaleInMeters: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaFrameFormat, IMediaFrameFormat_Vtbl, 0x71902b4e_b279_4a97_a9db_bd5a2fb78f39); +impl windows_core::RuntimeType for IMediaFrameFormat { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_MediaProperties")] +impl windows_core::RuntimeName for IMediaFrameFormat { + const NAME: &'static str = "Windows.Media.Capture.Frames.IMediaFrameFormat"; +} +#[cfg(feature = "Media_MediaProperties")] +pub trait IMediaFrameFormat_Impl: windows_core::IUnknownImpl { + fn MajorType(&self) -> windows_core::Result; + fn Subtype(&self) -> windows_core::Result; + fn FrameRate(&self) -> windows_core::Result; + fn Properties(&self) -> windows_core::Result>; + fn VideoFormat(&self) -> windows_core::Result; +} +#[cfg(feature = "Media_MediaProperties")] +impl IMediaFrameFormat_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn MajorType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameFormat_Impl::MajorType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Subtype(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameFormat_Impl::Subtype(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FrameRate(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameFormat_Impl::FrameRate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameFormat_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn VideoFormat(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameFormat_Impl::VideoFormat(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + MajorType: MajorType::, + Subtype: Subtype::, + FrameRate: FrameRate::, + Properties: Properties::, + VideoFormat: VideoFormat::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaFrameFormat_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub MajorType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Subtype: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Media_MediaProperties")] + pub FrameRate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + FrameRate: usize, + pub Properties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub VideoFormat: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaFrameFormat2, IMediaFrameFormat2_Vtbl, 0x63856340_5e87_4c10_86d1_6df097a6c6a8); +impl windows_core::RuntimeType for IMediaFrameFormat2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_MediaProperties")] +impl windows_core::RuntimeName for IMediaFrameFormat2 { + const NAME: &'static str = "Windows.Media.Capture.Frames.IMediaFrameFormat2"; +} +#[cfg(feature = "Media_MediaProperties")] +pub trait IMediaFrameFormat2_Impl: windows_core::IUnknownImpl { + fn AudioEncodingProperties(&self) -> windows_core::Result; +} +#[cfg(feature = "Media_MediaProperties")] +impl IMediaFrameFormat2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AudioEncodingProperties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameFormat2_Impl::AudioEncodingProperties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AudioEncodingProperties: AudioEncodingProperties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaFrameFormat2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_MediaProperties")] + pub AudioEncodingProperties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + AudioEncodingProperties: usize, +} +windows_core::imp::define_interface!(IMediaFrameSource, IMediaFrameSource_Vtbl, 0xd6782953_90db_46a8_8add_2aa884a8d253); +impl windows_core::RuntimeType for IMediaFrameSource { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Devices_Core")] +impl windows_core::RuntimeName for IMediaFrameSource { + const NAME: &'static str = "Windows.Media.Capture.Frames.IMediaFrameSource"; +} +#[cfg(feature = "Media_Devices_Core")] +pub trait IMediaFrameSource_Impl: windows_core::IUnknownImpl { + fn Info(&self) -> windows_core::Result; + fn Controller(&self) -> windows_core::Result; + fn SupportedFormats(&self) -> windows_core::Result>; + fn CurrentFormat(&self) -> windows_core::Result; + fn SetFormatAsync(&self, format: windows_core::Ref<'_, MediaFrameFormat>) -> windows_core::Result; + fn FormatChanged(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveFormatChanged(&self, token: i64) -> windows_core::Result<()>; + fn TryGetCameraIntrinsics(&self, format: windows_core::Ref<'_, MediaFrameFormat>) -> windows_core::Result; +} +#[cfg(feature = "Media_Devices_Core")] +impl IMediaFrameSource_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Info(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSource_Impl::Info(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Controller(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSource_Impl::Controller(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedFormats(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSource_Impl::SupportedFormats(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CurrentFormat(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSource_Impl::CurrentFormat(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetFormatAsync(this: *mut core::ffi::c_void, format: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSource_Impl::SetFormatAsync(this, core::mem::transmute_copy(&format)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FormatChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSource_Impl::FormatChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveFormatChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaFrameSource_Impl::RemoveFormatChanged(this, token).into() + } + } + unsafe extern "system" fn TryGetCameraIntrinsics(this: *mut core::ffi::c_void, format: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSource_Impl::TryGetCameraIntrinsics(this, core::mem::transmute_copy(&format)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Info: Info::, + Controller: Controller::, + SupportedFormats: SupportedFormats::, + CurrentFormat: CurrentFormat::, + SetFormatAsync: SetFormatAsync::, + FormatChanged: FormatChanged::, + RemoveFormatChanged: RemoveFormatChanged::, + TryGetCameraIntrinsics: TryGetCameraIntrinsics::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaFrameSource_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Info: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Controller: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SupportedFormats: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CurrentFormat: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetFormatAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub FormatChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveFormatChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + #[cfg(feature = "Media_Devices_Core")] + pub TryGetCameraIntrinsics: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Devices_Core"))] + TryGetCameraIntrinsics: usize, +} +windows_core::imp::define_interface!(IMediaFrameSourceController, IMediaFrameSourceController_Vtbl, 0x6d076635_316d_4b8f_b7b6_eeb04a8c6525); +impl windows_core::RuntimeType for IMediaFrameSourceController { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Devices")] +impl windows_core::RuntimeName for IMediaFrameSourceController { + const NAME: &'static str = "Windows.Media.Capture.Frames.IMediaFrameSourceController"; +} +#[cfg(feature = "Media_Devices")] +pub trait IMediaFrameSourceController_Impl: windows_core::IUnknownImpl { + fn GetPropertyAsync(&self, propertyId: &windows_core::HSTRING) -> windows_core::Result>; + fn SetPropertyAsync(&self, propertyId: &windows_core::HSTRING, propertyValue: windows_core::Ref<'_, windows_core::IInspectable>) -> windows_core::Result>; + fn VideoDeviceController(&self) -> windows_core::Result; +} +#[cfg(feature = "Media_Devices")] +impl IMediaFrameSourceController_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetPropertyAsync(this: *mut core::ffi::c_void, propertyid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceController_Impl::GetPropertyAsync(this, core::mem::transmute(&propertyid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPropertyAsync(this: *mut core::ffi::c_void, propertyid: *mut core::ffi::c_void, propertyvalue: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceController_Impl::SetPropertyAsync(this, core::mem::transmute(&propertyid), core::mem::transmute_copy(&propertyvalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn VideoDeviceController(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceController_Impl::VideoDeviceController(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetPropertyAsync: GetPropertyAsync::, + SetPropertyAsync: SetPropertyAsync::, + VideoDeviceController: VideoDeviceController::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaFrameSourceController_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub GetPropertyAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetPropertyAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Media_Devices")] + pub VideoDeviceController: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Devices"))] + VideoDeviceController: usize, +} +windows_core::imp::define_interface!(IMediaFrameSourceController2, IMediaFrameSourceController2_Vtbl, 0xefc49fd4_fcf2_4a03_b4e4_ac9628739bee); +impl windows_core::RuntimeType for IMediaFrameSourceController2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaFrameSourceController2 { + const NAME: &'static str = "Windows.Media.Capture.Frames.IMediaFrameSourceController2"; +} +pub trait IMediaFrameSourceController2_Impl: windows_core::IUnknownImpl { + fn GetPropertyByExtendedIdAsync(&self, extendedPropertyId: &[u8], maxPropertyValueSize: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result>; + fn SetPropertyByExtendedIdAsync(&self, extendedPropertyId: &[u8], propertyValue: &[u8]) -> windows_core::Result>; +} +impl IMediaFrameSourceController2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetPropertyByExtendedIdAsync(this: *mut core::ffi::c_void, extendedpropertyid_array_size: u32, extendedpropertyid: *const u8, maxpropertyvaluesize: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceController2_Impl::GetPropertyByExtendedIdAsync(this, core::slice::from_raw_parts(core::mem::transmute_copy(&extendedpropertyid), extendedpropertyid_array_size as usize), core::mem::transmute_copy(&maxpropertyvaluesize)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPropertyByExtendedIdAsync(this: *mut core::ffi::c_void, extendedpropertyid_array_size: u32, extendedpropertyid: *const u8, propertyvalue_array_size: u32, propertyvalue: *const u8, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceController2_Impl::SetPropertyByExtendedIdAsync(this, core::slice::from_raw_parts(core::mem::transmute_copy(&extendedpropertyid), extendedpropertyid_array_size as usize), core::slice::from_raw_parts(core::mem::transmute_copy(&propertyvalue), propertyvalue_array_size as usize)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetPropertyByExtendedIdAsync: GetPropertyByExtendedIdAsync::, + SetPropertyByExtendedIdAsync: SetPropertyByExtendedIdAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaFrameSourceController2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub GetPropertyByExtendedIdAsync: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const u8, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetPropertyByExtendedIdAsync: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const u8, u32, *const u8, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaFrameSourceController3, IMediaFrameSourceController3_Vtbl, 0x1f0cf815_2464_4651_b1e8_4a82dbdb54de); +impl windows_core::RuntimeType for IMediaFrameSourceController3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Devices")] +impl windows_core::RuntimeName for IMediaFrameSourceController3 { + const NAME: &'static str = "Windows.Media.Capture.Frames.IMediaFrameSourceController3"; +} +#[cfg(feature = "Media_Devices")] +pub trait IMediaFrameSourceController3_Impl: windows_core::IUnknownImpl { + fn AudioDeviceController(&self) -> windows_core::Result; +} +#[cfg(feature = "Media_Devices")] +impl IMediaFrameSourceController3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AudioDeviceController(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceController3_Impl::AudioDeviceController(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AudioDeviceController: AudioDeviceController::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaFrameSourceController3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_Devices")] + pub AudioDeviceController: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Devices"))] + AudioDeviceController: usize, +} +windows_core::imp::define_interface!(IMediaFrameSourceGetPropertyResult, IMediaFrameSourceGetPropertyResult_Vtbl, 0x088616c2_3a64_4bd5_bd2b_e7c898d2f37a); +impl windows_core::RuntimeType for IMediaFrameSourceGetPropertyResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaFrameSourceGetPropertyResult { + const NAME: &'static str = "Windows.Media.Capture.Frames.IMediaFrameSourceGetPropertyResult"; +} +pub trait IMediaFrameSourceGetPropertyResult_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; + fn Value(&self) -> windows_core::Result; +} +impl IMediaFrameSourceGetPropertyResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut MediaFrameSourceGetPropertyStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceGetPropertyResult_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceGetPropertyResult_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Status: Status::, + Value: Value::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaFrameSourceGetPropertyResult_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Status: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaFrameSourceGetPropertyStatus) -> windows_core::HRESULT, + pub Value: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaFrameSourceGroup, IMediaFrameSourceGroup_Vtbl, 0x7f605b87_4832_4b5f_ae3d_412faab37d34); +impl windows_core::RuntimeType for IMediaFrameSourceGroup { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaFrameSourceGroup { + const NAME: &'static str = "Windows.Media.Capture.Frames.IMediaFrameSourceGroup"; +} +pub trait IMediaFrameSourceGroup_Impl: windows_core::IUnknownImpl { + fn Id(&self) -> windows_core::Result; + fn DisplayName(&self) -> windows_core::Result; + fn SourceInfos(&self) -> windows_core::Result>; +} +impl IMediaFrameSourceGroup_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Id(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceGroup_Impl::Id(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DisplayName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceGroup_Impl::DisplayName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SourceInfos(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceGroup_Impl::SourceInfos(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Id: Id::, + DisplayName: DisplayName::, + SourceInfos: SourceInfos::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaFrameSourceGroup_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Id: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub DisplayName: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SourceInfos: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaFrameSourceGroupStatics, IMediaFrameSourceGroupStatics_Vtbl, 0x1c48bfc5_436f_4508_94cf_d5d8b7326445); +impl windows_core::RuntimeType for IMediaFrameSourceGroupStatics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaFrameSourceGroupStatics { + const NAME: &'static str = "Windows.Media.Capture.Frames.IMediaFrameSourceGroupStatics"; +} +pub trait IMediaFrameSourceGroupStatics_Impl: windows_core::IUnknownImpl { + fn FindAllAsync(&self) -> windows_core::Result>>; + fn FromIdAsync(&self, id: &windows_core::HSTRING) -> windows_core::Result>; + fn GetDeviceSelector(&self) -> windows_core::Result; +} +impl IMediaFrameSourceGroupStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FindAllAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceGroupStatics_Impl::FindAllAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FromIdAsync(this: *mut core::ffi::c_void, id: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceGroupStatics_Impl::FromIdAsync(this, core::mem::transmute(&id)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeviceSelector(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceGroupStatics_Impl::GetDeviceSelector(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FindAllAsync: FindAllAsync::, + FromIdAsync: FromIdAsync::, + GetDeviceSelector: GetDeviceSelector::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaFrameSourceGroupStatics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub FindAllAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub FromIdAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetDeviceSelector: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaFrameSourceInfo, IMediaFrameSourceInfo_Vtbl, 0x87bdc9cd_4601_408f_91cf_038318cd0af3); +impl windows_core::RuntimeType for IMediaFrameSourceInfo { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Devices_Enumeration", feature = "Perception_Spatial"))] +impl windows_core::RuntimeName for IMediaFrameSourceInfo { + const NAME: &'static str = "Windows.Media.Capture.Frames.IMediaFrameSourceInfo"; +} +#[cfg(all(feature = "Devices_Enumeration", feature = "Perception_Spatial"))] +pub trait IMediaFrameSourceInfo_Impl: windows_core::IUnknownImpl { + fn Id(&self) -> windows_core::Result; + fn MediaStreamType(&self) -> windows_core::Result; + fn SourceKind(&self) -> windows_core::Result; + fn SourceGroup(&self) -> windows_core::Result; + fn DeviceInformation(&self) -> windows_core::Result; + fn Properties(&self) -> windows_core::Result>; + fn CoordinateSystem(&self) -> windows_core::Result; +} +#[cfg(all(feature = "Devices_Enumeration", feature = "Perception_Spatial"))] +impl IMediaFrameSourceInfo_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Id(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceInfo_Impl::Id(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MediaStreamType(this: *mut core::ffi::c_void, result__: *mut super::MediaStreamType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceInfo_Impl::MediaStreamType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SourceKind(this: *mut core::ffi::c_void, result__: *mut MediaFrameSourceKind) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceInfo_Impl::SourceKind(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SourceGroup(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceInfo_Impl::SourceGroup(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DeviceInformation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceInfo_Impl::DeviceInformation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceInfo_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CoordinateSystem(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceInfo_Impl::CoordinateSystem(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Id: Id::, + MediaStreamType: MediaStreamType::, + SourceKind: SourceKind::, + SourceGroup: SourceGroup::, + DeviceInformation: DeviceInformation::, + Properties: Properties::, + CoordinateSystem: CoordinateSystem::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaFrameSourceInfo_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Id: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub MediaStreamType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::MediaStreamType) -> windows_core::HRESULT, + pub SourceKind: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaFrameSourceKind) -> windows_core::HRESULT, + pub SourceGroup: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Devices_Enumeration")] + pub DeviceInformation: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Devices_Enumeration"))] + DeviceInformation: usize, + pub Properties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Perception_Spatial")] + pub CoordinateSystem: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Perception_Spatial"))] + CoordinateSystem: usize, +} +windows_core::imp::define_interface!(IMediaFrameSourceInfo2, IMediaFrameSourceInfo2_Vtbl, 0x195a7855_6457_42c6_a769_19b65bd32e6e); +impl windows_core::RuntimeType for IMediaFrameSourceInfo2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaFrameSourceInfo2 { + const NAME: &'static str = "Windows.Media.Capture.Frames.IMediaFrameSourceInfo2"; +} +pub trait IMediaFrameSourceInfo2_Impl: windows_core::IUnknownImpl { + fn ProfileId(&self) -> windows_core::Result; + fn VideoProfileMediaDescription(&self) -> windows_core::Result>; +} +impl IMediaFrameSourceInfo2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ProfileId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceInfo2_Impl::ProfileId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn VideoProfileMediaDescription(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceInfo2_Impl::VideoProfileMediaDescription(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ProfileId: ProfileId::, + VideoProfileMediaDescription: VideoProfileMediaDescription::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaFrameSourceInfo2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ProfileId: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub VideoProfileMediaDescription: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaFrameSourceInfo3, IMediaFrameSourceInfo3_Vtbl, 0xca824ab6_66ea_5885_a2b6_26c0eeec3c7b); +impl windows_core::RuntimeType for IMediaFrameSourceInfo3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Devices_Enumeration", feature = "UI_WindowManagement"))] +impl windows_core::RuntimeName for IMediaFrameSourceInfo3 { + const NAME: &'static str = "Windows.Media.Capture.Frames.IMediaFrameSourceInfo3"; +} +#[cfg(all(feature = "Devices_Enumeration", feature = "UI_WindowManagement"))] +pub trait IMediaFrameSourceInfo3_Impl: windows_core::IUnknownImpl { + fn GetRelativePanel(&self, displayRegion: windows_core::Ref<'_, super::super::super::UI::WindowManagement::DisplayRegion>) -> windows_core::Result; +} +#[cfg(all(feature = "Devices_Enumeration", feature = "UI_WindowManagement"))] +impl IMediaFrameSourceInfo3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetRelativePanel(this: *mut core::ffi::c_void, displayregion: *mut core::ffi::c_void, result__: *mut super::super::super::Devices::Enumeration::Panel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceInfo3_Impl::GetRelativePanel(this, core::mem::transmute_copy(&displayregion)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetRelativePanel: GetRelativePanel::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaFrameSourceInfo3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(all(feature = "Devices_Enumeration", feature = "UI_WindowManagement"))] + pub GetRelativePanel: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut super::super::super::Devices::Enumeration::Panel) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Devices_Enumeration", feature = "UI_WindowManagement")))] + GetRelativePanel: usize, +} +windows_core::imp::define_interface!(IMediaFrameSourceInfo4, IMediaFrameSourceInfo4_Vtbl, 0x4817d721_85eb_470c_8f37_43ca5498e41d); +impl windows_core::RuntimeType for IMediaFrameSourceInfo4 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaFrameSourceInfo4 { + const NAME: &'static str = "Windows.Media.Capture.Frames.IMediaFrameSourceInfo4"; +} +pub trait IMediaFrameSourceInfo4_Impl: windows_core::IUnknownImpl { + fn IsShareable(&self) -> windows_core::Result; +} +impl IMediaFrameSourceInfo4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsShareable(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaFrameSourceInfo4_Impl::IsShareable(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), IsShareable: IsShareable:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaFrameSourceInfo4_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsShareable: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoMediaFrameFormat, IVideoMediaFrameFormat_Vtbl, 0x46027fc0_d71b_45c7_8f14_6d9a0ae604e4); +impl windows_core::RuntimeType for IVideoMediaFrameFormat { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoMediaFrameFormat { + const NAME: &'static str = "Windows.Media.Capture.Frames.IVideoMediaFrameFormat"; +} +pub trait IVideoMediaFrameFormat_Impl: windows_core::IUnknownImpl { + fn MediaFrameFormat(&self) -> windows_core::Result; + fn DepthFormat(&self) -> windows_core::Result; + fn Width(&self) -> windows_core::Result; + fn Height(&self) -> windows_core::Result; +} +impl IVideoMediaFrameFormat_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn MediaFrameFormat(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoMediaFrameFormat_Impl::MediaFrameFormat(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DepthFormat(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoMediaFrameFormat_Impl::DepthFormat(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Width(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoMediaFrameFormat_Impl::Width(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Height(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoMediaFrameFormat_Impl::Height(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + MediaFrameFormat: MediaFrameFormat::, + DepthFormat: DepthFormat::, + Width: Width::, + Height: Height::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoMediaFrameFormat_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub MediaFrameFormat: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub DepthFormat: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Width: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Height: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaFrameFormat(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaFrameFormat, windows_core::IUnknown, windows_core::IInspectable); +impl MediaFrameFormat { + pub fn MajorType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MajorType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Subtype(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Subtype)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(feature = "Media_MediaProperties")] + pub fn FrameRate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FrameRate)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Properties(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn VideoFormat(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).VideoFormat)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Media_MediaProperties")] + pub fn AudioEncodingProperties(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AudioEncodingProperties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaFrameFormat { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaFrameFormat { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaFrameFormat { + const NAME: &'static str = "Windows.Media.Capture.Frames.MediaFrameFormat"; +} +unsafe impl Send for MediaFrameFormat {} +unsafe impl Sync for MediaFrameFormat {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaFrameSource(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaFrameSource, windows_core::IUnknown, windows_core::IInspectable); +impl MediaFrameSource { + pub fn Info(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Info)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Controller(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Controller)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SupportedFormats(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedFormats)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CurrentFormat(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CurrentFormat)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetFormatAsync(&self, format: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetFormatAsync)(windows_core::Interface::as_raw(this), format.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn FormatChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FormatChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveFormatChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveFormatChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Media_Devices_Core")] + pub fn TryGetCameraIntrinsics(&self, format: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryGetCameraIntrinsics)(windows_core::Interface::as_raw(this), format.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaFrameSource { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaFrameSource { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaFrameSource { + const NAME: &'static str = "Windows.Media.Capture.Frames.MediaFrameSource"; +} +unsafe impl Send for MediaFrameSource {} +unsafe impl Sync for MediaFrameSource {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaFrameSourceController(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaFrameSourceController, windows_core::IUnknown, windows_core::IInspectable); +impl MediaFrameSourceController { + pub fn GetPropertyAsync(&self, propertyid: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetPropertyAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(propertyid), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetPropertyAsync(&self, propertyid: &windows_core::HSTRING, propertyvalue: P1) -> windows_core::Result> + where + P1: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetPropertyAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(propertyid), propertyvalue.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Media_Devices")] + pub fn VideoDeviceController(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).VideoDeviceController)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetPropertyByExtendedIdAsync(&self, extendedpropertyid: &[u8], maxpropertyvaluesize: P1) -> windows_core::Result> + where + P1: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetPropertyByExtendedIdAsync)(windows_core::Interface::as_raw(this), extendedpropertyid.len().try_into().unwrap(), extendedpropertyid.as_ptr(), maxpropertyvaluesize.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetPropertyByExtendedIdAsync(&self, extendedpropertyid: &[u8], propertyvalue: &[u8]) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetPropertyByExtendedIdAsync)(windows_core::Interface::as_raw(this), extendedpropertyid.len().try_into().unwrap(), extendedpropertyid.as_ptr(), propertyvalue.len().try_into().unwrap(), propertyvalue.as_ptr(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Media_Devices")] + pub fn AudioDeviceController(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AudioDeviceController)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaFrameSourceController { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaFrameSourceController { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaFrameSourceController { + const NAME: &'static str = "Windows.Media.Capture.Frames.MediaFrameSourceController"; +} +unsafe impl Send for MediaFrameSourceController {} +unsafe impl Sync for MediaFrameSourceController {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaFrameSourceGetPropertyResult(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaFrameSourceGetPropertyResult, windows_core::IUnknown, windows_core::IInspectable); +impl MediaFrameSourceGetPropertyResult { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaFrameSourceGetPropertyResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaFrameSourceGetPropertyResult { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaFrameSourceGetPropertyResult { + const NAME: &'static str = "Windows.Media.Capture.Frames.MediaFrameSourceGetPropertyResult"; +} +unsafe impl Send for MediaFrameSourceGetPropertyResult {} +unsafe impl Sync for MediaFrameSourceGetPropertyResult {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaFrameSourceGetPropertyStatus(pub i32); +impl MediaFrameSourceGetPropertyStatus { + pub const Success: Self = Self(0i32); + pub const UnknownFailure: Self = Self(1i32); + pub const NotSupported: Self = Self(2i32); + pub const DeviceNotAvailable: Self = Self(3i32); + pub const MaxPropertyValueSizeTooSmall: Self = Self(4i32); + pub const MaxPropertyValueSizeRequired: Self = Self(5i32); +} +impl windows_core::TypeKind for MediaFrameSourceGetPropertyStatus { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaFrameSourceGetPropertyStatus { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Capture.Frames.MediaFrameSourceGetPropertyStatus;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaFrameSourceGroup(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaFrameSourceGroup, windows_core::IUnknown, windows_core::IInspectable); +impl MediaFrameSourceGroup { + pub fn Id(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Id)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn DisplayName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SourceInfos(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SourceInfos)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn FindAllAsync() -> windows_core::Result>> { + Self::IMediaFrameSourceGroupStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindAllAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn FromIdAsync(id: &windows_core::HSTRING) -> windows_core::Result> { + Self::IMediaFrameSourceGroupStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FromIdAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(id), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetDeviceSelector() -> windows_core::Result { + Self::IMediaFrameSourceGroupStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeviceSelector)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + }) + } + fn IMediaFrameSourceGroupStatics windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for MediaFrameSourceGroup { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaFrameSourceGroup { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaFrameSourceGroup { + const NAME: &'static str = "Windows.Media.Capture.Frames.MediaFrameSourceGroup"; +} +unsafe impl Send for MediaFrameSourceGroup {} +unsafe impl Sync for MediaFrameSourceGroup {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaFrameSourceInfo(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaFrameSourceInfo, windows_core::IUnknown, windows_core::IInspectable); +impl MediaFrameSourceInfo { + pub fn Id(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Id)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn MediaStreamType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MediaStreamType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SourceKind(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SourceKind)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SourceGroup(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SourceGroup)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Devices_Enumeration")] + pub fn DeviceInformation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeviceInformation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Properties(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Perception_Spatial")] + pub fn CoordinateSystem(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CoordinateSystem)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ProfileId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProfileId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn VideoProfileMediaDescription(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).VideoProfileMediaDescription)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Devices_Enumeration", feature = "UI_WindowManagement"))] + pub fn GetRelativePanel(&self, displayregion: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetRelativePanel)(windows_core::Interface::as_raw(this), displayregion.param().abi(), &mut result__).map(|| result__) + } + } + pub fn IsShareable(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsShareable)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for MediaFrameSourceInfo { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaFrameSourceInfo { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaFrameSourceInfo { + const NAME: &'static str = "Windows.Media.Capture.Frames.MediaFrameSourceInfo"; +} +unsafe impl Send for MediaFrameSourceInfo {} +unsafe impl Sync for MediaFrameSourceInfo {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaFrameSourceKind(pub i32); +impl MediaFrameSourceKind { + pub const Custom: Self = Self(0i32); + pub const Color: Self = Self(1i32); + pub const Infrared: Self = Self(2i32); + pub const Depth: Self = Self(3i32); + pub const Audio: Self = Self(4i32); + pub const Image: Self = Self(5i32); + pub const Metadata: Self = Self(6i32); +} +impl windows_core::TypeKind for MediaFrameSourceKind { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaFrameSourceKind { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Capture.Frames.MediaFrameSourceKind;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaFrameSourceSetPropertyStatus(pub i32); +impl MediaFrameSourceSetPropertyStatus { + pub const Success: Self = Self(0i32); + pub const UnknownFailure: Self = Self(1i32); + pub const NotSupported: Self = Self(2i32); + pub const InvalidValue: Self = Self(3i32); + pub const DeviceNotAvailable: Self = Self(4i32); + pub const NotInControl: Self = Self(5i32); +} +impl windows_core::TypeKind for MediaFrameSourceSetPropertyStatus { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaFrameSourceSetPropertyStatus { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Capture.Frames.MediaFrameSourceSetPropertyStatus;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VideoMediaFrameFormat(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(VideoMediaFrameFormat, windows_core::IUnknown, windows_core::IInspectable); +impl VideoMediaFrameFormat { + pub fn MediaFrameFormat(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MediaFrameFormat)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DepthFormat(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DepthFormat)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Width(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Width)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Height(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Height)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for VideoMediaFrameFormat { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for VideoMediaFrameFormat { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for VideoMediaFrameFormat { + const NAME: &'static str = "Windows.Media.Capture.Frames.VideoMediaFrameFormat"; +} +unsafe impl Send for VideoMediaFrameFormat {} +unsafe impl Sync for VideoMediaFrameFormat {} +} +} +#[cfg(feature = "Media_Core")] +pub mod Core{ +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct AudioDecoderDegradation(pub i32); +impl AudioDecoderDegradation { + pub const None: Self = Self(0i32); + pub const DownmixTo2Channels: Self = Self(1i32); + pub const DownmixTo6Channels: Self = Self(2i32); + pub const DownmixTo8Channels: Self = Self(3i32); +} +impl windows_core::TypeKind for AudioDecoderDegradation { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for AudioDecoderDegradation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Core.AudioDecoderDegradation;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct AudioDecoderDegradationReason(pub i32); +impl AudioDecoderDegradationReason { + pub const None: Self = Self(0i32); + pub const LicensingRequirement: Self = Self(1i32); + pub const SpatialAudioNotSupported: Self = Self(2i32); +} +impl windows_core::TypeKind for AudioDecoderDegradationReason { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for AudioDecoderDegradationReason { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Core.AudioDecoderDegradationReason;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AudioTrack(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AudioTrack, windows_core::IUnknown, windows_core::IInspectable, IMediaTrack); +impl AudioTrack { + pub fn OpenFailed(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenFailed)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveOpenFailed(&self, token: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveOpenFailed)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Media_MediaProperties")] + pub fn GetEncodingProperties(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetEncodingProperties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Media_Playback")] + pub fn PlaybackItem(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PlaybackItem)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Name(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SupportInfo(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportInfo)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Id(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Id)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Language(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Language)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn TrackKind(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrackKind)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetLabel(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetLabel)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Label(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Label)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} +impl windows_core::RuntimeType for AudioTrack { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AudioTrack { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AudioTrack { + const NAME: &'static str = "Windows.Media.Core.AudioTrack"; +} +unsafe impl Send for AudioTrack {} +unsafe impl Sync for AudioTrack {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AudioTrackOpenFailedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AudioTrackOpenFailedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl AudioTrackOpenFailedEventArgs { + pub fn ExtendedError(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExtendedError)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for AudioTrackOpenFailedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AudioTrackOpenFailedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AudioTrackOpenFailedEventArgs { + const NAME: &'static str = "Windows.Media.Core.AudioTrackOpenFailedEventArgs"; +} +unsafe impl Send for AudioTrackOpenFailedEventArgs {} +unsafe impl Sync for AudioTrackOpenFailedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AudioTrackSupportInfo(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AudioTrackSupportInfo, windows_core::IUnknown, windows_core::IInspectable); +impl AudioTrackSupportInfo { + pub fn DecoderStatus(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DecoderStatus)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Degradation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Degradation)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DegradationReason(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DegradationReason)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MediaSourceStatus(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MediaSourceStatus)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for AudioTrackSupportInfo { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AudioTrackSupportInfo { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AudioTrackSupportInfo { + const NAME: &'static str = "Windows.Media.Core.AudioTrackSupportInfo"; +} +unsafe impl Send for AudioTrackSupportInfo {} +unsafe impl Sync for AudioTrackSupportInfo {} +windows_core::imp::define_interface!(IAudioTrack, IAudioTrack_Vtbl, 0xf23b6e77_3ef7_40de_b943_068b1321701d); +impl windows_core::RuntimeType for IAudioTrack { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Media_MediaProperties", feature = "Media_Playback"))] +impl windows_core::RuntimeName for IAudioTrack { + const NAME: &'static str = "Windows.Media.Core.IAudioTrack"; +} +#[cfg(all(feature = "Media_MediaProperties", feature = "Media_Playback"))] +pub trait IAudioTrack_Impl: windows_core::IUnknownImpl { + fn OpenFailed(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveOpenFailed(&self, token: i64) -> windows_core::Result<()>; + fn GetEncodingProperties(&self) -> windows_core::Result; + fn PlaybackItem(&self) -> windows_core::Result; + fn Name(&self) -> windows_core::Result; + fn SupportInfo(&self) -> windows_core::Result; +} +#[cfg(all(feature = "Media_MediaProperties", feature = "Media_Playback"))] +impl IAudioTrack_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn OpenFailed(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioTrack_Impl::OpenFailed(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveOpenFailed(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAudioTrack_Impl::RemoveOpenFailed(this, token).into() + } + } + unsafe extern "system" fn GetEncodingProperties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioTrack_Impl::GetEncodingProperties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PlaybackItem(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioTrack_Impl::PlaybackItem(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Name(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioTrack_Impl::Name(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportInfo(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioTrack_Impl::SupportInfo(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + OpenFailed: OpenFailed::, + RemoveOpenFailed: RemoveOpenFailed::, + GetEncodingProperties: GetEncodingProperties::, + PlaybackItem: PlaybackItem::, + Name: Name::, + SupportInfo: SupportInfo::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAudioTrack_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub OpenFailed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveOpenFailed: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + #[cfg(feature = "Media_MediaProperties")] + pub GetEncodingProperties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + GetEncodingProperties: usize, + #[cfg(feature = "Media_Playback")] + pub PlaybackItem: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Playback"))] + PlaybackItem: usize, + pub Name: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SupportInfo: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAudioTrackOpenFailedEventArgs, IAudioTrackOpenFailedEventArgs_Vtbl, 0xeeddb9b9_bb7c_4112_bf76_9384676f824b); +impl windows_core::RuntimeType for IAudioTrackOpenFailedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAudioTrackOpenFailedEventArgs { + const NAME: &'static str = "Windows.Media.Core.IAudioTrackOpenFailedEventArgs"; +} +pub trait IAudioTrackOpenFailedEventArgs_Impl: windows_core::IUnknownImpl { + fn ExtendedError(&self) -> windows_core::Result; +} +impl IAudioTrackOpenFailedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ExtendedError(this: *mut core::ffi::c_void, result__: *mut windows_core::HRESULT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioTrackOpenFailedEventArgs_Impl::ExtendedError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ExtendedError: ExtendedError::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAudioTrackOpenFailedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ExtendedError: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_core::HRESULT) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAudioTrackSupportInfo, IAudioTrackSupportInfo_Vtbl, 0x178beff7_cc39_44a6_b951_4a5653f073fa); +impl windows_core::RuntimeType for IAudioTrackSupportInfo { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAudioTrackSupportInfo { + const NAME: &'static str = "Windows.Media.Core.IAudioTrackSupportInfo"; +} +pub trait IAudioTrackSupportInfo_Impl: windows_core::IUnknownImpl { + fn DecoderStatus(&self) -> windows_core::Result; + fn Degradation(&self) -> windows_core::Result; + fn DegradationReason(&self) -> windows_core::Result; + fn MediaSourceStatus(&self) -> windows_core::Result; +} +impl IAudioTrackSupportInfo_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DecoderStatus(this: *mut core::ffi::c_void, result__: *mut MediaDecoderStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioTrackSupportInfo_Impl::DecoderStatus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Degradation(this: *mut core::ffi::c_void, result__: *mut AudioDecoderDegradation) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioTrackSupportInfo_Impl::Degradation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DegradationReason(this: *mut core::ffi::c_void, result__: *mut AudioDecoderDegradationReason) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioTrackSupportInfo_Impl::DegradationReason(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MediaSourceStatus(this: *mut core::ffi::c_void, result__: *mut MediaSourceStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioTrackSupportInfo_Impl::MediaSourceStatus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DecoderStatus: DecoderStatus::, + Degradation: Degradation::, + DegradationReason: DegradationReason::, + MediaSourceStatus: MediaSourceStatus::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAudioTrackSupportInfo_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub DecoderStatus: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaDecoderStatus) -> windows_core::HRESULT, + pub Degradation: unsafe extern "system" fn(*mut core::ffi::c_void, *mut AudioDecoderDegradation) -> windows_core::HRESULT, + pub DegradationReason: unsafe extern "system" fn(*mut core::ffi::c_void, *mut AudioDecoderDegradationReason) -> windows_core::HRESULT, + pub MediaSourceStatus: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaSourceStatus) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaBinder, IMediaBinder_Vtbl, 0x2b7e40aa_de07_424f_83f1_f1de46c4fa2e); +impl windows_core::RuntimeType for IMediaBinder { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Playback")] +impl windows_core::RuntimeName for IMediaBinder { + const NAME: &'static str = "Windows.Media.Core.IMediaBinder"; +} +#[cfg(feature = "Media_Playback")] +pub trait IMediaBinder_Impl: windows_core::IUnknownImpl { + fn Binding(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveBinding(&self, token: i64) -> windows_core::Result<()>; + fn Token(&self) -> windows_core::Result; + fn SetToken(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Source(&self) -> windows_core::Result; +} +#[cfg(feature = "Media_Playback")] +impl IMediaBinder_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Binding(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBinder_Impl::Binding(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveBinding(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaBinder_Impl::RemoveBinding(this, token).into() + } + } + unsafe extern "system" fn Token(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBinder_Impl::Token(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetToken(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaBinder_Impl::SetToken(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Source(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBinder_Impl::Source(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Binding: Binding::, + RemoveBinding: RemoveBinding::, + Token: Token::, + SetToken: SetToken::, + Source: Source::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaBinder_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Binding: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveBinding: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub Token: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetToken: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Media_Playback")] + pub Source: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Playback"))] + Source: usize, +} +windows_core::imp::define_interface!(IMediaBindingEventArgs, IMediaBindingEventArgs_Vtbl, 0xb61cb25a_1b6d_4630_a86d_2f0837f712e5); +impl windows_core::RuntimeType for IMediaBindingEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMediaBindingEventArgs { + const NAME: &'static str = "Windows.Media.Core.IMediaBindingEventArgs"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMediaBindingEventArgs_Impl: windows_core::IUnknownImpl { + fn Canceled(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveCanceled(&self, token: i64) -> windows_core::Result<()>; + fn MediaBinder(&self) -> windows_core::Result; + fn GetDeferral(&self) -> windows_core::Result; + fn SetUri(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result<()>; + fn SetStream(&self, stream: windows_core::Ref<'_, super::super::Storage::Streams::IRandomAccessStream>, contentType: &windows_core::HSTRING) -> windows_core::Result<()>; + fn SetStreamReference(&self, stream: windows_core::Ref<'_, super::super::Storage::Streams::IRandomAccessStreamReference>, contentType: &windows_core::HSTRING) -> windows_core::Result<()>; +} +#[cfg(feature = "Storage_Streams")] +impl IMediaBindingEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Canceled(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBindingEventArgs_Impl::Canceled(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveCanceled(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaBindingEventArgs_Impl::RemoveCanceled(this, token).into() + } + } + unsafe extern "system" fn MediaBinder(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBindingEventArgs_Impl::MediaBinder(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeferral(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBindingEventArgs_Impl::GetDeferral(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetUri(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaBindingEventArgs_Impl::SetUri(this, core::mem::transmute_copy(&uri)).into() + } + } + unsafe extern "system" fn SetStream(this: *mut core::ffi::c_void, stream: *mut core::ffi::c_void, contenttype: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaBindingEventArgs_Impl::SetStream(this, core::mem::transmute_copy(&stream), core::mem::transmute(&contenttype)).into() + } + } + unsafe extern "system" fn SetStreamReference(this: *mut core::ffi::c_void, stream: *mut core::ffi::c_void, contenttype: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaBindingEventArgs_Impl::SetStreamReference(this, core::mem::transmute_copy(&stream), core::mem::transmute(&contenttype)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Canceled: Canceled::, + RemoveCanceled: RemoveCanceled::, + MediaBinder: MediaBinder::, + GetDeferral: GetDeferral::, + SetUri: SetUri::, + SetStream: SetStream::, + SetStreamReference: SetStreamReference::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaBindingEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Canceled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveCanceled: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub MediaBinder: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetDeferral: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetUri: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Storage_Streams")] + pub SetStream: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + SetStream: usize, + #[cfg(feature = "Storage_Streams")] + pub SetStreamReference: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + SetStreamReference: usize, +} +windows_core::imp::define_interface!(IMediaBindingEventArgs2, IMediaBindingEventArgs2_Vtbl, 0x0464cceb_bb5a_482f_b8ba_f0284c696567); +impl windows_core::RuntimeType for IMediaBindingEventArgs2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Media_Streaming_Adaptive", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IMediaBindingEventArgs2 { + const NAME: &'static str = "Windows.Media.Core.IMediaBindingEventArgs2"; +} +#[cfg(all(feature = "Media_Streaming_Adaptive", feature = "Storage_Streams"))] +pub trait IMediaBindingEventArgs2_Impl: windows_core::IUnknownImpl { + fn SetAdaptiveMediaSource(&self, mediaSource: windows_core::Ref<'_, super::Streaming::Adaptive::AdaptiveMediaSource>) -> windows_core::Result<()>; + fn SetStorageFile(&self, file: windows_core::Ref<'_, super::super::Storage::IStorageFile>) -> windows_core::Result<()>; +} +#[cfg(all(feature = "Media_Streaming_Adaptive", feature = "Storage_Streams"))] +impl IMediaBindingEventArgs2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetAdaptiveMediaSource(this: *mut core::ffi::c_void, mediasource: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaBindingEventArgs2_Impl::SetAdaptiveMediaSource(this, core::mem::transmute_copy(&mediasource)).into() + } + } + unsafe extern "system" fn SetStorageFile(this: *mut core::ffi::c_void, file: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaBindingEventArgs2_Impl::SetStorageFile(this, core::mem::transmute_copy(&file)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetAdaptiveMediaSource: SetAdaptiveMediaSource::, + SetStorageFile: SetStorageFile::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaBindingEventArgs2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_Streaming_Adaptive")] + pub SetAdaptiveMediaSource: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Streaming_Adaptive"))] + SetAdaptiveMediaSource: usize, + #[cfg(feature = "Storage_Streams")] + pub SetStorageFile: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + SetStorageFile: usize, +} +windows_core::imp::define_interface!(IMediaBindingEventArgs3, IMediaBindingEventArgs3_Vtbl, 0xf8eb475e_19be_44fc_a5ed_7aba315037f9); +impl windows_core::RuntimeType for IMediaBindingEventArgs3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Networking_BackgroundTransfer")] +impl windows_core::RuntimeName for IMediaBindingEventArgs3 { + const NAME: &'static str = "Windows.Media.Core.IMediaBindingEventArgs3"; +} +#[cfg(feature = "Networking_BackgroundTransfer")] +pub trait IMediaBindingEventArgs3_Impl: windows_core::IUnknownImpl { + fn SetDownloadOperation(&self, downloadOperation: windows_core::Ref<'_, super::super::Networking::BackgroundTransfer::DownloadOperation>) -> windows_core::Result<()>; +} +#[cfg(feature = "Networking_BackgroundTransfer")] +impl IMediaBindingEventArgs3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetDownloadOperation(this: *mut core::ffi::c_void, downloadoperation: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaBindingEventArgs3_Impl::SetDownloadOperation(this, core::mem::transmute_copy(&downloadoperation)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetDownloadOperation: SetDownloadOperation::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaBindingEventArgs3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Networking_BackgroundTransfer")] + pub SetDownloadOperation: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Networking_BackgroundTransfer"))] + SetDownloadOperation: usize, +} +windows_core::imp::define_interface!(IMediaCue, IMediaCue_Vtbl, 0xc7d15e5d_59dc_431f_a0ee_27744323b36d); +impl windows_core::RuntimeType for IMediaCue { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IMediaCue, windows_core::IUnknown, windows_core::IInspectable); +impl IMediaCue { + pub fn SetStartTime(&self, value: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetStartTime)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn StartTime(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StartTime)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetDuration(&self, value: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDuration)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Duration(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Duration)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetId(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetId)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Id(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Id)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} +impl windows_core::RuntimeName for IMediaCue { + const NAME: &'static str = "Windows.Media.Core.IMediaCue"; +} +pub trait IMediaCue_Impl: windows_core::IUnknownImpl { + fn SetStartTime(&self, value: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; + fn StartTime(&self) -> windows_core::Result; + fn SetDuration(&self, value: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; + fn Duration(&self) -> windows_core::Result; + fn SetId(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Id(&self) -> windows_core::Result; +} +impl IMediaCue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetStartTime(this: *mut core::ffi::c_void, value: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaCue_Impl::SetStartTime(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn StartTime(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaCue_Impl::StartTime(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDuration(this: *mut core::ffi::c_void, value: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaCue_Impl::SetDuration(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Duration(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaCue_Impl::Duration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetId(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaCue_Impl::SetId(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Id(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaCue_Impl::Id(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetStartTime: SetStartTime::, + StartTime: StartTime::, + SetDuration: SetDuration::, + Duration: Duration::, + SetId: SetId::, + Id: Id::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaCue_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SetStartTime: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub StartTime: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub SetDuration: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub Duration: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub SetId: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Id: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaCueEventArgs, IMediaCueEventArgs_Vtbl, 0xd12f47f7_5fa4_4e68_9fe5_32160dcee57e); +impl windows_core::RuntimeType for IMediaCueEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaCueEventArgs { + const NAME: &'static str = "Windows.Media.Core.IMediaCueEventArgs"; +} +pub trait IMediaCueEventArgs_Impl: windows_core::IUnknownImpl { + fn Cue(&self) -> windows_core::Result; +} +impl IMediaCueEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Cue(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaCueEventArgs_Impl::Cue(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Cue: Cue:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaCueEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Cue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaSource, IMediaSource_Vtbl, 0xe7bfb599_a09d_4c21_bcdf_20af4f86b3d9); +impl windows_core::RuntimeType for IMediaSource { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IMediaSource, windows_core::IUnknown, windows_core::IInspectable); +impl windows_core::RuntimeName for IMediaSource { + const NAME: &'static str = "Windows.Media.Core.IMediaSource"; +} +pub trait IMediaSource_Impl: windows_core::IUnknownImpl {} +impl IMediaSource_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaSource_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, +} +#[cfg(feature = "Media_Playback")] +windows_core::imp::define_interface!(IMediaSource2, IMediaSource2_Vtbl, 0x2eb61048_655f_4c37_b813_b4e45dfa0abe); +#[cfg(feature = "Media_Playback")] +impl windows_core::RuntimeType for IMediaSource2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Playback"))] +impl windows_core::RuntimeName for IMediaSource2 { + const NAME: &'static str = "Windows.Media.Core.IMediaSource2"; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Playback"))] +pub trait IMediaSource2_Impl: super::super::Foundation::IClosable_Impl + super::Playback::IMediaPlaybackSource_Impl { + fn OpenOperationCompleted(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveOpenOperationCompleted(&self, token: i64) -> windows_core::Result<()>; + fn CustomProperties(&self) -> windows_core::Result; + fn Duration(&self) -> windows_core::Result>; + fn IsOpen(&self) -> windows_core::Result; + fn ExternalTimedTextSources(&self) -> windows_core::Result>; + fn ExternalTimedMetadataTracks(&self) -> windows_core::Result>; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Playback"))] +impl IMediaSource2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn OpenOperationCompleted(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSource2_Impl::OpenOperationCompleted(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveOpenOperationCompleted(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaSource2_Impl::RemoveOpenOperationCompleted(this, token).into() + } + } + unsafe extern "system" fn CustomProperties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSource2_Impl::CustomProperties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Duration(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSource2_Impl::Duration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsOpen(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSource2_Impl::IsOpen(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ExternalTimedTextSources(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSource2_Impl::ExternalTimedTextSources(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ExternalTimedMetadataTracks(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSource2_Impl::ExternalTimedMetadataTracks(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + OpenOperationCompleted: OpenOperationCompleted::, + RemoveOpenOperationCompleted: RemoveOpenOperationCompleted::, + CustomProperties: CustomProperties::, + Duration: Duration::, + IsOpen: IsOpen::, + ExternalTimedTextSources: ExternalTimedTextSources::, + ExternalTimedMetadataTracks: ExternalTimedMetadataTracks::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[cfg(feature = "Media_Playback")] +#[repr(C)] +#[doc(hidden)] +pub struct IMediaSource2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub OpenOperationCompleted: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveOpenOperationCompleted: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + #[cfg(feature = "Foundation_Collections")] + pub CustomProperties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Foundation_Collections"))] + CustomProperties: usize, + pub Duration: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub IsOpen: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + #[cfg(feature = "Foundation_Collections")] + pub ExternalTimedTextSources: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Foundation_Collections"))] + ExternalTimedTextSources: usize, + #[cfg(feature = "Foundation_Collections")] + pub ExternalTimedMetadataTracks: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Foundation_Collections"))] + ExternalTimedMetadataTracks: usize, +} +#[cfg(feature = "Media_Playback")] +windows_core::imp::define_interface!(IMediaSource3, IMediaSource3_Vtbl, 0xb59f0d9b_4b6e_41ed_bbb4_7c7509a994ad); +#[cfg(feature = "Media_Playback")] +impl windows_core::RuntimeType for IMediaSource3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Playback"))] +impl windows_core::RuntimeName for IMediaSource3 { + const NAME: &'static str = "Windows.Media.Core.IMediaSource3"; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Playback"))] +pub trait IMediaSource3_Impl: super::super::Foundation::IClosable_Impl + super::Playback::IMediaPlaybackSource_Impl + IMediaSource2_Impl { + fn StateChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveStateChanged(&self, token: i64) -> windows_core::Result<()>; + fn State(&self) -> windows_core::Result; + fn Reset(&self) -> windows_core::Result<()>; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Playback"))] +impl IMediaSource3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn StateChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSource3_Impl::StateChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveStateChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaSource3_Impl::RemoveStateChanged(this, token).into() + } + } + unsafe extern "system" fn State(this: *mut core::ffi::c_void, result__: *mut MediaSourceState) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSource3_Impl::State(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Reset(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaSource3_Impl::Reset(this).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + StateChanged: StateChanged::, + RemoveStateChanged: RemoveStateChanged::, + State: State::, + Reset: Reset::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[cfg(feature = "Media_Playback")] +#[repr(C)] +#[doc(hidden)] +pub struct IMediaSource3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub StateChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveStateChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub State: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaSourceState) -> windows_core::HRESULT, + pub Reset: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, +} +#[cfg(feature = "Media_Playback")] +windows_core::imp::define_interface!(IMediaSource4, IMediaSource4_Vtbl, 0xbdafad57_8eff_4c63_85a6_84de0ae3e4f2); +#[cfg(feature = "Media_Playback")] +impl windows_core::RuntimeType for IMediaSource4 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Playback", feature = "Media_Streaming_Adaptive"))] +impl windows_core::RuntimeName for IMediaSource4 { + const NAME: &'static str = "Windows.Media.Core.IMediaSource4"; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Playback", feature = "Media_Streaming_Adaptive"))] +pub trait IMediaSource4_Impl: super::super::Foundation::IClosable_Impl + super::Playback::IMediaPlaybackSource_Impl + IMediaSource2_Impl + IMediaSource3_Impl { + fn AdaptiveMediaSource(&self) -> windows_core::Result; + fn MediaStreamSource(&self) -> windows_core::Result; + fn MseStreamSource(&self) -> windows_core::Result; + fn Uri(&self) -> windows_core::Result; + fn OpenAsync(&self) -> windows_core::Result; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Playback", feature = "Media_Streaming_Adaptive"))] +impl IMediaSource4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AdaptiveMediaSource(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSource4_Impl::AdaptiveMediaSource(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MediaStreamSource(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSource4_Impl::MediaStreamSource(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MseStreamSource(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSource4_Impl::MseStreamSource(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Uri(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSource4_Impl::Uri(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OpenAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSource4_Impl::OpenAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AdaptiveMediaSource: AdaptiveMediaSource::, + MediaStreamSource: MediaStreamSource::, + MseStreamSource: MseStreamSource::, + Uri: Uri::, + OpenAsync: OpenAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[cfg(feature = "Media_Playback")] +#[repr(C)] +#[doc(hidden)] +pub struct IMediaSource4_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_Streaming_Adaptive")] + pub AdaptiveMediaSource: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Streaming_Adaptive"))] + AdaptiveMediaSource: usize, + pub MediaStreamSource: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub MseStreamSource: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Uri: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub OpenAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaSource5, IMediaSource5_Vtbl, 0x331a22ae_ed2e_4a22_94c8_b743a92b3022); +impl windows_core::RuntimeType for IMediaSource5 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Networking_BackgroundTransfer")] +impl windows_core::RuntimeName for IMediaSource5 { + const NAME: &'static str = "Windows.Media.Core.IMediaSource5"; +} +#[cfg(feature = "Networking_BackgroundTransfer")] +pub trait IMediaSource5_Impl: windows_core::IUnknownImpl { + fn DownloadOperation(&self) -> windows_core::Result; +} +#[cfg(feature = "Networking_BackgroundTransfer")] +impl IMediaSource5_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DownloadOperation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSource5_Impl::DownloadOperation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), DownloadOperation: DownloadOperation:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaSource5_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Networking_BackgroundTransfer")] + pub DownloadOperation: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Networking_BackgroundTransfer"))] + DownloadOperation: usize, +} +windows_core::imp::define_interface!(IMediaSourceError, IMediaSourceError_Vtbl, 0x5c0a8965_37c5_4e9d_8d21_1cdee90cecc6); +impl windows_core::RuntimeType for IMediaSourceError { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaSourceError { + const NAME: &'static str = "Windows.Media.Core.IMediaSourceError"; +} +pub trait IMediaSourceError_Impl: windows_core::IUnknownImpl { + fn ExtendedError(&self) -> windows_core::Result; +} +impl IMediaSourceError_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ExtendedError(this: *mut core::ffi::c_void, result__: *mut windows_core::HRESULT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSourceError_Impl::ExtendedError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), ExtendedError: ExtendedError:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaSourceError_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ExtendedError: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_core::HRESULT) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaSourceOpenOperationCompletedEventArgs, IMediaSourceOpenOperationCompletedEventArgs_Vtbl, 0xfc682ceb_e281_477c_a8e0_1acd654114c8); +impl windows_core::RuntimeType for IMediaSourceOpenOperationCompletedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaSourceOpenOperationCompletedEventArgs { + const NAME: &'static str = "Windows.Media.Core.IMediaSourceOpenOperationCompletedEventArgs"; +} +pub trait IMediaSourceOpenOperationCompletedEventArgs_Impl: windows_core::IUnknownImpl { + fn Error(&self) -> windows_core::Result; +} +impl IMediaSourceOpenOperationCompletedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Error(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSourceOpenOperationCompletedEventArgs_Impl::Error(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Error: Error::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaSourceOpenOperationCompletedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Error: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaSourceStateChangedEventArgs, IMediaSourceStateChangedEventArgs_Vtbl, 0x0a30af82_9071_4bac_bc39_ca2a93b717a9); +impl windows_core::RuntimeType for IMediaSourceStateChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaSourceStateChangedEventArgs { + const NAME: &'static str = "Windows.Media.Core.IMediaSourceStateChangedEventArgs"; +} +pub trait IMediaSourceStateChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn OldState(&self) -> windows_core::Result; + fn NewState(&self) -> windows_core::Result; +} +impl IMediaSourceStateChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn OldState(this: *mut core::ffi::c_void, result__: *mut MediaSourceState) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSourceStateChangedEventArgs_Impl::OldState(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NewState(this: *mut core::ffi::c_void, result__: *mut MediaSourceState) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSourceStateChangedEventArgs_Impl::NewState(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + OldState: OldState::, + NewState: NewState::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaSourceStateChangedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub OldState: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaSourceState) -> windows_core::HRESULT, + pub NewState: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaSourceState) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaSourceStatics, IMediaSourceStatics_Vtbl, 0xf77d6fa4_4652_410e_b1d8_e9a5e245a45c); +impl windows_core::RuntimeType for IMediaSourceStatics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Media_Playback", feature = "Media_Streaming_Adaptive", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IMediaSourceStatics { + const NAME: &'static str = "Windows.Media.Core.IMediaSourceStatics"; +} +#[cfg(all(feature = "Media_Playback", feature = "Media_Streaming_Adaptive", feature = "Storage_Streams"))] +pub trait IMediaSourceStatics_Impl: windows_core::IUnknownImpl { + fn CreateFromAdaptiveMediaSource(&self, mediaSource: windows_core::Ref<'_, super::Streaming::Adaptive::AdaptiveMediaSource>) -> windows_core::Result; + fn CreateFromMediaStreamSource(&self, mediaSource: windows_core::Ref<'_, MediaStreamSource>) -> windows_core::Result; + fn CreateFromMseStreamSource(&self, mediaSource: windows_core::Ref<'_, MseStreamSource>) -> windows_core::Result; + fn CreateFromIMediaSource(&self, mediaSource: windows_core::Ref<'_, IMediaSource>) -> windows_core::Result; + fn CreateFromStorageFile(&self, file: windows_core::Ref<'_, super::super::Storage::IStorageFile>) -> windows_core::Result; + fn CreateFromStream(&self, stream: windows_core::Ref<'_, super::super::Storage::Streams::IRandomAccessStream>, contentType: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromStreamReference(&self, stream: windows_core::Ref<'_, super::super::Storage::Streams::IRandomAccessStreamReference>, contentType: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromUri(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result; +} +#[cfg(all(feature = "Media_Playback", feature = "Media_Streaming_Adaptive", feature = "Storage_Streams"))] +impl IMediaSourceStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromAdaptiveMediaSource(this: *mut core::ffi::c_void, mediasource: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSourceStatics_Impl::CreateFromAdaptiveMediaSource(this, core::mem::transmute_copy(&mediasource)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromMediaStreamSource(this: *mut core::ffi::c_void, mediasource: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSourceStatics_Impl::CreateFromMediaStreamSource(this, core::mem::transmute_copy(&mediasource)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromMseStreamSource(this: *mut core::ffi::c_void, mediasource: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSourceStatics_Impl::CreateFromMseStreamSource(this, core::mem::transmute_copy(&mediasource)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromIMediaSource(this: *mut core::ffi::c_void, mediasource: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSourceStatics_Impl::CreateFromIMediaSource(this, core::mem::transmute_copy(&mediasource)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromStorageFile(this: *mut core::ffi::c_void, file: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSourceStatics_Impl::CreateFromStorageFile(this, core::mem::transmute_copy(&file)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromStream(this: *mut core::ffi::c_void, stream: *mut core::ffi::c_void, contenttype: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSourceStatics_Impl::CreateFromStream(this, core::mem::transmute_copy(&stream), core::mem::transmute(&contenttype)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromStreamReference(this: *mut core::ffi::c_void, stream: *mut core::ffi::c_void, contenttype: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSourceStatics_Impl::CreateFromStreamReference(this, core::mem::transmute_copy(&stream), core::mem::transmute(&contenttype)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromUri(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSourceStatics_Impl::CreateFromUri(this, core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromAdaptiveMediaSource: CreateFromAdaptiveMediaSource::, + CreateFromMediaStreamSource: CreateFromMediaStreamSource::, + CreateFromMseStreamSource: CreateFromMseStreamSource::, + CreateFromIMediaSource: CreateFromIMediaSource::, + CreateFromStorageFile: CreateFromStorageFile::, + CreateFromStream: CreateFromStream::, + CreateFromStreamReference: CreateFromStreamReference::, + CreateFromUri: CreateFromUri::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaSourceStatics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(all(feature = "Media_Playback", feature = "Media_Streaming_Adaptive"))] + pub CreateFromAdaptiveMediaSource: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Media_Playback", feature = "Media_Streaming_Adaptive")))] + CreateFromAdaptiveMediaSource: usize, + #[cfg(feature = "Media_Playback")] + pub CreateFromMediaStreamSource: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Playback"))] + CreateFromMediaStreamSource: usize, + #[cfg(feature = "Media_Playback")] + pub CreateFromMseStreamSource: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Playback"))] + CreateFromMseStreamSource: usize, + #[cfg(feature = "Media_Playback")] + pub CreateFromIMediaSource: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Playback"))] + CreateFromIMediaSource: usize, + #[cfg(all(feature = "Media_Playback", feature = "Storage_Streams"))] + pub CreateFromStorageFile: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Media_Playback", feature = "Storage_Streams")))] + CreateFromStorageFile: usize, + #[cfg(all(feature = "Media_Playback", feature = "Storage_Streams"))] + pub CreateFromStream: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Media_Playback", feature = "Storage_Streams")))] + CreateFromStream: usize, + #[cfg(all(feature = "Media_Playback", feature = "Storage_Streams"))] + pub CreateFromStreamReference: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Media_Playback", feature = "Storage_Streams")))] + CreateFromStreamReference: usize, + #[cfg(feature = "Media_Playback")] + pub CreateFromUri: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Playback"))] + CreateFromUri: usize, +} +windows_core::imp::define_interface!(IMediaSourceStatics2, IMediaSourceStatics2_Vtbl, 0xeee161a4_7f13_4896_b8cb_df0de5bcb9f1); +impl windows_core::RuntimeType for IMediaSourceStatics2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Playback")] +impl windows_core::RuntimeName for IMediaSourceStatics2 { + const NAME: &'static str = "Windows.Media.Core.IMediaSourceStatics2"; +} +#[cfg(feature = "Media_Playback")] +pub trait IMediaSourceStatics2_Impl: windows_core::IUnknownImpl { + fn CreateFromMediaBinder(&self, binder: windows_core::Ref<'_, MediaBinder>) -> windows_core::Result; +} +#[cfg(feature = "Media_Playback")] +impl IMediaSourceStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromMediaBinder(this: *mut core::ffi::c_void, binder: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSourceStatics2_Impl::CreateFromMediaBinder(this, core::mem::transmute_copy(&binder)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromMediaBinder: CreateFromMediaBinder::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaSourceStatics2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_Playback")] + pub CreateFromMediaBinder: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Playback"))] + CreateFromMediaBinder: usize, +} +windows_core::imp::define_interface!(IMediaSourceStatics3, IMediaSourceStatics3_Vtbl, 0x453a30d6_2bea_4122_9f73_eace04526e35); +impl windows_core::RuntimeType for IMediaSourceStatics3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Media_Capture_Frames", feature = "Media_Playback"))] +impl windows_core::RuntimeName for IMediaSourceStatics3 { + const NAME: &'static str = "Windows.Media.Core.IMediaSourceStatics3"; +} +#[cfg(all(feature = "Media_Capture_Frames", feature = "Media_Playback"))] +pub trait IMediaSourceStatics3_Impl: windows_core::IUnknownImpl { + fn CreateFromMediaFrameSource(&self, frameSource: windows_core::Ref<'_, super::Capture::Frames::MediaFrameSource>) -> windows_core::Result; +} +#[cfg(all(feature = "Media_Capture_Frames", feature = "Media_Playback"))] +impl IMediaSourceStatics3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromMediaFrameSource(this: *mut core::ffi::c_void, framesource: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSourceStatics3_Impl::CreateFromMediaFrameSource(this, core::mem::transmute_copy(&framesource)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromMediaFrameSource: CreateFromMediaFrameSource::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaSourceStatics3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(all(feature = "Media_Capture_Frames", feature = "Media_Playback"))] + pub CreateFromMediaFrameSource: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Media_Capture_Frames", feature = "Media_Playback")))] + CreateFromMediaFrameSource: usize, +} +windows_core::imp::define_interface!(IMediaSourceStatics4, IMediaSourceStatics4_Vtbl, 0x281b3bfc_e50a_4428_a500_9c4ed918d3f0); +impl windows_core::RuntimeType for IMediaSourceStatics4 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Media_Playback", feature = "Networking_BackgroundTransfer"))] +impl windows_core::RuntimeName for IMediaSourceStatics4 { + const NAME: &'static str = "Windows.Media.Core.IMediaSourceStatics4"; +} +#[cfg(all(feature = "Media_Playback", feature = "Networking_BackgroundTransfer"))] +pub trait IMediaSourceStatics4_Impl: windows_core::IUnknownImpl { + fn CreateFromDownloadOperation(&self, downloadOperation: windows_core::Ref<'_, super::super::Networking::BackgroundTransfer::DownloadOperation>) -> windows_core::Result; +} +#[cfg(all(feature = "Media_Playback", feature = "Networking_BackgroundTransfer"))] +impl IMediaSourceStatics4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromDownloadOperation(this: *mut core::ffi::c_void, downloadoperation: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaSourceStatics4_Impl::CreateFromDownloadOperation(this, core::mem::transmute_copy(&downloadoperation)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromDownloadOperation: CreateFromDownloadOperation::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaSourceStatics4_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(all(feature = "Media_Playback", feature = "Networking_BackgroundTransfer"))] + pub CreateFromDownloadOperation: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Media_Playback", feature = "Networking_BackgroundTransfer")))] + CreateFromDownloadOperation: usize, +} +windows_core::imp::define_interface!(IMediaStreamDescriptor, IMediaStreamDescriptor_Vtbl, 0x80f16e6e_92f7_451e_97d2_afd80742da70); +impl windows_core::RuntimeType for IMediaStreamDescriptor { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IMediaStreamDescriptor, windows_core::IUnknown, windows_core::IInspectable); +impl IMediaStreamDescriptor { + pub fn IsSelected(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsSelected)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetName(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetName)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Name(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetLanguage(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetLanguage)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Language(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Language)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} +impl windows_core::RuntimeName for IMediaStreamDescriptor { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamDescriptor"; +} +pub trait IMediaStreamDescriptor_Impl: windows_core::IUnknownImpl { + fn IsSelected(&self) -> windows_core::Result; + fn SetName(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Name(&self) -> windows_core::Result; + fn SetLanguage(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Language(&self) -> windows_core::Result; +} +impl IMediaStreamDescriptor_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsSelected(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamDescriptor_Impl::IsSelected(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetName(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamDescriptor_Impl::SetName(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Name(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamDescriptor_Impl::Name(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetLanguage(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamDescriptor_Impl::SetLanguage(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Language(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamDescriptor_Impl::Language(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsSelected: IsSelected::, + SetName: SetName::, + Name: Name::, + SetLanguage: SetLanguage::, + Language: Language::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamDescriptor_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsSelected: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetName: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Name: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetLanguage: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Language: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSample, IMediaStreamSample_Vtbl, 0x5c8db627_4b80_4361_9837_6cb7481ad9d6); +impl windows_core::RuntimeType for IMediaStreamSample { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMediaStreamSample { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSample"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMediaStreamSample_Impl: windows_core::IUnknownImpl { + fn Processed(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveProcessed(&self, token: i64) -> windows_core::Result<()>; + fn Buffer(&self) -> windows_core::Result; + fn Timestamp(&self) -> windows_core::Result; + fn ExtendedProperties(&self) -> windows_core::Result; + fn Protection(&self) -> windows_core::Result; + fn SetDecodeTimestamp(&self, value: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; + fn DecodeTimestamp(&self) -> windows_core::Result; + fn SetDuration(&self, value: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; + fn Duration(&self) -> windows_core::Result; + fn SetKeyFrame(&self, value: bool) -> windows_core::Result<()>; + fn KeyFrame(&self) -> windows_core::Result; + fn SetDiscontinuous(&self, value: bool) -> windows_core::Result<()>; + fn Discontinuous(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IMediaStreamSample_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Processed(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSample_Impl::Processed(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveProcessed(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSample_Impl::RemoveProcessed(this, token).into() + } + } + unsafe extern "system" fn Buffer(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSample_Impl::Buffer(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Timestamp(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSample_Impl::Timestamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ExtendedProperties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSample_Impl::ExtendedProperties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Protection(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSample_Impl::Protection(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDecodeTimestamp(this: *mut core::ffi::c_void, value: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSample_Impl::SetDecodeTimestamp(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn DecodeTimestamp(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSample_Impl::DecodeTimestamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDuration(this: *mut core::ffi::c_void, value: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSample_Impl::SetDuration(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Duration(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSample_Impl::Duration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetKeyFrame(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSample_Impl::SetKeyFrame(this, value).into() + } + } + unsafe extern "system" fn KeyFrame(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSample_Impl::KeyFrame(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDiscontinuous(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSample_Impl::SetDiscontinuous(this, value).into() + } + } + unsafe extern "system" fn Discontinuous(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSample_Impl::Discontinuous(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Processed: Processed::, + RemoveProcessed: RemoveProcessed::, + Buffer: Buffer::, + Timestamp: Timestamp::, + ExtendedProperties: ExtendedProperties::, + Protection: Protection::, + SetDecodeTimestamp: SetDecodeTimestamp::, + DecodeTimestamp: DecodeTimestamp::, + SetDuration: SetDuration::, + Duration: Duration::, + SetKeyFrame: SetKeyFrame::, + KeyFrame: KeyFrame::, + SetDiscontinuous: SetDiscontinuous::, + Discontinuous: Discontinuous::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSample_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Processed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveProcessed: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + #[cfg(feature = "Storage_Streams")] + pub Buffer: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + Buffer: usize, + pub Timestamp: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub ExtendedProperties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Protection: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetDecodeTimestamp: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub DecodeTimestamp: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub SetDuration: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub Duration: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub SetKeyFrame: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub KeyFrame: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetDiscontinuous: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub Discontinuous: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSample2, IMediaStreamSample2_Vtbl, 0x45078691_fce8_4746_a1c8_10c25d3d7cd3); +impl windows_core::RuntimeType for IMediaStreamSample2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Graphics_DirectX_Direct3D11")] +impl windows_core::RuntimeName for IMediaStreamSample2 { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSample2"; +} +#[cfg(feature = "Graphics_DirectX_Direct3D11")] +pub trait IMediaStreamSample2_Impl: windows_core::IUnknownImpl { + fn Direct3D11Surface(&self) -> windows_core::Result; +} +#[cfg(feature = "Graphics_DirectX_Direct3D11")] +impl IMediaStreamSample2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Direct3D11Surface(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSample2_Impl::Direct3D11Surface(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Direct3D11Surface: Direct3D11Surface::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSample2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Graphics_DirectX_Direct3D11")] + pub Direct3D11Surface: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Graphics_DirectX_Direct3D11"))] + Direct3D11Surface: usize, +} +windows_core::imp::define_interface!(IMediaStreamSampleProtectionProperties, IMediaStreamSampleProtectionProperties_Vtbl, 0x4eb88292_ecdf_493e_841d_dd4add7caca2); +impl windows_core::RuntimeType for IMediaStreamSampleProtectionProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaStreamSampleProtectionProperties { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSampleProtectionProperties"; +} +pub trait IMediaStreamSampleProtectionProperties_Impl: windows_core::IUnknownImpl { + fn SetKeyIdentifier(&self, value: &[u8]) -> windows_core::Result<()>; + fn GetKeyIdentifier(&self, value: &mut windows_core::Array) -> windows_core::Result<()>; + fn SetInitializationVector(&self, value: &[u8]) -> windows_core::Result<()>; + fn GetInitializationVector(&self, value: &mut windows_core::Array) -> windows_core::Result<()>; + fn SetSubSampleMapping(&self, value: &[u8]) -> windows_core::Result<()>; + fn GetSubSampleMapping(&self, value: &mut windows_core::Array) -> windows_core::Result<()>; +} +impl IMediaStreamSampleProtectionProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetKeyIdentifier(this: *mut core::ffi::c_void, value_array_size: u32, value: *const u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSampleProtectionProperties_Impl::SetKeyIdentifier(this, core::slice::from_raw_parts(core::mem::transmute_copy(&value), value_array_size as usize)).into() + } + } + unsafe extern "system" fn GetKeyIdentifier(this: *mut core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSampleProtectionProperties_Impl::GetKeyIdentifier(this, &mut windows_core::imp::array_proxy(core::mem::transmute_copy(&value), value_array_size)).into() + } + } + unsafe extern "system" fn SetInitializationVector(this: *mut core::ffi::c_void, value_array_size: u32, value: *const u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSampleProtectionProperties_Impl::SetInitializationVector(this, core::slice::from_raw_parts(core::mem::transmute_copy(&value), value_array_size as usize)).into() + } + } + unsafe extern "system" fn GetInitializationVector(this: *mut core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSampleProtectionProperties_Impl::GetInitializationVector(this, &mut windows_core::imp::array_proxy(core::mem::transmute_copy(&value), value_array_size)).into() + } + } + unsafe extern "system" fn SetSubSampleMapping(this: *mut core::ffi::c_void, value_array_size: u32, value: *const u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSampleProtectionProperties_Impl::SetSubSampleMapping(this, core::slice::from_raw_parts(core::mem::transmute_copy(&value), value_array_size as usize)).into() + } + } + unsafe extern "system" fn GetSubSampleMapping(this: *mut core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSampleProtectionProperties_Impl::GetSubSampleMapping(this, &mut windows_core::imp::array_proxy(core::mem::transmute_copy(&value), value_array_size)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetKeyIdentifier: SetKeyIdentifier::, + GetKeyIdentifier: GetKeyIdentifier::, + SetInitializationVector: SetInitializationVector::, + GetInitializationVector: GetInitializationVector::, + SetSubSampleMapping: SetSubSampleMapping::, + GetSubSampleMapping: GetSubSampleMapping::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSampleProtectionProperties_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SetKeyIdentifier: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const u8) -> windows_core::HRESULT, + pub GetKeyIdentifier: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32, *mut *mut u8) -> windows_core::HRESULT, + pub SetInitializationVector: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const u8) -> windows_core::HRESULT, + pub GetInitializationVector: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32, *mut *mut u8) -> windows_core::HRESULT, + pub SetSubSampleMapping: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const u8) -> windows_core::HRESULT, + pub GetSubSampleMapping: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32, *mut *mut u8) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSampleStatics, IMediaStreamSampleStatics_Vtbl, 0xdfdf218f_a6cf_4579_be41_73dd941ad972); +impl windows_core::RuntimeType for IMediaStreamSampleStatics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMediaStreamSampleStatics { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSampleStatics"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMediaStreamSampleStatics_Impl: windows_core::IUnknownImpl { + fn CreateFromBuffer(&self, buffer: windows_core::Ref<'_, super::super::Storage::Streams::IBuffer>, timestamp: &super::super::Foundation::TimeSpan) -> windows_core::Result; + fn CreateFromStreamAsync(&self, stream: windows_core::Ref<'_, super::super::Storage::Streams::IInputStream>, count: u32, timestamp: &super::super::Foundation::TimeSpan) -> windows_core::Result>; +} +#[cfg(feature = "Storage_Streams")] +impl IMediaStreamSampleStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromBuffer(this: *mut core::ffi::c_void, buffer: *mut core::ffi::c_void, timestamp: super::super::Foundation::TimeSpan, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSampleStatics_Impl::CreateFromBuffer(this, core::mem::transmute_copy(&buffer), core::mem::transmute(×tamp)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromStreamAsync(this: *mut core::ffi::c_void, stream: *mut core::ffi::c_void, count: u32, timestamp: super::super::Foundation::TimeSpan, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSampleStatics_Impl::CreateFromStreamAsync(this, core::mem::transmute_copy(&stream), count, core::mem::transmute(×tamp)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromBuffer: CreateFromBuffer::, + CreateFromStreamAsync: CreateFromStreamAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSampleStatics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Storage_Streams")] + pub CreateFromBuffer: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, super::super::Foundation::TimeSpan, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + CreateFromBuffer: usize, + #[cfg(feature = "Storage_Streams")] + pub CreateFromStreamAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, u32, super::super::Foundation::TimeSpan, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + CreateFromStreamAsync: usize, +} +windows_core::imp::define_interface!(IMediaStreamSampleStatics2, IMediaStreamSampleStatics2_Vtbl, 0x9efe9521_6d46_494c_a2f8_d662922e2dd7); +impl windows_core::RuntimeType for IMediaStreamSampleStatics2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Graphics_DirectX_Direct3D11")] +impl windows_core::RuntimeName for IMediaStreamSampleStatics2 { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSampleStatics2"; +} +#[cfg(feature = "Graphics_DirectX_Direct3D11")] +pub trait IMediaStreamSampleStatics2_Impl: windows_core::IUnknownImpl { + fn CreateFromDirect3D11Surface(&self, surface: windows_core::Ref<'_, super::super::Graphics::DirectX::Direct3D11::IDirect3DSurface>, timestamp: &super::super::Foundation::TimeSpan) -> windows_core::Result; +} +#[cfg(feature = "Graphics_DirectX_Direct3D11")] +impl IMediaStreamSampleStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromDirect3D11Surface(this: *mut core::ffi::c_void, surface: *mut core::ffi::c_void, timestamp: super::super::Foundation::TimeSpan, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSampleStatics2_Impl::CreateFromDirect3D11Surface(this, core::mem::transmute_copy(&surface), core::mem::transmute(×tamp)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromDirect3D11Surface: CreateFromDirect3D11Surface::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSampleStatics2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Graphics_DirectX_Direct3D11")] + pub CreateFromDirect3D11Surface: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, super::super::Foundation::TimeSpan, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Graphics_DirectX_Direct3D11"))] + CreateFromDirect3D11Surface: usize, +} +windows_core::imp::define_interface!(IMediaStreamSource, IMediaStreamSource_Vtbl, 0x3712d543_45eb_4138_aa62_c01e26f3843f); +impl windows_core::RuntimeType for IMediaStreamSource { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Media_Protection", feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IMediaStreamSource { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSource"; +} +#[cfg(all(feature = "Media_Protection", feature = "Storage_FileProperties", feature = "Storage_Streams"))] +pub trait IMediaStreamSource_Impl: IMediaSource_Impl { + fn Closed(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveClosed(&self, token: i64) -> windows_core::Result<()>; + fn Starting(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveStarting(&self, token: i64) -> windows_core::Result<()>; + fn Paused(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemovePaused(&self, token: i64) -> windows_core::Result<()>; + fn SampleRequested(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveSampleRequested(&self, token: i64) -> windows_core::Result<()>; + fn SwitchStreamsRequested(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveSwitchStreamsRequested(&self, token: i64) -> windows_core::Result<()>; + fn NotifyError(&self, errorStatus: MediaStreamSourceErrorStatus) -> windows_core::Result<()>; + fn AddStreamDescriptor(&self, descriptor: windows_core::Ref<'_, IMediaStreamDescriptor>) -> windows_core::Result<()>; + fn SetMediaProtectionManager(&self, value: windows_core::Ref<'_, super::Protection::MediaProtectionManager>) -> windows_core::Result<()>; + fn MediaProtectionManager(&self) -> windows_core::Result; + fn SetDuration(&self, value: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; + fn Duration(&self) -> windows_core::Result; + fn SetCanSeek(&self, value: bool) -> windows_core::Result<()>; + fn CanSeek(&self) -> windows_core::Result; + fn SetBufferTime(&self, value: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; + fn BufferTime(&self) -> windows_core::Result; + fn SetBufferedRange(&self, startOffset: &super::super::Foundation::TimeSpan, endOffset: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; + fn MusicProperties(&self) -> windows_core::Result; + fn VideoProperties(&self) -> windows_core::Result; + fn SetThumbnail(&self, value: windows_core::Ref<'_, super::super::Storage::Streams::IRandomAccessStreamReference>) -> windows_core::Result<()>; + fn Thumbnail(&self) -> windows_core::Result; + fn AddProtectionKey(&self, streamDescriptor: windows_core::Ref<'_, IMediaStreamDescriptor>, keyIdentifier: &[u8], licenseData: &[u8]) -> windows_core::Result<()>; +} +#[cfg(all(feature = "Media_Protection", feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl IMediaStreamSource_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Closed(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSource_Impl::Closed(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveClosed(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource_Impl::RemoveClosed(this, token).into() + } + } + unsafe extern "system" fn Starting(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSource_Impl::Starting(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveStarting(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource_Impl::RemoveStarting(this, token).into() + } + } + unsafe extern "system" fn Paused(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSource_Impl::Paused(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemovePaused(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource_Impl::RemovePaused(this, token).into() + } + } + unsafe extern "system" fn SampleRequested(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSource_Impl::SampleRequested(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveSampleRequested(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource_Impl::RemoveSampleRequested(this, token).into() + } + } + unsafe extern "system" fn SwitchStreamsRequested(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSource_Impl::SwitchStreamsRequested(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveSwitchStreamsRequested(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource_Impl::RemoveSwitchStreamsRequested(this, token).into() + } + } + unsafe extern "system" fn NotifyError(this: *mut core::ffi::c_void, errorstatus: MediaStreamSourceErrorStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource_Impl::NotifyError(this, errorstatus).into() + } + } + unsafe extern "system" fn AddStreamDescriptor(this: *mut core::ffi::c_void, descriptor: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource_Impl::AddStreamDescriptor(this, core::mem::transmute_copy(&descriptor)).into() + } + } + unsafe extern "system" fn SetMediaProtectionManager(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource_Impl::SetMediaProtectionManager(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn MediaProtectionManager(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSource_Impl::MediaProtectionManager(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDuration(this: *mut core::ffi::c_void, value: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource_Impl::SetDuration(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Duration(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSource_Impl::Duration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetCanSeek(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource_Impl::SetCanSeek(this, value).into() + } + } + unsafe extern "system" fn CanSeek(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSource_Impl::CanSeek(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetBufferTime(this: *mut core::ffi::c_void, value: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource_Impl::SetBufferTime(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn BufferTime(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSource_Impl::BufferTime(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetBufferedRange(this: *mut core::ffi::c_void, startoffset: super::super::Foundation::TimeSpan, endoffset: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource_Impl::SetBufferedRange(this, core::mem::transmute(&startoffset), core::mem::transmute(&endoffset)).into() + } + } + unsafe extern "system" fn MusicProperties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSource_Impl::MusicProperties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn VideoProperties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSource_Impl::VideoProperties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetThumbnail(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource_Impl::SetThumbnail(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Thumbnail(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSource_Impl::Thumbnail(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AddProtectionKey(this: *mut core::ffi::c_void, streamdescriptor: *mut core::ffi::c_void, keyidentifier_array_size: u32, keyidentifier: *const u8, licensedata_array_size: u32, licensedata: *const u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource_Impl::AddProtectionKey(this, core::mem::transmute_copy(&streamdescriptor), core::slice::from_raw_parts(core::mem::transmute_copy(&keyidentifier), keyidentifier_array_size as usize), core::slice::from_raw_parts(core::mem::transmute_copy(&licensedata), licensedata_array_size as usize)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Closed: Closed::, + RemoveClosed: RemoveClosed::, + Starting: Starting::, + RemoveStarting: RemoveStarting::, + Paused: Paused::, + RemovePaused: RemovePaused::, + SampleRequested: SampleRequested::, + RemoveSampleRequested: RemoveSampleRequested::, + SwitchStreamsRequested: SwitchStreamsRequested::, + RemoveSwitchStreamsRequested: RemoveSwitchStreamsRequested::, + NotifyError: NotifyError::, + AddStreamDescriptor: AddStreamDescriptor::, + SetMediaProtectionManager: SetMediaProtectionManager::, + MediaProtectionManager: MediaProtectionManager::, + SetDuration: SetDuration::, + Duration: Duration::, + SetCanSeek: SetCanSeek::, + CanSeek: CanSeek::, + SetBufferTime: SetBufferTime::, + BufferTime: BufferTime::, + SetBufferedRange: SetBufferedRange::, + MusicProperties: MusicProperties::, + VideoProperties: VideoProperties::, + SetThumbnail: SetThumbnail::, + Thumbnail: Thumbnail::, + AddProtectionKey: AddProtectionKey::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSource_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Closed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveClosed: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub Starting: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveStarting: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub Paused: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemovePaused: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub SampleRequested: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveSampleRequested: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub SwitchStreamsRequested: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveSwitchStreamsRequested: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub NotifyError: unsafe extern "system" fn(*mut core::ffi::c_void, MediaStreamSourceErrorStatus) -> windows_core::HRESULT, + pub AddStreamDescriptor: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Media_Protection")] + pub SetMediaProtectionManager: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Protection"))] + SetMediaProtectionManager: usize, + #[cfg(feature = "Media_Protection")] + pub MediaProtectionManager: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Protection"))] + MediaProtectionManager: usize, + pub SetDuration: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub Duration: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub SetCanSeek: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub CanSeek: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetBufferTime: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub BufferTime: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub SetBufferedRange: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan, super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + #[cfg(feature = "Storage_FileProperties")] + pub MusicProperties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_FileProperties"))] + MusicProperties: usize, + #[cfg(feature = "Storage_FileProperties")] + pub VideoProperties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_FileProperties"))] + VideoProperties: usize, + #[cfg(feature = "Storage_Streams")] + pub SetThumbnail: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + SetThumbnail: usize, + #[cfg(feature = "Storage_Streams")] + pub Thumbnail: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + Thumbnail: usize, + pub AddProtectionKey: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, u32, *const u8, u32, *const u8) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSource2, IMediaStreamSource2_Vtbl, 0xec55d0ad_2e6a_4f74_adbb_b562d1533849); +impl windows_core::RuntimeType for IMediaStreamSource2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Media_Protection", feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IMediaStreamSource2 { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSource2"; +} +#[cfg(all(feature = "Media_Protection", feature = "Storage_FileProperties", feature = "Storage_Streams"))] +pub trait IMediaStreamSource2_Impl: IMediaSource_Impl + IMediaStreamSource_Impl { + fn SampleRendered(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveSampleRendered(&self, token: i64) -> windows_core::Result<()>; +} +#[cfg(all(feature = "Media_Protection", feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl IMediaStreamSource2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SampleRendered(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSource2_Impl::SampleRendered(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveSampleRendered(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource2_Impl::RemoveSampleRendered(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SampleRendered: SampleRendered::, + RemoveSampleRendered: RemoveSampleRendered::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSource2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SampleRendered: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveSampleRendered: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSource3, IMediaStreamSource3_Vtbl, 0x6a2a2746_3ddd_4ddf_a121_94045ecf9440); +impl windows_core::RuntimeType for IMediaStreamSource3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Media_Protection", feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IMediaStreamSource3 { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSource3"; +} +#[cfg(all(feature = "Media_Protection", feature = "Storage_FileProperties", feature = "Storage_Streams"))] +pub trait IMediaStreamSource3_Impl: IMediaSource_Impl + IMediaStreamSource_Impl { + fn SetMaxSupportedPlaybackRate(&self, value: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn MaxSupportedPlaybackRate(&self) -> windows_core::Result>; +} +#[cfg(all(feature = "Media_Protection", feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl IMediaStreamSource3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetMaxSupportedPlaybackRate(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource3_Impl::SetMaxSupportedPlaybackRate(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn MaxSupportedPlaybackRate(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSource3_Impl::MaxSupportedPlaybackRate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetMaxSupportedPlaybackRate: SetMaxSupportedPlaybackRate::, + MaxSupportedPlaybackRate: MaxSupportedPlaybackRate::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSource3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SetMaxSupportedPlaybackRate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub MaxSupportedPlaybackRate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSource4, IMediaStreamSource4_Vtbl, 0x1d0cfcab_830d_417c_a3a9_2454fd6415c7); +impl windows_core::RuntimeType for IMediaStreamSource4 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Media_Protection", feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IMediaStreamSource4 { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSource4"; +} +#[cfg(all(feature = "Media_Protection", feature = "Storage_FileProperties", feature = "Storage_Streams"))] +pub trait IMediaStreamSource4_Impl: IMediaSource_Impl + IMediaStreamSource_Impl { + fn SetIsLive(&self, value: bool) -> windows_core::Result<()>; + fn IsLive(&self) -> windows_core::Result; +} +#[cfg(all(feature = "Media_Protection", feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl IMediaStreamSource4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetIsLive(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSource4_Impl::SetIsLive(this, value).into() + } + } + unsafe extern "system" fn IsLive(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSource4_Impl::IsLive(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetIsLive: SetIsLive::, + IsLive: IsLive::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSource4_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SetIsLive: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub IsLive: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSourceClosedEventArgs, IMediaStreamSourceClosedEventArgs_Vtbl, 0xcd8c7eb2_4816_4e24_88f0_491ef7386406); +impl windows_core::RuntimeType for IMediaStreamSourceClosedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaStreamSourceClosedEventArgs { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSourceClosedEventArgs"; +} +pub trait IMediaStreamSourceClosedEventArgs_Impl: windows_core::IUnknownImpl { + fn Request(&self) -> windows_core::Result; +} +impl IMediaStreamSourceClosedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Request(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceClosedEventArgs_Impl::Request(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Request: Request:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSourceClosedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Request: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSourceClosedRequest, IMediaStreamSourceClosedRequest_Vtbl, 0x907c00e9_18a3_4951_887a_2c1eebd5c69e); +impl windows_core::RuntimeType for IMediaStreamSourceClosedRequest { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaStreamSourceClosedRequest { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSourceClosedRequest"; +} +pub trait IMediaStreamSourceClosedRequest_Impl: windows_core::IUnknownImpl { + fn Reason(&self) -> windows_core::Result; +} +impl IMediaStreamSourceClosedRequest_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Reason(this: *mut core::ffi::c_void, result__: *mut MediaStreamSourceClosedReason) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceClosedRequest_Impl::Reason(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Reason: Reason:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSourceClosedRequest_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Reason: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaStreamSourceClosedReason) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSourceFactory, IMediaStreamSourceFactory_Vtbl, 0xef77e0d9_d158_4b7a_863f_203342fbfd41); +impl windows_core::RuntimeType for IMediaStreamSourceFactory { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaStreamSourceFactory { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSourceFactory"; +} +pub trait IMediaStreamSourceFactory_Impl: windows_core::IUnknownImpl { + fn CreateFromDescriptor(&self, descriptor: windows_core::Ref<'_, IMediaStreamDescriptor>) -> windows_core::Result; + fn CreateFromDescriptors(&self, descriptor: windows_core::Ref<'_, IMediaStreamDescriptor>, descriptor2: windows_core::Ref<'_, IMediaStreamDescriptor>) -> windows_core::Result; +} +impl IMediaStreamSourceFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromDescriptor(this: *mut core::ffi::c_void, descriptor: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceFactory_Impl::CreateFromDescriptor(this, core::mem::transmute_copy(&descriptor)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromDescriptors(this: *mut core::ffi::c_void, descriptor: *mut core::ffi::c_void, descriptor2: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceFactory_Impl::CreateFromDescriptors(this, core::mem::transmute_copy(&descriptor), core::mem::transmute_copy(&descriptor2)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromDescriptor: CreateFromDescriptor::, + CreateFromDescriptors: CreateFromDescriptors::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSourceFactory_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub CreateFromDescriptor: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateFromDescriptors: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSourceSampleRenderedEventArgs, IMediaStreamSourceSampleRenderedEventArgs_Vtbl, 0x9d697b05_d4f2_4c7a_9dfe_8d6cd0b3ee84); +impl windows_core::RuntimeType for IMediaStreamSourceSampleRenderedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaStreamSourceSampleRenderedEventArgs { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSourceSampleRenderedEventArgs"; +} +pub trait IMediaStreamSourceSampleRenderedEventArgs_Impl: windows_core::IUnknownImpl { + fn SampleLag(&self) -> windows_core::Result; +} +impl IMediaStreamSourceSampleRenderedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SampleLag(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceSampleRenderedEventArgs_Impl::SampleLag(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SampleLag: SampleLag::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSourceSampleRenderedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SampleLag: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSourceSampleRequest, IMediaStreamSourceSampleRequest_Vtbl, 0x4db341a9_3501_4d9b_83f9_8f235c822532); +impl windows_core::RuntimeType for IMediaStreamSourceSampleRequest { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaStreamSourceSampleRequest { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSourceSampleRequest"; +} +pub trait IMediaStreamSourceSampleRequest_Impl: windows_core::IUnknownImpl { + fn StreamDescriptor(&self) -> windows_core::Result; + fn GetDeferral(&self) -> windows_core::Result; + fn SetSample(&self, value: windows_core::Ref<'_, MediaStreamSample>) -> windows_core::Result<()>; + fn Sample(&self) -> windows_core::Result; + fn ReportSampleProgress(&self, progress: u32) -> windows_core::Result<()>; +} +impl IMediaStreamSourceSampleRequest_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn StreamDescriptor(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceSampleRequest_Impl::StreamDescriptor(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeferral(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceSampleRequest_Impl::GetDeferral(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetSample(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSourceSampleRequest_Impl::SetSample(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Sample(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceSampleRequest_Impl::Sample(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReportSampleProgress(this: *mut core::ffi::c_void, progress: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSourceSampleRequest_Impl::ReportSampleProgress(this, progress).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + StreamDescriptor: StreamDescriptor::, + GetDeferral: GetDeferral::, + SetSample: SetSample::, + Sample: Sample::, + ReportSampleProgress: ReportSampleProgress::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSourceSampleRequest_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub StreamDescriptor: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetDeferral: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetSample: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Sample: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ReportSampleProgress: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSourceSampleRequestDeferral, IMediaStreamSourceSampleRequestDeferral_Vtbl, 0x7895cc02_f982_43c8_9d16_c62d999319be); +impl windows_core::RuntimeType for IMediaStreamSourceSampleRequestDeferral { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaStreamSourceSampleRequestDeferral { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSourceSampleRequestDeferral"; +} +pub trait IMediaStreamSourceSampleRequestDeferral_Impl: windows_core::IUnknownImpl { + fn Complete(&self) -> windows_core::Result<()>; +} +impl IMediaStreamSourceSampleRequestDeferral_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Complete(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSourceSampleRequestDeferral_Impl::Complete(this).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Complete: Complete::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSourceSampleRequestDeferral_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Complete: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSourceSampleRequestedEventArgs, IMediaStreamSourceSampleRequestedEventArgs_Vtbl, 0x10f9bb9e_71c5_492f_847f_0da1f35e81f8); +impl windows_core::RuntimeType for IMediaStreamSourceSampleRequestedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaStreamSourceSampleRequestedEventArgs { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSourceSampleRequestedEventArgs"; +} +pub trait IMediaStreamSourceSampleRequestedEventArgs_Impl: windows_core::IUnknownImpl { + fn Request(&self) -> windows_core::Result; +} +impl IMediaStreamSourceSampleRequestedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Request(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceSampleRequestedEventArgs_Impl::Request(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Request: Request::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSourceSampleRequestedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Request: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSourceStartingEventArgs, IMediaStreamSourceStartingEventArgs_Vtbl, 0xf41468f2_c274_4940_a5bb_28a572452fa7); +impl windows_core::RuntimeType for IMediaStreamSourceStartingEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaStreamSourceStartingEventArgs { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSourceStartingEventArgs"; +} +pub trait IMediaStreamSourceStartingEventArgs_Impl: windows_core::IUnknownImpl { + fn Request(&self) -> windows_core::Result; +} +impl IMediaStreamSourceStartingEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Request(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceStartingEventArgs_Impl::Request(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Request: Request:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSourceStartingEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Request: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSourceStartingRequest, IMediaStreamSourceStartingRequest_Vtbl, 0x2a9093e4_35c4_4b1b_a791_0d99db56dd1d); +impl windows_core::RuntimeType for IMediaStreamSourceStartingRequest { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaStreamSourceStartingRequest { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSourceStartingRequest"; +} +pub trait IMediaStreamSourceStartingRequest_Impl: windows_core::IUnknownImpl { + fn StartPosition(&self) -> windows_core::Result>; + fn GetDeferral(&self) -> windows_core::Result; + fn SetActualStartPosition(&self, position: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; +} +impl IMediaStreamSourceStartingRequest_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn StartPosition(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceStartingRequest_Impl::StartPosition(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeferral(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceStartingRequest_Impl::GetDeferral(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetActualStartPosition(this: *mut core::ffi::c_void, position: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSourceStartingRequest_Impl::SetActualStartPosition(this, core::mem::transmute(&position)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + StartPosition: StartPosition::, + GetDeferral: GetDeferral::, + SetActualStartPosition: SetActualStartPosition::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSourceStartingRequest_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub StartPosition: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetDeferral: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetActualStartPosition: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSourceStartingRequestDeferral, IMediaStreamSourceStartingRequestDeferral_Vtbl, 0x3f1356a5_6340_4dc4_9910_068ed9f598f8); +impl windows_core::RuntimeType for IMediaStreamSourceStartingRequestDeferral { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaStreamSourceStartingRequestDeferral { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSourceStartingRequestDeferral"; +} +pub trait IMediaStreamSourceStartingRequestDeferral_Impl: windows_core::IUnknownImpl { + fn Complete(&self) -> windows_core::Result<()>; +} +impl IMediaStreamSourceStartingRequestDeferral_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Complete(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSourceStartingRequestDeferral_Impl::Complete(this).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Complete: Complete::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSourceStartingRequestDeferral_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Complete: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSourceSwitchStreamsRequest, IMediaStreamSourceSwitchStreamsRequest_Vtbl, 0x41b8808e_38a9_4ec3_9ba0_b69b85501e90); +impl windows_core::RuntimeType for IMediaStreamSourceSwitchStreamsRequest { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaStreamSourceSwitchStreamsRequest { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSourceSwitchStreamsRequest"; +} +pub trait IMediaStreamSourceSwitchStreamsRequest_Impl: windows_core::IUnknownImpl { + fn OldStreamDescriptor(&self) -> windows_core::Result; + fn NewStreamDescriptor(&self) -> windows_core::Result; + fn GetDeferral(&self) -> windows_core::Result; +} +impl IMediaStreamSourceSwitchStreamsRequest_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn OldStreamDescriptor(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceSwitchStreamsRequest_Impl::OldStreamDescriptor(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NewStreamDescriptor(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceSwitchStreamsRequest_Impl::NewStreamDescriptor(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeferral(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceSwitchStreamsRequest_Impl::GetDeferral(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + OldStreamDescriptor: OldStreamDescriptor::, + NewStreamDescriptor: NewStreamDescriptor::, + GetDeferral: GetDeferral::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSourceSwitchStreamsRequest_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub OldStreamDescriptor: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub NewStreamDescriptor: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetDeferral: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSourceSwitchStreamsRequestDeferral, IMediaStreamSourceSwitchStreamsRequestDeferral_Vtbl, 0xbee3d835_a505_4f9a_b943_2b8cb1b4bbd9); +impl windows_core::RuntimeType for IMediaStreamSourceSwitchStreamsRequestDeferral { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaStreamSourceSwitchStreamsRequestDeferral { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSourceSwitchStreamsRequestDeferral"; +} +pub trait IMediaStreamSourceSwitchStreamsRequestDeferral_Impl: windows_core::IUnknownImpl { + fn Complete(&self) -> windows_core::Result<()>; +} +impl IMediaStreamSourceSwitchStreamsRequestDeferral_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Complete(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaStreamSourceSwitchStreamsRequestDeferral_Impl::Complete(this).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Complete: Complete::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSourceSwitchStreamsRequestDeferral_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Complete: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaStreamSourceSwitchStreamsRequestedEventArgs, IMediaStreamSourceSwitchStreamsRequestedEventArgs_Vtbl, 0x42202b72_6ea1_4677_981e_350a0da412aa); +impl windows_core::RuntimeType for IMediaStreamSourceSwitchStreamsRequestedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaStreamSourceSwitchStreamsRequestedEventArgs { + const NAME: &'static str = "Windows.Media.Core.IMediaStreamSourceSwitchStreamsRequestedEventArgs"; +} +pub trait IMediaStreamSourceSwitchStreamsRequestedEventArgs_Impl: windows_core::IUnknownImpl { + fn Request(&self) -> windows_core::Result; +} +impl IMediaStreamSourceSwitchStreamsRequestedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Request(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaStreamSourceSwitchStreamsRequestedEventArgs_Impl::Request(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Request: Request::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaStreamSourceSwitchStreamsRequestedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Request: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaTrack, IMediaTrack_Vtbl, 0x03e1fafc_c931_491a_b46b_c10ee8c256b7); +impl windows_core::RuntimeType for IMediaTrack { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IMediaTrack, windows_core::IUnknown, windows_core::IInspectable); +impl IMediaTrack { + pub fn Id(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Id)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Language(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Language)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn TrackKind(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrackKind)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetLabel(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetLabel)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Label(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Label)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} +impl windows_core::RuntimeName for IMediaTrack { + const NAME: &'static str = "Windows.Media.Core.IMediaTrack"; +} +pub trait IMediaTrack_Impl: windows_core::IUnknownImpl { + fn Id(&self) -> windows_core::Result; + fn Language(&self) -> windows_core::Result; + fn TrackKind(&self) -> windows_core::Result; + fn SetLabel(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Label(&self) -> windows_core::Result; +} +impl IMediaTrack_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Id(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaTrack_Impl::Id(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Language(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaTrack_Impl::Language(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TrackKind(this: *mut core::ffi::c_void, result__: *mut MediaTrackKind) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaTrack_Impl::TrackKind(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetLabel(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaTrack_Impl::SetLabel(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Label(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaTrack_Impl::Label(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Id: Id::, + Language: Language::, + TrackKind: TrackKind::, + SetLabel: SetLabel::, + Label: Label::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaTrack_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Id: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Language: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub TrackKind: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaTrackKind) -> windows_core::HRESULT, + pub SetLabel: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Label: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMseSourceBuffer, IMseSourceBuffer_Vtbl, 0x0c1aa3e3_df8d_4079_a3fe_6849184b4e2f); +impl windows_core::RuntimeType for IMseSourceBuffer { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMseSourceBuffer { + const NAME: &'static str = "Windows.Media.Core.IMseSourceBuffer"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMseSourceBuffer_Impl: windows_core::IUnknownImpl { + fn UpdateStarting(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveUpdateStarting(&self, token: i64) -> windows_core::Result<()>; + fn Updated(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveUpdated(&self, token: i64) -> windows_core::Result<()>; + fn UpdateEnded(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveUpdateEnded(&self, token: i64) -> windows_core::Result<()>; + fn ErrorOccurred(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveErrorOccurred(&self, token: i64) -> windows_core::Result<()>; + fn Aborted(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveAborted(&self, token: i64) -> windows_core::Result<()>; + fn Mode(&self) -> windows_core::Result; + fn SetMode(&self, value: MseAppendMode) -> windows_core::Result<()>; + fn IsUpdating(&self) -> windows_core::Result; + fn Buffered(&self) -> windows_core::Result>; + fn TimestampOffset(&self) -> windows_core::Result; + fn SetTimestampOffset(&self, value: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; + fn AppendWindowStart(&self) -> windows_core::Result; + fn SetAppendWindowStart(&self, value: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; + fn AppendWindowEnd(&self) -> windows_core::Result>; + fn SetAppendWindowEnd(&self, value: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn AppendBuffer(&self, buffer: windows_core::Ref<'_, super::super::Storage::Streams::IBuffer>) -> windows_core::Result<()>; + fn AppendStream(&self, stream: windows_core::Ref<'_, super::super::Storage::Streams::IInputStream>) -> windows_core::Result<()>; + fn AppendStreamMaxSize(&self, stream: windows_core::Ref<'_, super::super::Storage::Streams::IInputStream>, maxSize: u64) -> windows_core::Result<()>; + fn Abort(&self) -> windows_core::Result<()>; + fn Remove(&self, start: &super::super::Foundation::TimeSpan, end: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result<()>; +} +#[cfg(feature = "Storage_Streams")] +impl IMseSourceBuffer_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn UpdateStarting(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseSourceBuffer_Impl::UpdateStarting(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveUpdateStarting(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBuffer_Impl::RemoveUpdateStarting(this, token).into() + } + } + unsafe extern "system" fn Updated(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseSourceBuffer_Impl::Updated(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveUpdated(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBuffer_Impl::RemoveUpdated(this, token).into() + } + } + unsafe extern "system" fn UpdateEnded(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseSourceBuffer_Impl::UpdateEnded(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveUpdateEnded(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBuffer_Impl::RemoveUpdateEnded(this, token).into() + } + } + unsafe extern "system" fn ErrorOccurred(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseSourceBuffer_Impl::ErrorOccurred(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveErrorOccurred(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBuffer_Impl::RemoveErrorOccurred(this, token).into() + } + } + unsafe extern "system" fn Aborted(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseSourceBuffer_Impl::Aborted(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveAborted(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBuffer_Impl::RemoveAborted(this, token).into() + } + } + unsafe extern "system" fn Mode(this: *mut core::ffi::c_void, result__: *mut MseAppendMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseSourceBuffer_Impl::Mode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMode(this: *mut core::ffi::c_void, value: MseAppendMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBuffer_Impl::SetMode(this, value).into() + } + } + unsafe extern "system" fn IsUpdating(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseSourceBuffer_Impl::IsUpdating(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Buffered(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseSourceBuffer_Impl::Buffered(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TimestampOffset(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseSourceBuffer_Impl::TimestampOffset(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetTimestampOffset(this: *mut core::ffi::c_void, value: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBuffer_Impl::SetTimestampOffset(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn AppendWindowStart(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseSourceBuffer_Impl::AppendWindowStart(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAppendWindowStart(this: *mut core::ffi::c_void, value: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBuffer_Impl::SetAppendWindowStart(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn AppendWindowEnd(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseSourceBuffer_Impl::AppendWindowEnd(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAppendWindowEnd(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBuffer_Impl::SetAppendWindowEnd(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn AppendBuffer(this: *mut core::ffi::c_void, buffer: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBuffer_Impl::AppendBuffer(this, core::mem::transmute_copy(&buffer)).into() + } + } + unsafe extern "system" fn AppendStream(this: *mut core::ffi::c_void, stream: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBuffer_Impl::AppendStream(this, core::mem::transmute_copy(&stream)).into() + } + } + unsafe extern "system" fn AppendStreamMaxSize(this: *mut core::ffi::c_void, stream: *mut core::ffi::c_void, maxsize: u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBuffer_Impl::AppendStreamMaxSize(this, core::mem::transmute_copy(&stream), maxsize).into() + } + } + unsafe extern "system" fn Abort(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBuffer_Impl::Abort(this).into() + } + } + unsafe extern "system" fn Remove(this: *mut core::ffi::c_void, start: super::super::Foundation::TimeSpan, end: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBuffer_Impl::Remove(this, core::mem::transmute(&start), core::mem::transmute_copy(&end)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + UpdateStarting: UpdateStarting::, + RemoveUpdateStarting: RemoveUpdateStarting::, + Updated: Updated::, + RemoveUpdated: RemoveUpdated::, + UpdateEnded: UpdateEnded::, + RemoveUpdateEnded: RemoveUpdateEnded::, + ErrorOccurred: ErrorOccurred::, + RemoveErrorOccurred: RemoveErrorOccurred::, + Aborted: Aborted::, + RemoveAborted: RemoveAborted::, + Mode: Mode::, + SetMode: SetMode::, + IsUpdating: IsUpdating::, + Buffered: Buffered::, + TimestampOffset: TimestampOffset::, + SetTimestampOffset: SetTimestampOffset::, + AppendWindowStart: AppendWindowStart::, + SetAppendWindowStart: SetAppendWindowStart::, + AppendWindowEnd: AppendWindowEnd::, + SetAppendWindowEnd: SetAppendWindowEnd::, + AppendBuffer: AppendBuffer::, + AppendStream: AppendStream::, + AppendStreamMaxSize: AppendStreamMaxSize::, + Abort: Abort::, + Remove: Remove::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMseSourceBuffer_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub UpdateStarting: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveUpdateStarting: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub Updated: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveUpdated: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub UpdateEnded: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveUpdateEnded: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub ErrorOccurred: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveErrorOccurred: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub Aborted: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveAborted: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub Mode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MseAppendMode) -> windows_core::HRESULT, + pub SetMode: unsafe extern "system" fn(*mut core::ffi::c_void, MseAppendMode) -> windows_core::HRESULT, + pub IsUpdating: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Buffered: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub TimestampOffset: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub SetTimestampOffset: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub AppendWindowStart: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub SetAppendWindowStart: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub AppendWindowEnd: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetAppendWindowEnd: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Storage_Streams")] + pub AppendBuffer: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + AppendBuffer: usize, + #[cfg(feature = "Storage_Streams")] + pub AppendStream: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + AppendStream: usize, + #[cfg(feature = "Storage_Streams")] + pub AppendStreamMaxSize: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, u64) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + AppendStreamMaxSize: usize, + pub Abort: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, + pub Remove: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMseSourceBufferList, IMseSourceBufferList_Vtbl, 0x95fae8e7_a8e7_4ebf_8927_145e940ba511); +impl windows_core::RuntimeType for IMseSourceBufferList { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMseSourceBufferList { + const NAME: &'static str = "Windows.Media.Core.IMseSourceBufferList"; +} +pub trait IMseSourceBufferList_Impl: windows_core::IUnknownImpl { + fn SourceBufferAdded(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveSourceBufferAdded(&self, token: i64) -> windows_core::Result<()>; + fn SourceBufferRemoved(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveSourceBufferRemoved(&self, token: i64) -> windows_core::Result<()>; + fn Buffers(&self) -> windows_core::Result>; +} +impl IMseSourceBufferList_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SourceBufferAdded(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseSourceBufferList_Impl::SourceBufferAdded(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveSourceBufferAdded(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBufferList_Impl::RemoveSourceBufferAdded(this, token).into() + } + } + unsafe extern "system" fn SourceBufferRemoved(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseSourceBufferList_Impl::SourceBufferRemoved(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveSourceBufferRemoved(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseSourceBufferList_Impl::RemoveSourceBufferRemoved(this, token).into() + } + } + unsafe extern "system" fn Buffers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseSourceBufferList_Impl::Buffers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SourceBufferAdded: SourceBufferAdded::, + RemoveSourceBufferAdded: RemoveSourceBufferAdded::, + SourceBufferRemoved: SourceBufferRemoved::, + RemoveSourceBufferRemoved: RemoveSourceBufferRemoved::, + Buffers: Buffers::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMseSourceBufferList_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SourceBufferAdded: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveSourceBufferAdded: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub SourceBufferRemoved: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveSourceBufferRemoved: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub Buffers: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMseStreamSource, IMseStreamSource_Vtbl, 0xb0b4198d_02f4_4923_88dd_81bc3f360ffa); +impl windows_core::RuntimeType for IMseStreamSource { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMseStreamSource { + const NAME: &'static str = "Windows.Media.Core.IMseStreamSource"; +} +pub trait IMseStreamSource_Impl: IMediaSource_Impl { + fn Opened(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveOpened(&self, token: i64) -> windows_core::Result<()>; + fn Ended(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveEnded(&self, token: i64) -> windows_core::Result<()>; + fn Closed(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveClosed(&self, token: i64) -> windows_core::Result<()>; + fn SourceBuffers(&self) -> windows_core::Result; + fn ActiveSourceBuffers(&self) -> windows_core::Result; + fn ReadyState(&self) -> windows_core::Result; + fn Duration(&self) -> windows_core::Result>; + fn SetDuration(&self, value: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn AddSourceBuffer(&self, mimeType: &windows_core::HSTRING) -> windows_core::Result; + fn RemoveSourceBuffer(&self, buffer: windows_core::Ref<'_, MseSourceBuffer>) -> windows_core::Result<()>; + fn EndOfStream(&self, status: MseEndOfStreamStatus) -> windows_core::Result<()>; +} +impl IMseStreamSource_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Opened(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseStreamSource_Impl::Opened(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveOpened(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseStreamSource_Impl::RemoveOpened(this, token).into() + } + } + unsafe extern "system" fn Ended(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseStreamSource_Impl::Ended(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveEnded(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseStreamSource_Impl::RemoveEnded(this, token).into() + } + } + unsafe extern "system" fn Closed(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseStreamSource_Impl::Closed(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveClosed(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseStreamSource_Impl::RemoveClosed(this, token).into() + } + } + unsafe extern "system" fn SourceBuffers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseStreamSource_Impl::SourceBuffers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ActiveSourceBuffers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseStreamSource_Impl::ActiveSourceBuffers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReadyState(this: *mut core::ffi::c_void, result__: *mut MseReadyState) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseStreamSource_Impl::ReadyState(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Duration(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseStreamSource_Impl::Duration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDuration(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseStreamSource_Impl::SetDuration(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn AddSourceBuffer(this: *mut core::ffi::c_void, mimetype: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseStreamSource_Impl::AddSourceBuffer(this, core::mem::transmute(&mimetype)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveSourceBuffer(this: *mut core::ffi::c_void, buffer: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseStreamSource_Impl::RemoveSourceBuffer(this, core::mem::transmute_copy(&buffer)).into() + } + } + unsafe extern "system" fn EndOfStream(this: *mut core::ffi::c_void, status: MseEndOfStreamStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseStreamSource_Impl::EndOfStream(this, status).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Opened: Opened::, + RemoveOpened: RemoveOpened::, + Ended: Ended::, + RemoveEnded: RemoveEnded::, + Closed: Closed::, + RemoveClosed: RemoveClosed::, + SourceBuffers: SourceBuffers::, + ActiveSourceBuffers: ActiveSourceBuffers::, + ReadyState: ReadyState::, + Duration: Duration::, + SetDuration: SetDuration::, + AddSourceBuffer: AddSourceBuffer::, + RemoveSourceBuffer: RemoveSourceBuffer::, + EndOfStream: EndOfStream::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMseStreamSource_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Opened: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveOpened: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub Ended: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveEnded: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub Closed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveClosed: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub SourceBuffers: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ActiveSourceBuffers: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ReadyState: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MseReadyState) -> windows_core::HRESULT, + pub Duration: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetDuration: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub AddSourceBuffer: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub RemoveSourceBuffer: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub EndOfStream: unsafe extern "system" fn(*mut core::ffi::c_void, MseEndOfStreamStatus) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMseStreamSource2, IMseStreamSource2_Vtbl, 0x66f57d37_f9e7_418a_9cde_a020e956552b); +impl windows_core::RuntimeType for IMseStreamSource2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMseStreamSource2 { + const NAME: &'static str = "Windows.Media.Core.IMseStreamSource2"; +} +pub trait IMseStreamSource2_Impl: windows_core::IUnknownImpl { + fn LiveSeekableRange(&self) -> windows_core::Result>; + fn SetLiveSeekableRange(&self, value: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result<()>; +} +impl IMseStreamSource2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn LiveSeekableRange(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseStreamSource2_Impl::LiveSeekableRange(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetLiveSeekableRange(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMseStreamSource2_Impl::SetLiveSeekableRange(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + LiveSeekableRange: LiveSeekableRange::, + SetLiveSeekableRange: SetLiveSeekableRange::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMseStreamSource2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub LiveSeekableRange: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetLiveSeekableRange: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMseStreamSourceStatics, IMseStreamSourceStatics_Vtbl, 0x465c679d_d570_43ce_ba21_0bff5f3fbd0a); +impl windows_core::RuntimeType for IMseStreamSourceStatics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMseStreamSourceStatics { + const NAME: &'static str = "Windows.Media.Core.IMseStreamSourceStatics"; +} +pub trait IMseStreamSourceStatics_Impl: windows_core::IUnknownImpl { + fn IsContentTypeSupported(&self, contentType: &windows_core::HSTRING) -> windows_core::Result; +} +impl IMseStreamSourceStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsContentTypeSupported(this: *mut core::ffi::c_void, contenttype: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMseStreamSourceStatics_Impl::IsContentTypeSupported(this, core::mem::transmute(&contenttype)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsContentTypeSupported: IsContentTypeSupported::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMseStreamSourceStatics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsContentTypeSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISingleSelectMediaTrackList, ISingleSelectMediaTrackList_Vtbl, 0x77206f1f_c34f_494f_8077_2bad9ff4ecf1); +impl windows_core::RuntimeType for ISingleSelectMediaTrackList { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(ISingleSelectMediaTrackList, windows_core::IUnknown, windows_core::IInspectable); +impl ISingleSelectMediaTrackList { + pub fn SelectedIndexChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SelectedIndexChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveSelectedIndexChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveSelectedIndexChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn SetSelectedIndex(&self, value: i32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSelectedIndex)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn SelectedIndex(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SelectedIndex)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeName for ISingleSelectMediaTrackList { + const NAME: &'static str = "Windows.Media.Core.ISingleSelectMediaTrackList"; +} +pub trait ISingleSelectMediaTrackList_Impl: windows_core::IUnknownImpl { + fn SelectedIndexChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveSelectedIndexChanged(&self, token: i64) -> windows_core::Result<()>; + fn SetSelectedIndex(&self, value: i32) -> windows_core::Result<()>; + fn SelectedIndex(&self) -> windows_core::Result; +} +impl ISingleSelectMediaTrackList_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SelectedIndexChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISingleSelectMediaTrackList_Impl::SelectedIndexChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveSelectedIndexChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISingleSelectMediaTrackList_Impl::RemoveSelectedIndexChanged(this, token).into() + } + } + unsafe extern "system" fn SetSelectedIndex(this: *mut core::ffi::c_void, value: i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISingleSelectMediaTrackList_Impl::SetSelectedIndex(this, value).into() + } + } + unsafe extern "system" fn SelectedIndex(this: *mut core::ffi::c_void, result__: *mut i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISingleSelectMediaTrackList_Impl::SelectedIndex(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SelectedIndexChanged: SelectedIndexChanged::, + RemoveSelectedIndexChanged: RemoveSelectedIndexChanged::, + SetSelectedIndex: SetSelectedIndex::, + SelectedIndex: SelectedIndex::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISingleSelectMediaTrackList_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SelectedIndexChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveSelectedIndexChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub SetSelectedIndex: unsafe extern "system" fn(*mut core::ffi::c_void, i32) -> windows_core::HRESULT, + pub SelectedIndex: unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ITimedMetadataTrack, ITimedMetadataTrack_Vtbl, 0x9e6aed9e_f67a_49a9_b330_cf03b0e9cf07); +impl windows_core::RuntimeType for ITimedMetadataTrack { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ITimedMetadataTrack { + const NAME: &'static str = "Windows.Media.Core.ITimedMetadataTrack"; +} +pub trait ITimedMetadataTrack_Impl: IMediaTrack_Impl { + fn CueEntered(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveCueEntered(&self, token: i64) -> windows_core::Result<()>; + fn CueExited(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveCueExited(&self, token: i64) -> windows_core::Result<()>; + fn TrackFailed(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveTrackFailed(&self, token: i64) -> windows_core::Result<()>; + fn Cues(&self) -> windows_core::Result>; + fn ActiveCues(&self) -> windows_core::Result>; + fn TimedMetadataKind(&self) -> windows_core::Result; + fn DispatchType(&self) -> windows_core::Result; + fn AddCue(&self, cue: windows_core::Ref<'_, IMediaCue>) -> windows_core::Result<()>; + fn RemoveCue(&self, cue: windows_core::Ref<'_, IMediaCue>) -> windows_core::Result<()>; +} +impl ITimedMetadataTrack_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CueEntered(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataTrack_Impl::CueEntered(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveCueEntered(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ITimedMetadataTrack_Impl::RemoveCueEntered(this, token).into() + } + } + unsafe extern "system" fn CueExited(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataTrack_Impl::CueExited(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveCueExited(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ITimedMetadataTrack_Impl::RemoveCueExited(this, token).into() + } + } + unsafe extern "system" fn TrackFailed(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataTrack_Impl::TrackFailed(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveTrackFailed(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ITimedMetadataTrack_Impl::RemoveTrackFailed(this, token).into() + } + } + unsafe extern "system" fn Cues(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataTrack_Impl::Cues(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ActiveCues(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataTrack_Impl::ActiveCues(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TimedMetadataKind(this: *mut core::ffi::c_void, result__: *mut TimedMetadataKind) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataTrack_Impl::TimedMetadataKind(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DispatchType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataTrack_Impl::DispatchType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AddCue(this: *mut core::ffi::c_void, cue: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ITimedMetadataTrack_Impl::AddCue(this, core::mem::transmute_copy(&cue)).into() + } + } + unsafe extern "system" fn RemoveCue(this: *mut core::ffi::c_void, cue: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ITimedMetadataTrack_Impl::RemoveCue(this, core::mem::transmute_copy(&cue)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CueEntered: CueEntered::, + RemoveCueEntered: RemoveCueEntered::, + CueExited: CueExited::, + RemoveCueExited: RemoveCueExited::, + TrackFailed: TrackFailed::, + RemoveTrackFailed: RemoveTrackFailed::, + Cues: Cues::, + ActiveCues: ActiveCues::, + TimedMetadataKind: TimedMetadataKind::, + DispatchType: DispatchType::, + AddCue: AddCue::, + RemoveCue: RemoveCue::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ITimedMetadataTrack_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub CueEntered: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveCueEntered: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub CueExited: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveCueExited: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub TrackFailed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveTrackFailed: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub Cues: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ActiveCues: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub TimedMetadataKind: unsafe extern "system" fn(*mut core::ffi::c_void, *mut TimedMetadataKind) -> windows_core::HRESULT, + pub DispatchType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub AddCue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub RemoveCue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ITimedMetadataTrack2, ITimedMetadataTrack2_Vtbl, 0x21b4b648_9f9d_40ba_a8f3_1a92753aef0b); +impl windows_core::RuntimeType for ITimedMetadataTrack2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Playback")] +impl windows_core::RuntimeName for ITimedMetadataTrack2 { + const NAME: &'static str = "Windows.Media.Core.ITimedMetadataTrack2"; +} +#[cfg(feature = "Media_Playback")] +pub trait ITimedMetadataTrack2_Impl: IMediaTrack_Impl + ITimedMetadataTrack_Impl { + fn PlaybackItem(&self) -> windows_core::Result; + fn Name(&self) -> windows_core::Result; +} +#[cfg(feature = "Media_Playback")] +impl ITimedMetadataTrack2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn PlaybackItem(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataTrack2_Impl::PlaybackItem(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Name(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataTrack2_Impl::Name(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + PlaybackItem: PlaybackItem::, + Name: Name::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ITimedMetadataTrack2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_Playback")] + pub PlaybackItem: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Playback"))] + PlaybackItem: usize, + pub Name: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ITimedMetadataTrackError, ITimedMetadataTrackError_Vtbl, 0xb3767915_4114_4819_b9d9_dd76089e72f8); +impl windows_core::RuntimeType for ITimedMetadataTrackError { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ITimedMetadataTrackError { + const NAME: &'static str = "Windows.Media.Core.ITimedMetadataTrackError"; +} +pub trait ITimedMetadataTrackError_Impl: windows_core::IUnknownImpl { + fn ErrorCode(&self) -> windows_core::Result; + fn ExtendedError(&self) -> windows_core::Result; +} +impl ITimedMetadataTrackError_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ErrorCode(this: *mut core::ffi::c_void, result__: *mut TimedMetadataTrackErrorCode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataTrackError_Impl::ErrorCode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ExtendedError(this: *mut core::ffi::c_void, result__: *mut windows_core::HRESULT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataTrackError_Impl::ExtendedError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ErrorCode: ErrorCode::, + ExtendedError: ExtendedError::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ITimedMetadataTrackError_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ErrorCode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut TimedMetadataTrackErrorCode) -> windows_core::HRESULT, + pub ExtendedError: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_core::HRESULT) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ITimedMetadataTrackFactory, ITimedMetadataTrackFactory_Vtbl, 0x8dd57611_97b3_4e1f_852c_0f482c81ad26); +impl windows_core::RuntimeType for ITimedMetadataTrackFactory { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ITimedMetadataTrackFactory { + const NAME: &'static str = "Windows.Media.Core.ITimedMetadataTrackFactory"; +} +pub trait ITimedMetadataTrackFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, id: &windows_core::HSTRING, language: &windows_core::HSTRING, kind: TimedMetadataKind) -> windows_core::Result; +} +impl ITimedMetadataTrackFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, id: *mut core::ffi::c_void, language: *mut core::ffi::c_void, kind: TimedMetadataKind, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataTrackFactory_Impl::Create(this, core::mem::transmute(&id), core::mem::transmute(&language), kind) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ITimedMetadataTrackFactory_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Create: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, TimedMetadataKind, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ITimedMetadataTrackFailedEventArgs, ITimedMetadataTrackFailedEventArgs_Vtbl, 0xa57fc9d1_6789_4d4d_b07f_84b4f31acb70); +impl windows_core::RuntimeType for ITimedMetadataTrackFailedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ITimedMetadataTrackFailedEventArgs { + const NAME: &'static str = "Windows.Media.Core.ITimedMetadataTrackFailedEventArgs"; +} +pub trait ITimedMetadataTrackFailedEventArgs_Impl: windows_core::IUnknownImpl { + fn Error(&self) -> windows_core::Result; +} +impl ITimedMetadataTrackFailedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Error(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataTrackFailedEventArgs_Impl::Error(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Error: Error:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ITimedMetadataTrackFailedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Error: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ITimedMetadataTrackProvider, ITimedMetadataTrackProvider_Vtbl, 0x3b7f2024_f74e_4ade_93c5_219da05b6856); +impl windows_core::RuntimeType for ITimedMetadataTrackProvider { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(ITimedMetadataTrackProvider, windows_core::IUnknown, windows_core::IInspectable); +impl ITimedMetadataTrackProvider { + pub fn TimedMetadataTracks(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TimedMetadataTracks)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeName for ITimedMetadataTrackProvider { + const NAME: &'static str = "Windows.Media.Core.ITimedMetadataTrackProvider"; +} +pub trait ITimedMetadataTrackProvider_Impl: windows_core::IUnknownImpl { + fn TimedMetadataTracks(&self) -> windows_core::Result>; +} +impl ITimedMetadataTrackProvider_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TimedMetadataTracks(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataTrackProvider_Impl::TimedMetadataTracks(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + TimedMetadataTracks: TimedMetadataTracks::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ITimedMetadataTrackProvider_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub TimedMetadataTracks: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ITimedTextSource, ITimedTextSource_Vtbl, 0xc4ed9ba6_101f_404d_a949_82f33fcd93b7); +impl windows_core::RuntimeType for ITimedTextSource { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ITimedTextSource { + const NAME: &'static str = "Windows.Media.Core.ITimedTextSource"; +} +pub trait ITimedTextSource_Impl: windows_core::IUnknownImpl { + fn Resolved(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveResolved(&self, token: i64) -> windows_core::Result<()>; +} +impl ITimedTextSource_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Resolved(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedTextSource_Impl::Resolved(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveResolved(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ITimedTextSource_Impl::RemoveResolved(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Resolved: Resolved::, + RemoveResolved: RemoveResolved::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ITimedTextSource_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Resolved: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveResolved: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ITimedTextSourceResolveResultEventArgs, ITimedTextSourceResolveResultEventArgs_Vtbl, 0x48907c9c_dcd8_4c33_9ad3_6cdce7b1c566); +impl windows_core::RuntimeType for ITimedTextSourceResolveResultEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ITimedTextSourceResolveResultEventArgs { + const NAME: &'static str = "Windows.Media.Core.ITimedTextSourceResolveResultEventArgs"; +} +pub trait ITimedTextSourceResolveResultEventArgs_Impl: windows_core::IUnknownImpl { + fn Error(&self) -> windows_core::Result; + fn Tracks(&self) -> windows_core::Result>; +} +impl ITimedTextSourceResolveResultEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Error(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedTextSourceResolveResultEventArgs_Impl::Error(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Tracks(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedTextSourceResolveResultEventArgs_Impl::Tracks(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Error: Error::, + Tracks: Tracks::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ITimedTextSourceResolveResultEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Error: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Tracks: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ITimedTextSourceStatics, ITimedTextSourceStatics_Vtbl, 0x7e311853_9aba_4ac4_bb98_2fb176c3bfdd); +impl windows_core::RuntimeType for ITimedTextSourceStatics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for ITimedTextSourceStatics { + const NAME: &'static str = "Windows.Media.Core.ITimedTextSourceStatics"; +} +#[cfg(feature = "Storage_Streams")] +pub trait ITimedTextSourceStatics_Impl: windows_core::IUnknownImpl { + fn CreateFromStream(&self, stream: windows_core::Ref<'_, super::super::Storage::Streams::IRandomAccessStream>) -> windows_core::Result; + fn CreateFromUri(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result; + fn CreateFromStreamWithLanguage(&self, stream: windows_core::Ref<'_, super::super::Storage::Streams::IRandomAccessStream>, defaultLanguage: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromUriWithLanguage(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>, defaultLanguage: &windows_core::HSTRING) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl ITimedTextSourceStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromStream(this: *mut core::ffi::c_void, stream: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedTextSourceStatics_Impl::CreateFromStream(this, core::mem::transmute_copy(&stream)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromUri(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedTextSourceStatics_Impl::CreateFromUri(this, core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromStreamWithLanguage(this: *mut core::ffi::c_void, stream: *mut core::ffi::c_void, defaultlanguage: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedTextSourceStatics_Impl::CreateFromStreamWithLanguage(this, core::mem::transmute_copy(&stream), core::mem::transmute(&defaultlanguage)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromUriWithLanguage(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, defaultlanguage: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedTextSourceStatics_Impl::CreateFromUriWithLanguage(this, core::mem::transmute_copy(&uri), core::mem::transmute(&defaultlanguage)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromStream: CreateFromStream::, + CreateFromUri: CreateFromUri::, + CreateFromStreamWithLanguage: CreateFromStreamWithLanguage::, + CreateFromUriWithLanguage: CreateFromUriWithLanguage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ITimedTextSourceStatics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Storage_Streams")] + pub CreateFromStream: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + CreateFromStream: usize, + pub CreateFromUri: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Storage_Streams")] + pub CreateFromStreamWithLanguage: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + CreateFromStreamWithLanguage: usize, + pub CreateFromUriWithLanguage: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ITimedTextSourceStatics2, ITimedTextSourceStatics2_Vtbl, 0xb66b7602_923e_43fa_9633_587075812db5); +impl windows_core::RuntimeType for ITimedTextSourceStatics2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for ITimedTextSourceStatics2 { + const NAME: &'static str = "Windows.Media.Core.ITimedTextSourceStatics2"; +} +#[cfg(feature = "Storage_Streams")] +pub trait ITimedTextSourceStatics2_Impl: windows_core::IUnknownImpl { + fn CreateFromStreamWithIndex(&self, stream: windows_core::Ref<'_, super::super::Storage::Streams::IRandomAccessStream>, indexStream: windows_core::Ref<'_, super::super::Storage::Streams::IRandomAccessStream>) -> windows_core::Result; + fn CreateFromUriWithIndex(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>, indexUri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result; + fn CreateFromStreamWithIndexAndLanguage(&self, stream: windows_core::Ref<'_, super::super::Storage::Streams::IRandomAccessStream>, indexStream: windows_core::Ref<'_, super::super::Storage::Streams::IRandomAccessStream>, defaultLanguage: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromUriWithIndexAndLanguage(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>, indexUri: windows_core::Ref<'_, super::super::Foundation::Uri>, defaultLanguage: &windows_core::HSTRING) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl ITimedTextSourceStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromStreamWithIndex(this: *mut core::ffi::c_void, stream: *mut core::ffi::c_void, indexstream: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedTextSourceStatics2_Impl::CreateFromStreamWithIndex(this, core::mem::transmute_copy(&stream), core::mem::transmute_copy(&indexstream)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromUriWithIndex(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, indexuri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedTextSourceStatics2_Impl::CreateFromUriWithIndex(this, core::mem::transmute_copy(&uri), core::mem::transmute_copy(&indexuri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromStreamWithIndexAndLanguage(this: *mut core::ffi::c_void, stream: *mut core::ffi::c_void, indexstream: *mut core::ffi::c_void, defaultlanguage: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedTextSourceStatics2_Impl::CreateFromStreamWithIndexAndLanguage(this, core::mem::transmute_copy(&stream), core::mem::transmute_copy(&indexstream), core::mem::transmute(&defaultlanguage)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromUriWithIndexAndLanguage(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, indexuri: *mut core::ffi::c_void, defaultlanguage: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedTextSourceStatics2_Impl::CreateFromUriWithIndexAndLanguage(this, core::mem::transmute_copy(&uri), core::mem::transmute_copy(&indexuri), core::mem::transmute(&defaultlanguage)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromStreamWithIndex: CreateFromStreamWithIndex::, + CreateFromUriWithIndex: CreateFromUriWithIndex::, + CreateFromStreamWithIndexAndLanguage: CreateFromStreamWithIndexAndLanguage::, + CreateFromUriWithIndexAndLanguage: CreateFromUriWithIndexAndLanguage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ITimedTextSourceStatics2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Storage_Streams")] + pub CreateFromStreamWithIndex: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + CreateFromStreamWithIndex: usize, + pub CreateFromUriWithIndex: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Storage_Streams")] + pub CreateFromStreamWithIndexAndLanguage: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + CreateFromStreamWithIndexAndLanguage: usize, + pub CreateFromUriWithIndexAndLanguage: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoTrack, IVideoTrack_Vtbl, 0x99f3b7f3_e298_4396_bb6a_a51be6a2a20a); +impl windows_core::RuntimeType for IVideoTrack { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Media_MediaProperties", feature = "Media_Playback"))] +impl windows_core::RuntimeName for IVideoTrack { + const NAME: &'static str = "Windows.Media.Core.IVideoTrack"; +} +#[cfg(all(feature = "Media_MediaProperties", feature = "Media_Playback"))] +pub trait IVideoTrack_Impl: windows_core::IUnknownImpl { + fn OpenFailed(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveOpenFailed(&self, token: i64) -> windows_core::Result<()>; + fn GetEncodingProperties(&self) -> windows_core::Result; + fn PlaybackItem(&self) -> windows_core::Result; + fn Name(&self) -> windows_core::Result; + fn SupportInfo(&self) -> windows_core::Result; +} +#[cfg(all(feature = "Media_MediaProperties", feature = "Media_Playback"))] +impl IVideoTrack_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn OpenFailed(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoTrack_Impl::OpenFailed(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveOpenFailed(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVideoTrack_Impl::RemoveOpenFailed(this, token).into() + } + } + unsafe extern "system" fn GetEncodingProperties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoTrack_Impl::GetEncodingProperties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PlaybackItem(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoTrack_Impl::PlaybackItem(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Name(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoTrack_Impl::Name(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportInfo(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoTrack_Impl::SupportInfo(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + OpenFailed: OpenFailed::, + RemoveOpenFailed: RemoveOpenFailed::, + GetEncodingProperties: GetEncodingProperties::, + PlaybackItem: PlaybackItem::, + Name: Name::, + SupportInfo: SupportInfo::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoTrack_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub OpenFailed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveOpenFailed: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + #[cfg(feature = "Media_MediaProperties")] + pub GetEncodingProperties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + GetEncodingProperties: usize, + #[cfg(feature = "Media_Playback")] + pub PlaybackItem: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Playback"))] + PlaybackItem: usize, + pub Name: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SupportInfo: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoTrackOpenFailedEventArgs, IVideoTrackOpenFailedEventArgs_Vtbl, 0x7679e231_04f9_4c82_a4ee_8602c8bb4754); +impl windows_core::RuntimeType for IVideoTrackOpenFailedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoTrackOpenFailedEventArgs { + const NAME: &'static str = "Windows.Media.Core.IVideoTrackOpenFailedEventArgs"; +} +pub trait IVideoTrackOpenFailedEventArgs_Impl: windows_core::IUnknownImpl { + fn ExtendedError(&self) -> windows_core::Result; +} +impl IVideoTrackOpenFailedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ExtendedError(this: *mut core::ffi::c_void, result__: *mut windows_core::HRESULT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoTrackOpenFailedEventArgs_Impl::ExtendedError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ExtendedError: ExtendedError::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoTrackOpenFailedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ExtendedError: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_core::HRESULT) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoTrackSupportInfo, IVideoTrackSupportInfo_Vtbl, 0x4bb534a0_fc5f_450d_8ff0_778d590486de); +impl windows_core::RuntimeType for IVideoTrackSupportInfo { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoTrackSupportInfo { + const NAME: &'static str = "Windows.Media.Core.IVideoTrackSupportInfo"; +} +pub trait IVideoTrackSupportInfo_Impl: windows_core::IUnknownImpl { + fn DecoderStatus(&self) -> windows_core::Result; + fn MediaSourceStatus(&self) -> windows_core::Result; +} +impl IVideoTrackSupportInfo_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DecoderStatus(this: *mut core::ffi::c_void, result__: *mut MediaDecoderStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoTrackSupportInfo_Impl::DecoderStatus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MediaSourceStatus(this: *mut core::ffi::c_void, result__: *mut MediaSourceStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoTrackSupportInfo_Impl::MediaSourceStatus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DecoderStatus: DecoderStatus::, + MediaSourceStatus: MediaSourceStatus::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoTrackSupportInfo_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub DecoderStatus: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaDecoderStatus) -> windows_core::HRESULT, + pub MediaSourceStatus: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaSourceStatus) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaBinder(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaBinder, windows_core::IUnknown, windows_core::IInspectable); +impl MediaBinder { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn Binding(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Binding)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveBinding(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveBinding)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn Token(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Token)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetToken(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetToken)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + #[cfg(feature = "Media_Playback")] + pub fn Source(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Source)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaBinder { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaBinder { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaBinder { + const NAME: &'static str = "Windows.Media.Core.MediaBinder"; +} +unsafe impl Send for MediaBinder {} +unsafe impl Sync for MediaBinder {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaBindingEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaBindingEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl MediaBindingEventArgs { + pub fn Canceled(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Canceled)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveCanceled(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveCanceled)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn MediaBinder(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MediaBinder)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetDeferral(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeferral)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetUri(&self, uri: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetUri)(windows_core::Interface::as_raw(this), uri.param().abi()).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn SetStream(&self, stream: P0, contenttype: &windows_core::HSTRING) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetStream)(windows_core::Interface::as_raw(this), stream.param().abi(), core::mem::transmute_copy(contenttype)).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn SetStreamReference(&self, stream: P0, contenttype: &windows_core::HSTRING) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetStreamReference)(windows_core::Interface::as_raw(this), stream.param().abi(), core::mem::transmute_copy(contenttype)).ok() } + } + #[cfg(feature = "Media_Streaming_Adaptive")] + pub fn SetAdaptiveMediaSource(&self, mediasource: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAdaptiveMediaSource)(windows_core::Interface::as_raw(this), mediasource.param().abi()).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn SetStorageFile(&self, file: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetStorageFile)(windows_core::Interface::as_raw(this), file.param().abi()).ok() } + } + #[cfg(feature = "Networking_BackgroundTransfer")] + pub fn SetDownloadOperation(&self, downloadoperation: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetDownloadOperation)(windows_core::Interface::as_raw(this), downloadoperation.param().abi()).ok() } + } +} +impl windows_core::RuntimeType for MediaBindingEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaBindingEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaBindingEventArgs { + const NAME: &'static str = "Windows.Media.Core.MediaBindingEventArgs"; +} +unsafe impl Send for MediaBindingEventArgs {} +unsafe impl Sync for MediaBindingEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaCueEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaCueEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl MediaCueEventArgs { + pub fn Cue(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Cue)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaCueEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaCueEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaCueEventArgs { + const NAME: &'static str = "Windows.Media.Core.MediaCueEventArgs"; +} +unsafe impl Send for MediaCueEventArgs {} +unsafe impl Sync for MediaCueEventArgs {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaDecoderStatus(pub i32); +impl MediaDecoderStatus { + pub const FullySupported: Self = Self(0i32); + pub const UnsupportedSubtype: Self = Self(1i32); + pub const UnsupportedEncoderProperties: Self = Self(2i32); + pub const Degraded: Self = Self(3i32); +} +impl windows_core::TypeKind for MediaDecoderStatus { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaDecoderStatus { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Core.MediaDecoderStatus;i4)"); +} +#[cfg(feature = "Media_Playback")] +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaSource(windows_core::IUnknown); +#[cfg(feature = "Media_Playback")] +windows_core::imp::interface_hierarchy!(MediaSource, windows_core::IUnknown, windows_core::IInspectable); +#[cfg(feature = "Media_Playback")] +windows_core::imp::required_hierarchy!(MediaSource, super::super::Foundation::IClosable, super::Playback::IMediaPlaybackSource); +#[cfg(feature = "Media_Playback")] +impl MediaSource { + pub fn Close(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn OpenOperationCompleted(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenOperationCompleted)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveOpenOperationCompleted(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveOpenOperationCompleted)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Foundation_Collections")] + pub fn CustomProperties(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CustomProperties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Duration(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Duration)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IsOpen(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsOpen)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Foundation_Collections")] + pub fn ExternalTimedTextSources(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExternalTimedTextSources)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Foundation_Collections")] + pub fn ExternalTimedMetadataTracks(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExternalTimedMetadataTracks)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn StateChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StateChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveStateChanged(&self, token: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveStateChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn State(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).State)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Reset(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Reset)(windows_core::Interface::as_raw(this)).ok() } + } + #[cfg(feature = "Media_Streaming_Adaptive")] + pub fn AdaptiveMediaSource(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AdaptiveMediaSource)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MediaStreamSource(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MediaStreamSource)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MseStreamSource(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MseStreamSource)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Uri(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Uri)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn OpenAsync(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Networking_BackgroundTransfer")] + pub fn DownloadOperation(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DownloadOperation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Media_Streaming_Adaptive")] + pub fn CreateFromAdaptiveMediaSource(mediasource: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromAdaptiveMediaSource)(windows_core::Interface::as_raw(this), mediasource.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromMediaStreamSource(mediasource: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromMediaStreamSource)(windows_core::Interface::as_raw(this), mediasource.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromMseStreamSource(mediasource: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromMseStreamSource)(windows_core::Interface::as_raw(this), mediasource.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromIMediaSource(mediasource: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromIMediaSource)(windows_core::Interface::as_raw(this), mediasource.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFromStorageFile(file: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromStorageFile)(windows_core::Interface::as_raw(this), file.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFromStream(stream: P0, contenttype: &windows_core::HSTRING) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromStream)(windows_core::Interface::as_raw(this), stream.param().abi(), core::mem::transmute_copy(contenttype), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFromStreamReference(stream: P0, contenttype: &windows_core::HSTRING) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromStreamReference)(windows_core::Interface::as_raw(this), stream.param().abi(), core::mem::transmute_copy(contenttype), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromUri(uri: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromUri)(windows_core::Interface::as_raw(this), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromMediaBinder(binder: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaSourceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromMediaBinder)(windows_core::Interface::as_raw(this), binder.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Media_Capture_Frames")] + pub fn CreateFromMediaFrameSource(framesource: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaSourceStatics3(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromMediaFrameSource)(windows_core::Interface::as_raw(this), framesource.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Networking_BackgroundTransfer")] + pub fn CreateFromDownloadOperation(downloadoperation: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaSourceStatics4(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromDownloadOperation)(windows_core::Interface::as_raw(this), downloadoperation.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn IMediaSourceStatics windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn IMediaSourceStatics2 windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn IMediaSourceStatics3 windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn IMediaSourceStatics4 windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +#[cfg(feature = "Media_Playback")] +impl windows_core::RuntimeType for MediaSource { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +#[cfg(feature = "Media_Playback")] +unsafe impl windows_core::Interface for MediaSource { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +#[cfg(feature = "Media_Playback")] +impl windows_core::RuntimeName for MediaSource { + const NAME: &'static str = "Windows.Media.Core.MediaSource"; +} +#[cfg(feature = "Media_Playback")] +unsafe impl Send for MediaSource {} +#[cfg(feature = "Media_Playback")] +unsafe impl Sync for MediaSource {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaSourceError(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaSourceError, windows_core::IUnknown, windows_core::IInspectable); +impl MediaSourceError { + pub fn ExtendedError(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExtendedError)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for MediaSourceError { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaSourceError { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaSourceError { + const NAME: &'static str = "Windows.Media.Core.MediaSourceError"; +} +unsafe impl Send for MediaSourceError {} +unsafe impl Sync for MediaSourceError {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaSourceOpenOperationCompletedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaSourceOpenOperationCompletedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl MediaSourceOpenOperationCompletedEventArgs { + pub fn Error(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Error)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaSourceOpenOperationCompletedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaSourceOpenOperationCompletedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaSourceOpenOperationCompletedEventArgs { + const NAME: &'static str = "Windows.Media.Core.MediaSourceOpenOperationCompletedEventArgs"; +} +unsafe impl Send for MediaSourceOpenOperationCompletedEventArgs {} +unsafe impl Sync for MediaSourceOpenOperationCompletedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaSourceState(pub i32); +impl MediaSourceState { + pub const Initial: Self = Self(0i32); + pub const Opening: Self = Self(1i32); + pub const Opened: Self = Self(2i32); + pub const Failed: Self = Self(3i32); + pub const Closed: Self = Self(4i32); +} +impl windows_core::TypeKind for MediaSourceState { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaSourceState { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Core.MediaSourceState;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaSourceStateChangedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaSourceStateChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl MediaSourceStateChangedEventArgs { + pub fn OldState(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OldState)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn NewState(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NewState)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for MediaSourceStateChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaSourceStateChangedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaSourceStateChangedEventArgs { + const NAME: &'static str = "Windows.Media.Core.MediaSourceStateChangedEventArgs"; +} +unsafe impl Send for MediaSourceStateChangedEventArgs {} +unsafe impl Sync for MediaSourceStateChangedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaSourceStatus(pub i32); +impl MediaSourceStatus { + pub const FullySupported: Self = Self(0i32); + pub const Unknown: Self = Self(1i32); +} +impl windows_core::TypeKind for MediaSourceStatus { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaSourceStatus { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Core.MediaSourceStatus;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSample(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaStreamSample, windows_core::IUnknown, windows_core::IInspectable); +impl MediaStreamSample { + pub fn Processed(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Processed)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveProcessed(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveProcessed)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn Buffer(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Buffer)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Timestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ExtendedProperties(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExtendedProperties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Protection(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Protection)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetDecodeTimestamp(&self, value: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDecodeTimestamp)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn DecodeTimestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DecodeTimestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetDuration(&self, value: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDuration)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Duration(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Duration)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetKeyFrame(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetKeyFrame)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn KeyFrame(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).KeyFrame)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetDiscontinuous(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDiscontinuous)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Discontinuous(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Discontinuous)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Graphics_DirectX_Direct3D11")] + pub fn Direct3D11Surface(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Direct3D11Surface)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFromBuffer(buffer: P0, timestamp: super::super::Foundation::TimeSpan) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaStreamSampleStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromBuffer)(windows_core::Interface::as_raw(this), buffer.param().abi(), timestamp, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFromStreamAsync(stream: P0, count: u32, timestamp: super::super::Foundation::TimeSpan) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::IMediaStreamSampleStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromStreamAsync)(windows_core::Interface::as_raw(this), stream.param().abi(), count, timestamp, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Graphics_DirectX_Direct3D11")] + pub fn CreateFromDirect3D11Surface(surface: P0, timestamp: super::super::Foundation::TimeSpan) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaStreamSampleStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromDirect3D11Surface)(windows_core::Interface::as_raw(this), surface.param().abi(), timestamp, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn IMediaStreamSampleStatics windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn IMediaStreamSampleStatics2 windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for MediaStreamSample { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaStreamSample { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaStreamSample { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSample"; +} +unsafe impl Send for MediaStreamSample {} +unsafe impl Sync for MediaStreamSample {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSamplePropertySet(windows_core::IUnknown); +windows_core::imp::interface_hierarchy ! ( MediaStreamSamplePropertySet , windows_core::IUnknown , windows_core::IInspectable , windows_collections:: IMap < windows_core::GUID , windows_core::IInspectable > ); +windows_core::imp::required_hierarchy!(MediaStreamSamplePropertySet, windows_collections::IIterable>); +impl MediaStreamSamplePropertySet { + pub fn First(&self) -> windows_core::Result>> { + let this = &windows_core::Interface::cast::>>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Lookup(&self, key: windows_core::GUID) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Lookup)(windows_core::Interface::as_raw(this), key, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn HasKey(&self, key: windows_core::GUID) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HasKey)(windows_core::Interface::as_raw(this), key, &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Insert(&self, key: windows_core::GUID, value: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Insert)(windows_core::Interface::as_raw(this), key, value.param().abi(), &mut result__).map(|| result__) + } + } + pub fn Remove(&self, key: windows_core::GUID) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Remove)(windows_core::Interface::as_raw(this), key).ok() } + } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } +} +impl windows_core::RuntimeType for MediaStreamSamplePropertySet { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::>(); +} +unsafe impl windows_core::Interface for MediaStreamSamplePropertySet { + type Vtable = as windows_core::Interface>::Vtable; + const IID: windows_core::GUID = as windows_core::Interface>::IID; +} +impl windows_core::RuntimeName for MediaStreamSamplePropertySet { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSamplePropertySet"; +} +unsafe impl Send for MediaStreamSamplePropertySet {} +unsafe impl Sync for MediaStreamSamplePropertySet {} +impl IntoIterator for MediaStreamSamplePropertySet { + type Item = windows_collections::IKeyValuePair; + type IntoIter = windows_collections::IIterator; + fn into_iter(self) -> Self::IntoIter { + IntoIterator::into_iter(&self) + } +} +impl IntoIterator for &MediaStreamSamplePropertySet { + type Item = windows_collections::IKeyValuePair; + type IntoIter = windows_collections::IIterator; + fn into_iter(self) -> Self::IntoIter { + self.First().unwrap() + } +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSampleProtectionProperties(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaStreamSampleProtectionProperties, windows_core::IUnknown, windows_core::IInspectable); +impl MediaStreamSampleProtectionProperties { + pub fn SetKeyIdentifier(&self, value: &[u8]) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetKeyIdentifier)(windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr()).ok() } + } + pub fn GetKeyIdentifier(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetKeyIdentifier)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn SetInitializationVector(&self, value: &[u8]) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetInitializationVector)(windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr()).ok() } + } + pub fn GetInitializationVector(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetInitializationVector)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn SetSubSampleMapping(&self, value: &[u8]) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSubSampleMapping)(windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr()).ok() } + } + pub fn GetSubSampleMapping(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).GetSubSampleMapping)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } +} +impl windows_core::RuntimeType for MediaStreamSampleProtectionProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaStreamSampleProtectionProperties { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaStreamSampleProtectionProperties { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSampleProtectionProperties"; +} +unsafe impl Send for MediaStreamSampleProtectionProperties {} +unsafe impl Sync for MediaStreamSampleProtectionProperties {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSource(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaStreamSource, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(MediaStreamSource, IMediaSource); +impl MediaStreamSource { + pub fn Closed(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Closed)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveClosed(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveClosed)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn Starting(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Starting)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveStarting(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveStarting)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn Paused(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Paused)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemovePaused(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemovePaused)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn SampleRequested(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SampleRequested)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveSampleRequested(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveSampleRequested)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn SwitchStreamsRequested(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SwitchStreamsRequested)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveSwitchStreamsRequested(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveSwitchStreamsRequested)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn NotifyError(&self, errorstatus: MediaStreamSourceErrorStatus) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).NotifyError)(windows_core::Interface::as_raw(this), errorstatus).ok() } + } + pub fn AddStreamDescriptor(&self, descriptor: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).AddStreamDescriptor)(windows_core::Interface::as_raw(this), descriptor.param().abi()).ok() } + } + #[cfg(feature = "Media_Protection")] + pub fn SetMediaProtectionManager(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMediaProtectionManager)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + #[cfg(feature = "Media_Protection")] + pub fn MediaProtectionManager(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MediaProtectionManager)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetDuration(&self, value: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDuration)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Duration(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Duration)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetCanSeek(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetCanSeek)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn CanSeek(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanSeek)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetBufferTime(&self, value: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetBufferTime)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn BufferTime(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BufferTime)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetBufferedRange(&self, startoffset: super::super::Foundation::TimeSpan, endoffset: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetBufferedRange)(windows_core::Interface::as_raw(this), startoffset, endoffset).ok() } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn MusicProperties(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MusicProperties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn VideoProperties(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).VideoProperties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn SetThumbnail(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetThumbnail)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn Thumbnail(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Thumbnail)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn AddProtectionKey(&self, streamdescriptor: P0, keyidentifier: &[u8], licensedata: &[u8]) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).AddProtectionKey)(windows_core::Interface::as_raw(this), streamdescriptor.param().abi(), keyidentifier.len().try_into().unwrap(), keyidentifier.as_ptr(), licensedata.len().try_into().unwrap(), licensedata.as_ptr()).ok() } + } + pub fn SampleRendered(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SampleRendered)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveSampleRendered(&self, token: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveSampleRendered)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn SetMaxSupportedPlaybackRate(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetMaxSupportedPlaybackRate)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn MaxSupportedPlaybackRate(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxSupportedPlaybackRate)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetIsLive(&self, value: bool) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetIsLive)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn IsLive(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsLive)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CreateFromDescriptor(descriptor: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaStreamSourceFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromDescriptor)(windows_core::Interface::as_raw(this), descriptor.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromDescriptors(descriptor: P0, descriptor2: P1) -> windows_core::Result + where + P0: windows_core::Param, + P1: windows_core::Param, + { + Self::IMediaStreamSourceFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromDescriptors)(windows_core::Interface::as_raw(this), descriptor.param().abi(), descriptor2.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn IMediaStreamSourceFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for MediaStreamSource { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaStreamSource { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaStreamSource { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSource"; +} +unsafe impl Send for MediaStreamSource {} +unsafe impl Sync for MediaStreamSource {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSourceClosedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaStreamSourceClosedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl MediaStreamSourceClosedEventArgs { + pub fn Request(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Request)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaStreamSourceClosedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaStreamSourceClosedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaStreamSourceClosedEventArgs { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSourceClosedEventArgs"; +} +unsafe impl Send for MediaStreamSourceClosedEventArgs {} +unsafe impl Sync for MediaStreamSourceClosedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaStreamSourceClosedReason(pub i32); +impl MediaStreamSourceClosedReason { + pub const Done: Self = Self(0i32); + pub const UnknownError: Self = Self(1i32); + pub const AppReportedError: Self = Self(2i32); + pub const UnsupportedProtectionSystem: Self = Self(3i32); + pub const ProtectionSystemFailure: Self = Self(4i32); + pub const UnsupportedEncodingFormat: Self = Self(5i32); + pub const MissingSampleRequestedEventHandler: Self = Self(6i32); +} +impl windows_core::TypeKind for MediaStreamSourceClosedReason { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaStreamSourceClosedReason { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Core.MediaStreamSourceClosedReason;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSourceClosedRequest(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaStreamSourceClosedRequest, windows_core::IUnknown, windows_core::IInspectable); +impl MediaStreamSourceClosedRequest { + pub fn Reason(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Reason)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for MediaStreamSourceClosedRequest { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaStreamSourceClosedRequest { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaStreamSourceClosedRequest { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSourceClosedRequest"; +} +unsafe impl Send for MediaStreamSourceClosedRequest {} +unsafe impl Sync for MediaStreamSourceClosedRequest {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaStreamSourceErrorStatus(pub i32); +impl MediaStreamSourceErrorStatus { + pub const Other: Self = Self(0i32); + pub const OutOfMemory: Self = Self(1i32); + pub const FailedToOpenFile: Self = Self(2i32); + pub const FailedToConnectToServer: Self = Self(3i32); + pub const ConnectionToServerLost: Self = Self(4i32); + pub const UnspecifiedNetworkError: Self = Self(5i32); + pub const DecodeError: Self = Self(6i32); + pub const UnsupportedMediaFormat: Self = Self(7i32); +} +impl windows_core::TypeKind for MediaStreamSourceErrorStatus { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaStreamSourceErrorStatus { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Core.MediaStreamSourceErrorStatus;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSourceSampleRenderedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaStreamSourceSampleRenderedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl MediaStreamSourceSampleRenderedEventArgs { + pub fn SampleLag(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SampleLag)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for MediaStreamSourceSampleRenderedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaStreamSourceSampleRenderedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaStreamSourceSampleRenderedEventArgs { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSourceSampleRenderedEventArgs"; +} +unsafe impl Send for MediaStreamSourceSampleRenderedEventArgs {} +unsafe impl Sync for MediaStreamSourceSampleRenderedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSourceSampleRequest(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaStreamSourceSampleRequest, windows_core::IUnknown, windows_core::IInspectable); +impl MediaStreamSourceSampleRequest { + pub fn StreamDescriptor(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StreamDescriptor)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetDeferral(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeferral)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetSample(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSample)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn Sample(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Sample)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ReportSampleProgress(&self, progress: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ReportSampleProgress)(windows_core::Interface::as_raw(this), progress).ok() } + } +} +impl windows_core::RuntimeType for MediaStreamSourceSampleRequest { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaStreamSourceSampleRequest { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaStreamSourceSampleRequest { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSourceSampleRequest"; +} +unsafe impl Send for MediaStreamSourceSampleRequest {} +unsafe impl Sync for MediaStreamSourceSampleRequest {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSourceSampleRequestDeferral(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaStreamSourceSampleRequestDeferral, windows_core::IUnknown, windows_core::IInspectable); +impl MediaStreamSourceSampleRequestDeferral { + pub fn Complete(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Complete)(windows_core::Interface::as_raw(this)).ok() } + } +} +impl windows_core::RuntimeType for MediaStreamSourceSampleRequestDeferral { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaStreamSourceSampleRequestDeferral { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaStreamSourceSampleRequestDeferral { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSourceSampleRequestDeferral"; +} +unsafe impl Send for MediaStreamSourceSampleRequestDeferral {} +unsafe impl Sync for MediaStreamSourceSampleRequestDeferral {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSourceSampleRequestedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaStreamSourceSampleRequestedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl MediaStreamSourceSampleRequestedEventArgs { + pub fn Request(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Request)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaStreamSourceSampleRequestedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaStreamSourceSampleRequestedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaStreamSourceSampleRequestedEventArgs { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSourceSampleRequestedEventArgs"; +} +unsafe impl Send for MediaStreamSourceSampleRequestedEventArgs {} +unsafe impl Sync for MediaStreamSourceSampleRequestedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSourceStartingEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaStreamSourceStartingEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl MediaStreamSourceStartingEventArgs { + pub fn Request(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Request)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaStreamSourceStartingEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaStreamSourceStartingEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaStreamSourceStartingEventArgs { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSourceStartingEventArgs"; +} +unsafe impl Send for MediaStreamSourceStartingEventArgs {} +unsafe impl Sync for MediaStreamSourceStartingEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSourceStartingRequest(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaStreamSourceStartingRequest, windows_core::IUnknown, windows_core::IInspectable); +impl MediaStreamSourceStartingRequest { + pub fn StartPosition(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StartPosition)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetDeferral(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeferral)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetActualStartPosition(&self, position: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetActualStartPosition)(windows_core::Interface::as_raw(this), position).ok() } + } +} +impl windows_core::RuntimeType for MediaStreamSourceStartingRequest { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaStreamSourceStartingRequest { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaStreamSourceStartingRequest { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSourceStartingRequest"; +} +unsafe impl Send for MediaStreamSourceStartingRequest {} +unsafe impl Sync for MediaStreamSourceStartingRequest {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSourceStartingRequestDeferral(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaStreamSourceStartingRequestDeferral, windows_core::IUnknown, windows_core::IInspectable); +impl MediaStreamSourceStartingRequestDeferral { + pub fn Complete(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Complete)(windows_core::Interface::as_raw(this)).ok() } + } +} +impl windows_core::RuntimeType for MediaStreamSourceStartingRequestDeferral { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaStreamSourceStartingRequestDeferral { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaStreamSourceStartingRequestDeferral { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSourceStartingRequestDeferral"; +} +unsafe impl Send for MediaStreamSourceStartingRequestDeferral {} +unsafe impl Sync for MediaStreamSourceStartingRequestDeferral {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSourceSwitchStreamsRequest(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaStreamSourceSwitchStreamsRequest, windows_core::IUnknown, windows_core::IInspectable); +impl MediaStreamSourceSwitchStreamsRequest { + pub fn OldStreamDescriptor(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OldStreamDescriptor)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn NewStreamDescriptor(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NewStreamDescriptor)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetDeferral(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeferral)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaStreamSourceSwitchStreamsRequest { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaStreamSourceSwitchStreamsRequest { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaStreamSourceSwitchStreamsRequest { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSourceSwitchStreamsRequest"; +} +unsafe impl Send for MediaStreamSourceSwitchStreamsRequest {} +unsafe impl Sync for MediaStreamSourceSwitchStreamsRequest {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSourceSwitchStreamsRequestDeferral(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaStreamSourceSwitchStreamsRequestDeferral, windows_core::IUnknown, windows_core::IInspectable); +impl MediaStreamSourceSwitchStreamsRequestDeferral { + pub fn Complete(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Complete)(windows_core::Interface::as_raw(this)).ok() } + } +} +impl windows_core::RuntimeType for MediaStreamSourceSwitchStreamsRequestDeferral { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaStreamSourceSwitchStreamsRequestDeferral { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaStreamSourceSwitchStreamsRequestDeferral { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSourceSwitchStreamsRequestDeferral"; +} +unsafe impl Send for MediaStreamSourceSwitchStreamsRequestDeferral {} +unsafe impl Sync for MediaStreamSourceSwitchStreamsRequestDeferral {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaStreamSourceSwitchStreamsRequestedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaStreamSourceSwitchStreamsRequestedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl MediaStreamSourceSwitchStreamsRequestedEventArgs { + pub fn Request(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Request)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaStreamSourceSwitchStreamsRequestedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaStreamSourceSwitchStreamsRequestedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaStreamSourceSwitchStreamsRequestedEventArgs { + const NAME: &'static str = "Windows.Media.Core.MediaStreamSourceSwitchStreamsRequestedEventArgs"; +} +unsafe impl Send for MediaStreamSourceSwitchStreamsRequestedEventArgs {} +unsafe impl Sync for MediaStreamSourceSwitchStreamsRequestedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaTrackKind(pub i32); +impl MediaTrackKind { + pub const Audio: Self = Self(0i32); + pub const Video: Self = Self(1i32); + pub const TimedMetadata: Self = Self(2i32); +} +impl windows_core::TypeKind for MediaTrackKind { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaTrackKind { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Core.MediaTrackKind;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MseAppendMode(pub i32); +impl MseAppendMode { + pub const Segments: Self = Self(0i32); + pub const Sequence: Self = Self(1i32); +} +impl windows_core::TypeKind for MseAppendMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MseAppendMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Core.MseAppendMode;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MseEndOfStreamStatus(pub i32); +impl MseEndOfStreamStatus { + pub const Success: Self = Self(0i32); + pub const NetworkError: Self = Self(1i32); + pub const DecodeError: Self = Self(2i32); + pub const UnknownError: Self = Self(3i32); +} +impl windows_core::TypeKind for MseEndOfStreamStatus { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MseEndOfStreamStatus { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Core.MseEndOfStreamStatus;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MseReadyState(pub i32); +impl MseReadyState { + pub const Closed: Self = Self(0i32); + pub const Open: Self = Self(1i32); + pub const Ended: Self = Self(2i32); +} +impl windows_core::TypeKind for MseReadyState { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MseReadyState { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Core.MseReadyState;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MseSourceBuffer(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MseSourceBuffer, windows_core::IUnknown, windows_core::IInspectable); +impl MseSourceBuffer { + pub fn UpdateStarting(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UpdateStarting)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveUpdateStarting(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveUpdateStarting)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn Updated(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Updated)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveUpdated(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveUpdated)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn UpdateEnded(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UpdateEnded)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveUpdateEnded(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveUpdateEnded)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn ErrorOccurred(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ErrorOccurred)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveErrorOccurred(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveErrorOccurred)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn Aborted(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Aborted)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveAborted(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveAborted)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn Mode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Mode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetMode(&self, value: MseAppendMode) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMode)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn IsUpdating(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsUpdating)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Buffered(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Buffered)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TimestampOffset(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TimestampOffset)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetTimestampOffset(&self, value: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetTimestampOffset)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn AppendWindowStart(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AppendWindowStart)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAppendWindowStart(&self, value: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAppendWindowStart)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn AppendWindowEnd(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AppendWindowEnd)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetAppendWindowEnd(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAppendWindowEnd)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn AppendBuffer(&self, buffer: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).AppendBuffer)(windows_core::Interface::as_raw(this), buffer.param().abi()).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn AppendStream(&self, stream: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).AppendStream)(windows_core::Interface::as_raw(this), stream.param().abi()).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn AppendStreamMaxSize(&self, stream: P0, maxsize: u64) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).AppendStreamMaxSize)(windows_core::Interface::as_raw(this), stream.param().abi(), maxsize).ok() } + } + pub fn Abort(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Abort)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn Remove(&self, start: super::super::Foundation::TimeSpan, end: P1) -> windows_core::Result<()> + where + P1: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Remove)(windows_core::Interface::as_raw(this), start, end.param().abi()).ok() } + } +} +impl windows_core::RuntimeType for MseSourceBuffer { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MseSourceBuffer { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MseSourceBuffer { + const NAME: &'static str = "Windows.Media.Core.MseSourceBuffer"; +} +unsafe impl Send for MseSourceBuffer {} +unsafe impl Sync for MseSourceBuffer {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MseSourceBufferList(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MseSourceBufferList, windows_core::IUnknown, windows_core::IInspectable); +impl MseSourceBufferList { + pub fn SourceBufferAdded(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SourceBufferAdded)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveSourceBufferAdded(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveSourceBufferAdded)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn SourceBufferRemoved(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SourceBufferRemoved)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveSourceBufferRemoved(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveSourceBufferRemoved)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn Buffers(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Buffers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MseSourceBufferList { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MseSourceBufferList { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MseSourceBufferList { + const NAME: &'static str = "Windows.Media.Core.MseSourceBufferList"; +} +unsafe impl Send for MseSourceBufferList {} +unsafe impl Sync for MseSourceBufferList {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MseStreamSource(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MseStreamSource, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(MseStreamSource, IMediaSource); +impl MseStreamSource { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn Opened(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Opened)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveOpened(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveOpened)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn Ended(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Ended)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveEnded(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveEnded)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn Closed(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Closed)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveClosed(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveClosed)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn SourceBuffers(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SourceBuffers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ActiveSourceBuffers(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ActiveSourceBuffers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ReadyState(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadyState)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Duration(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Duration)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetDuration(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDuration)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn AddSourceBuffer(&self, mimetype: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AddSourceBuffer)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(mimetype), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RemoveSourceBuffer(&self, buffer: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveSourceBuffer)(windows_core::Interface::as_raw(this), buffer.param().abi()).ok() } + } + pub fn EndOfStream(&self, status: MseEndOfStreamStatus) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).EndOfStream)(windows_core::Interface::as_raw(this), status).ok() } + } + pub fn LiveSeekableRange(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LiveSeekableRange)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetLiveSeekableRange(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetLiveSeekableRange)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn IsContentTypeSupported(contenttype: &windows_core::HSTRING) -> windows_core::Result { + Self::IMseStreamSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsContentTypeSupported)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(contenttype), &mut result__).map(|| result__) + }) + } + fn IMseStreamSourceStatics windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for MseStreamSource { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MseStreamSource { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MseStreamSource { + const NAME: &'static str = "Windows.Media.Core.MseStreamSource"; +} +unsafe impl Send for MseStreamSource {} +unsafe impl Sync for MseStreamSource {} +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct MseTimeRange { + pub Start: super::super::Foundation::TimeSpan, + pub End: super::super::Foundation::TimeSpan, +} +impl windows_core::TypeKind for MseTimeRange { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MseTimeRange { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"struct(Windows.Media.Core.MseTimeRange;struct(Windows.Foundation.TimeSpan;i8);struct(Windows.Foundation.TimeSpan;i8))"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct TimedMetadataKind(pub i32); +impl TimedMetadataKind { + pub const Caption: Self = Self(0i32); + pub const Chapter: Self = Self(1i32); + pub const Custom: Self = Self(2i32); + pub const Data: Self = Self(3i32); + pub const Description: Self = Self(4i32); + pub const Subtitle: Self = Self(5i32); + pub const ImageSubtitle: Self = Self(6i32); + pub const Speech: Self = Self(7i32); +} +impl windows_core::TypeKind for TimedMetadataKind { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for TimedMetadataKind { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Core.TimedMetadataKind;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct TimedMetadataTrack(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(TimedMetadataTrack, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(TimedMetadataTrack, IMediaTrack); +impl TimedMetadataTrack { + pub fn Id(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Id)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Language(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Language)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn TrackKind(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrackKind)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetLabel(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetLabel)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Label(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Label)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn CueEntered(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CueEntered)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveCueEntered(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveCueEntered)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn CueExited(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CueExited)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveCueExited(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveCueExited)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn TrackFailed(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrackFailed)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveTrackFailed(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveTrackFailed)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn Cues(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Cues)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ActiveCues(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ActiveCues)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TimedMetadataKind(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TimedMetadataKind)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DispatchType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DispatchType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn AddCue(&self, cue: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).AddCue)(windows_core::Interface::as_raw(this), cue.param().abi()).ok() } + } + pub fn RemoveCue(&self, cue: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveCue)(windows_core::Interface::as_raw(this), cue.param().abi()).ok() } + } + #[cfg(feature = "Media_Playback")] + pub fn PlaybackItem(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PlaybackItem)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Name(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Create(id: &windows_core::HSTRING, language: &windows_core::HSTRING, kind: TimedMetadataKind) -> windows_core::Result { + Self::ITimedMetadataTrackFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(id), core::mem::transmute_copy(language), kind, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn ITimedMetadataTrackFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for TimedMetadataTrack { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for TimedMetadataTrack { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for TimedMetadataTrack { + const NAME: &'static str = "Windows.Media.Core.TimedMetadataTrack"; +} +unsafe impl Send for TimedMetadataTrack {} +unsafe impl Sync for TimedMetadataTrack {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct TimedMetadataTrackError(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(TimedMetadataTrackError, windows_core::IUnknown, windows_core::IInspectable); +impl TimedMetadataTrackError { + pub fn ErrorCode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ErrorCode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ExtendedError(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExtendedError)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for TimedMetadataTrackError { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for TimedMetadataTrackError { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for TimedMetadataTrackError { + const NAME: &'static str = "Windows.Media.Core.TimedMetadataTrackError"; +} +unsafe impl Send for TimedMetadataTrackError {} +unsafe impl Sync for TimedMetadataTrackError {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct TimedMetadataTrackErrorCode(pub i32); +impl TimedMetadataTrackErrorCode { + pub const None: Self = Self(0i32); + pub const DataFormatError: Self = Self(1i32); + pub const NetworkError: Self = Self(2i32); + pub const InternalError: Self = Self(3i32); +} +impl windows_core::TypeKind for TimedMetadataTrackErrorCode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for TimedMetadataTrackErrorCode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Core.TimedMetadataTrackErrorCode;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct TimedMetadataTrackFailedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(TimedMetadataTrackFailedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl TimedMetadataTrackFailedEventArgs { + pub fn Error(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Error)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for TimedMetadataTrackFailedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for TimedMetadataTrackFailedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for TimedMetadataTrackFailedEventArgs { + const NAME: &'static str = "Windows.Media.Core.TimedMetadataTrackFailedEventArgs"; +} +unsafe impl Send for TimedMetadataTrackFailedEventArgs {} +unsafe impl Sync for TimedMetadataTrackFailedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct TimedTextSource(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(TimedTextSource, windows_core::IUnknown, windows_core::IInspectable); +impl TimedTextSource { + pub fn Resolved(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Resolved)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveResolved(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveResolved)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFromStream(stream: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::ITimedTextSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromStream)(windows_core::Interface::as_raw(this), stream.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromUri(uri: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::ITimedTextSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromUri)(windows_core::Interface::as_raw(this), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFromStreamWithLanguage(stream: P0, defaultlanguage: &windows_core::HSTRING) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::ITimedTextSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromStreamWithLanguage)(windows_core::Interface::as_raw(this), stream.param().abi(), core::mem::transmute_copy(defaultlanguage), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromUriWithLanguage(uri: P0, defaultlanguage: &windows_core::HSTRING) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::ITimedTextSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromUriWithLanguage)(windows_core::Interface::as_raw(this), uri.param().abi(), core::mem::transmute_copy(defaultlanguage), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFromStreamWithIndex(stream: P0, indexstream: P1) -> windows_core::Result + where + P0: windows_core::Param, + P1: windows_core::Param, + { + Self::ITimedTextSourceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromStreamWithIndex)(windows_core::Interface::as_raw(this), stream.param().abi(), indexstream.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromUriWithIndex(uri: P0, indexuri: P1) -> windows_core::Result + where + P0: windows_core::Param, + P1: windows_core::Param, + { + Self::ITimedTextSourceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromUriWithIndex)(windows_core::Interface::as_raw(this), uri.param().abi(), indexuri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFromStreamWithIndexAndLanguage(stream: P0, indexstream: P1, defaultlanguage: &windows_core::HSTRING) -> windows_core::Result + where + P0: windows_core::Param, + P1: windows_core::Param, + { + Self::ITimedTextSourceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromStreamWithIndexAndLanguage)(windows_core::Interface::as_raw(this), stream.param().abi(), indexstream.param().abi(), core::mem::transmute_copy(defaultlanguage), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromUriWithIndexAndLanguage(uri: P0, indexuri: P1, defaultlanguage: &windows_core::HSTRING) -> windows_core::Result + where + P0: windows_core::Param, + P1: windows_core::Param, + { + Self::ITimedTextSourceStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromUriWithIndexAndLanguage)(windows_core::Interface::as_raw(this), uri.param().abi(), indexuri.param().abi(), core::mem::transmute_copy(defaultlanguage), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn ITimedTextSourceStatics windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn ITimedTextSourceStatics2 windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for TimedTextSource { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for TimedTextSource { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for TimedTextSource { + const NAME: &'static str = "Windows.Media.Core.TimedTextSource"; +} +unsafe impl Send for TimedTextSource {} +unsafe impl Sync for TimedTextSource {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct TimedTextSourceResolveResultEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(TimedTextSourceResolveResultEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl TimedTextSourceResolveResultEventArgs { + pub fn Error(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Error)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Tracks(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Tracks)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for TimedTextSourceResolveResultEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for TimedTextSourceResolveResultEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for TimedTextSourceResolveResultEventArgs { + const NAME: &'static str = "Windows.Media.Core.TimedTextSourceResolveResultEventArgs"; +} +unsafe impl Send for TimedTextSourceResolveResultEventArgs {} +unsafe impl Sync for TimedTextSourceResolveResultEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VideoTrack(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(VideoTrack, windows_core::IUnknown, windows_core::IInspectable, IMediaTrack); +impl VideoTrack { + pub fn Id(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Id)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Language(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Language)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn TrackKind(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrackKind)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetLabel(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetLabel)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Label(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Label)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn OpenFailed(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenFailed)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveOpenFailed(&self, token: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveOpenFailed)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Media_MediaProperties")] + pub fn GetEncodingProperties(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetEncodingProperties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Media_Playback")] + pub fn PlaybackItem(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PlaybackItem)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Name(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SupportInfo(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportInfo)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for VideoTrack { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for VideoTrack { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for VideoTrack { + const NAME: &'static str = "Windows.Media.Core.VideoTrack"; +} +unsafe impl Send for VideoTrack {} +unsafe impl Sync for VideoTrack {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VideoTrackOpenFailedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(VideoTrackOpenFailedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl VideoTrackOpenFailedEventArgs { + pub fn ExtendedError(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExtendedError)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for VideoTrackOpenFailedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for VideoTrackOpenFailedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for VideoTrackOpenFailedEventArgs { + const NAME: &'static str = "Windows.Media.Core.VideoTrackOpenFailedEventArgs"; +} +unsafe impl Send for VideoTrackOpenFailedEventArgs {} +unsafe impl Sync for VideoTrackOpenFailedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VideoTrackSupportInfo(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(VideoTrackSupportInfo, windows_core::IUnknown, windows_core::IInspectable); +impl VideoTrackSupportInfo { + pub fn DecoderStatus(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DecoderStatus)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MediaSourceStatus(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MediaSourceStatus)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for VideoTrackSupportInfo { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for VideoTrackSupportInfo { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for VideoTrackSupportInfo { + const NAME: &'static str = "Windows.Media.Core.VideoTrackSupportInfo"; +} +unsafe impl Send for VideoTrackSupportInfo {} +unsafe impl Sync for VideoTrackSupportInfo {} +} +#[cfg(feature = "Media_Devices")] +pub mod Devices{ +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdvancedPhotoCaptureSettings(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AdvancedPhotoCaptureSettings, windows_core::IUnknown, windows_core::IInspectable); +impl AdvancedPhotoCaptureSettings { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn Mode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Mode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetMode(&self, value: AdvancedPhotoMode) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMode)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for AdvancedPhotoCaptureSettings { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AdvancedPhotoCaptureSettings { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AdvancedPhotoCaptureSettings { + const NAME: &'static str = "Windows.Media.Devices.AdvancedPhotoCaptureSettings"; +} +unsafe impl Send for AdvancedPhotoCaptureSettings {} +unsafe impl Sync for AdvancedPhotoCaptureSettings {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdvancedPhotoControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AdvancedPhotoControl, windows_core::IUnknown, windows_core::IInspectable); +impl AdvancedPhotoControl { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SupportedModes(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedModes)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Mode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Mode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Configure(&self, settings: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Configure)(windows_core::Interface::as_raw(this), settings.param().abi()).ok() } + } +} +impl windows_core::RuntimeType for AdvancedPhotoControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AdvancedPhotoControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AdvancedPhotoControl { + const NAME: &'static str = "Windows.Media.Devices.AdvancedPhotoControl"; +} +unsafe impl Send for AdvancedPhotoControl {} +unsafe impl Sync for AdvancedPhotoControl {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct AdvancedPhotoMode(pub i32); +impl AdvancedPhotoMode { + pub const Auto: Self = Self(0i32); + pub const Standard: Self = Self(1i32); + pub const Hdr: Self = Self(2i32); + pub const LowLight: Self = Self(3i32); +} +impl windows_core::TypeKind for AdvancedPhotoMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for AdvancedPhotoMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.AdvancedPhotoMode;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AudioDeviceController(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AudioDeviceController, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(AudioDeviceController, IMediaDeviceController); +impl AudioDeviceController { + pub fn SetMuted(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMuted)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Muted(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Muted)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetVolumePercent(&self, value: f32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetVolumePercent)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn VolumePercent(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).VolumePercent)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Media_Effects")] + pub fn AudioCaptureEffectsManager(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AudioCaptureEffectsManager)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] + pub fn GetAvailableMediaStreamProperties(&self, mediastreamtype: super::Capture::MediaStreamType) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAvailableMediaStreamProperties)(windows_core::Interface::as_raw(this), mediastreamtype, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] + pub fn GetMediaStreamProperties(&self, mediastreamtype: super::Capture::MediaStreamType) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMediaStreamProperties)(windows_core::Interface::as_raw(this), mediastreamtype, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] + pub fn SetMediaStreamPropertiesAsync(&self, mediastreamtype: super::Capture::MediaStreamType, mediaencodingproperties: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetMediaStreamPropertiesAsync)(windows_core::Interface::as_raw(this), mediastreamtype, mediaencodingproperties.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for AudioDeviceController { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AudioDeviceController { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AudioDeviceController { + const NAME: &'static str = "Windows.Media.Devices.AudioDeviceController"; +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct AutoFocusRange(pub i32); +impl AutoFocusRange { + pub const FullRange: Self = Self(0i32); + pub const Macro: Self = Self(1i32); + pub const Normal: Self = Self(2i32); +} +impl windows_core::TypeKind for AutoFocusRange { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for AutoFocusRange { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.AutoFocusRange;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct CameraOcclusionInfo(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(CameraOcclusionInfo, windows_core::IUnknown, windows_core::IInspectable); +impl CameraOcclusionInfo { + pub fn GetState(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetState)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IsOcclusionKindSupported(&self, occlusionkind: CameraOcclusionKind) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsOcclusionKindSupported)(windows_core::Interface::as_raw(this), occlusionkind, &mut result__).map(|| result__) + } + } + pub fn StateChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StateChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveStateChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveStateChanged)(windows_core::Interface::as_raw(this), token).ok() } + } +} +impl windows_core::RuntimeType for CameraOcclusionInfo { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for CameraOcclusionInfo { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for CameraOcclusionInfo { + const NAME: &'static str = "Windows.Media.Devices.CameraOcclusionInfo"; +} +unsafe impl Send for CameraOcclusionInfo {} +unsafe impl Sync for CameraOcclusionInfo {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct CameraOcclusionKind(pub i32); +impl CameraOcclusionKind { + pub const Lid: Self = Self(0i32); + pub const CameraHardware: Self = Self(1i32); +} +impl windows_core::TypeKind for CameraOcclusionKind { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for CameraOcclusionKind { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.CameraOcclusionKind;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct CameraOcclusionState(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(CameraOcclusionState, windows_core::IUnknown, windows_core::IInspectable); +impl CameraOcclusionState { + pub fn IsOccluded(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsOccluded)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsOcclusionKind(&self, occlusionkind: CameraOcclusionKind) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsOcclusionKind)(windows_core::Interface::as_raw(this), occlusionkind, &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for CameraOcclusionState { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for CameraOcclusionState { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for CameraOcclusionState { + const NAME: &'static str = "Windows.Media.Devices.CameraOcclusionState"; +} +unsafe impl Send for CameraOcclusionState {} +unsafe impl Sync for CameraOcclusionState {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct CameraOcclusionStateChangedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(CameraOcclusionStateChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl CameraOcclusionStateChangedEventArgs { + pub fn State(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).State)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for CameraOcclusionStateChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for CameraOcclusionStateChangedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for CameraOcclusionStateChangedEventArgs { + const NAME: &'static str = "Windows.Media.Devices.CameraOcclusionStateChangedEventArgs"; +} +unsafe impl Send for CameraOcclusionStateChangedEventArgs {} +unsafe impl Sync for CameraOcclusionStateChangedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct CaptureSceneMode(pub i32); +impl CaptureSceneMode { + pub const Auto: Self = Self(0i32); + pub const Manual: Self = Self(1i32); + pub const Macro: Self = Self(2i32); + pub const Portrait: Self = Self(3i32); + pub const Sport: Self = Self(4i32); + pub const Snow: Self = Self(5i32); + pub const Night: Self = Self(6i32); + pub const Beach: Self = Self(7i32); + pub const Sunset: Self = Self(8i32); + pub const Candlelight: Self = Self(9i32); + pub const Landscape: Self = Self(10i32); + pub const NightPortrait: Self = Self(11i32); + pub const Backlit: Self = Self(12i32); +} +impl windows_core::TypeKind for CaptureSceneMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for CaptureSceneMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.CaptureSceneMode;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct CaptureUse(pub i32); +impl CaptureUse { + pub const None: Self = Self(0i32); + pub const Photo: Self = Self(1i32); + pub const Video: Self = Self(2i32); +} +impl windows_core::TypeKind for CaptureUse { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for CaptureUse { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.CaptureUse;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct ColorTemperaturePreset(pub i32); +impl ColorTemperaturePreset { + pub const Auto: Self = Self(0i32); + pub const Manual: Self = Self(1i32); + pub const Cloudy: Self = Self(2i32); + pub const Daylight: Self = Self(3i32); + pub const Flash: Self = Self(4i32); + pub const Fluorescent: Self = Self(5i32); + pub const Tungsten: Self = Self(6i32); + pub const Candlelight: Self = Self(7i32); +} +impl windows_core::TypeKind for ColorTemperaturePreset { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for ColorTemperaturePreset { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.ColorTemperaturePreset;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct DigitalWindowBounds(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(DigitalWindowBounds, windows_core::IUnknown, windows_core::IInspectable); +impl DigitalWindowBounds { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn NormalizedOriginTop(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NormalizedOriginTop)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetNormalizedOriginTop(&self, value: f64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetNormalizedOriginTop)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn NormalizedOriginLeft(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NormalizedOriginLeft)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetNormalizedOriginLeft(&self, value: f64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetNormalizedOriginLeft)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Scale(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Scale)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetScale(&self, value: f64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetScale)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for DigitalWindowBounds { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for DigitalWindowBounds { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for DigitalWindowBounds { + const NAME: &'static str = "Windows.Media.Devices.DigitalWindowBounds"; +} +unsafe impl Send for DigitalWindowBounds {} +unsafe impl Sync for DigitalWindowBounds {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct DigitalWindowCapability(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(DigitalWindowCapability, windows_core::IUnknown, windows_core::IInspectable); +impl DigitalWindowCapability { + pub fn Width(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Width)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Height(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Height)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MinScaleValue(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinScaleValue)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaxScaleValue(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxScaleValue)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MinScaleValueWithoutUpsampling(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinScaleValueWithoutUpsampling)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn NormalizedFieldOfViewLimit(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NormalizedFieldOfViewLimit)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for DigitalWindowCapability { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for DigitalWindowCapability { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for DigitalWindowCapability { + const NAME: &'static str = "Windows.Media.Devices.DigitalWindowCapability"; +} +unsafe impl Send for DigitalWindowCapability {} +unsafe impl Sync for DigitalWindowCapability {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct DigitalWindowControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(DigitalWindowControl, windows_core::IUnknown, windows_core::IInspectable); +impl DigitalWindowControl { + pub fn IsSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SupportedModes(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::MaybeUninit::zeroed(); + (windows_core::Interface::vtable(this).SupportedModes)(windows_core::Interface::as_raw(this), windows_core::Array::::set_abi_len(core::mem::transmute(&mut result__)), result__.as_mut_ptr() as *mut _ as _).map(|| result__.assume_init()) + } + } + pub fn CurrentMode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CurrentMode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetBounds(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetBounds)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Configure(&self, digitalwindowmode: DigitalWindowMode) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Configure)(windows_core::Interface::as_raw(this), digitalwindowmode).ok() } + } + pub fn ConfigureWithBounds(&self, digitalwindowmode: DigitalWindowMode, digitalwindowbounds: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ConfigureWithBounds)(windows_core::Interface::as_raw(this), digitalwindowmode, digitalwindowbounds.param().abi()).ok() } + } + pub fn SupportedCapabilities(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedCapabilities)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetCapabilityForSize(&self, width: i32, height: i32) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCapabilityForSize)(windows_core::Interface::as_raw(this), width, height, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for DigitalWindowControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for DigitalWindowControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for DigitalWindowControl { + const NAME: &'static str = "Windows.Media.Devices.DigitalWindowControl"; +} +unsafe impl Send for DigitalWindowControl {} +unsafe impl Sync for DigitalWindowControl {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct DigitalWindowMode(pub i32); +impl DigitalWindowMode { + pub const Off: Self = Self(0i32); + pub const On: Self = Self(1i32); + pub const Auto: Self = Self(2i32); +} +impl windows_core::TypeKind for DigitalWindowMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for DigitalWindowMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.DigitalWindowMode;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ExposureCompensationControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(ExposureCompensationControl, windows_core::IUnknown, windows_core::IInspectable); +impl ExposureCompensationControl { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Min(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Min)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Max(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Max)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Step(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Step)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetValueAsync(&self, value: f32) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetValueAsync)(windows_core::Interface::as_raw(this), value, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for ExposureCompensationControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for ExposureCompensationControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for ExposureCompensationControl { + const NAME: &'static str = "Windows.Media.Devices.ExposureCompensationControl"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ExposureControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(ExposureControl, windows_core::IUnknown, windows_core::IInspectable); +impl ExposureControl { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Auto(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Auto)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAutoAsync(&self, value: bool) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetAutoAsync)(windows_core::Interface::as_raw(this), value, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Min(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Min)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Max(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Max)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Step(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Step)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetValueAsync(&self, shutterduration: super::super::Foundation::TimeSpan) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetValueAsync)(windows_core::Interface::as_raw(this), shutterduration, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for ExposureControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for ExposureControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for ExposureControl { + const NAME: &'static str = "Windows.Media.Devices.ExposureControl"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ExposurePriorityVideoControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(ExposurePriorityVideoControl, windows_core::IUnknown, windows_core::IInspectable); +impl ExposurePriorityVideoControl { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Enabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Enabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for ExposurePriorityVideoControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for ExposurePriorityVideoControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for ExposurePriorityVideoControl { + const NAME: &'static str = "Windows.Media.Devices.ExposurePriorityVideoControl"; +} +unsafe impl Send for ExposurePriorityVideoControl {} +unsafe impl Sync for ExposurePriorityVideoControl {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FlashControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(FlashControl, windows_core::IUnknown, windows_core::IInspectable); +impl FlashControl { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PowerSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PowerSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn RedEyeReductionSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RedEyeReductionSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Enabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Enabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Auto(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Auto)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAuto(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAuto)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn RedEyeReduction(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RedEyeReduction)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetRedEyeReduction(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetRedEyeReduction)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn PowerPercent(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PowerPercent)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetPowerPercent(&self, value: f32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPowerPercent)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn AssistantLightSupported(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AssistantLightSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AssistantLightEnabled(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AssistantLightEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAssistantLightEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAssistantLightEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for FlashControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for FlashControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for FlashControl { + const NAME: &'static str = "Windows.Media.Devices.FlashControl"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FocusControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(FocusControl, windows_core::IUnknown, windows_core::IInspectable); +impl FocusControl { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SupportedPresets(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedPresets)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Preset(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Preset)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetPresetAsync(&self, preset: FocusPreset) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetPresetAsync)(windows_core::Interface::as_raw(this), preset, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetPresetWithCompletionOptionAsync(&self, preset: FocusPreset, completebeforefocus: bool) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetPresetWithCompletionOptionAsync)(windows_core::Interface::as_raw(this), preset, completebeforefocus, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Min(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Min)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Max(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Max)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Step(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Step)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetValueAsync(&self, focus: u32) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetValueAsync)(windows_core::Interface::as_raw(this), focus, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn FocusAsync(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FocusAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn FocusChangedSupported(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FocusChangedSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn WaitForFocusSupported(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WaitForFocusSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SupportedFocusModes(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedFocusModes)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SupportedFocusDistances(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedFocusDistances)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SupportedFocusRanges(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedFocusRanges)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Mode(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Mode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn FocusState(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FocusState)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn UnlockAsync(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UnlockAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn LockAsync(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LockAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Configure(&self, settings: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Configure)(windows_core::Interface::as_raw(this), settings.param().abi()).ok() } + } +} +impl windows_core::RuntimeType for FocusControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for FocusControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for FocusControl { + const NAME: &'static str = "Windows.Media.Devices.FocusControl"; +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct FocusMode(pub i32); +impl FocusMode { + pub const Auto: Self = Self(0i32); + pub const Single: Self = Self(1i32); + pub const Continuous: Self = Self(2i32); + pub const Manual: Self = Self(3i32); +} +impl windows_core::TypeKind for FocusMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for FocusMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.FocusMode;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct FocusPreset(pub i32); +impl FocusPreset { + pub const Auto: Self = Self(0i32); + pub const Manual: Self = Self(1i32); + pub const AutoMacro: Self = Self(2i32); + pub const AutoNormal: Self = Self(3i32); + pub const AutoInfinity: Self = Self(4i32); + pub const AutoHyperfocal: Self = Self(5i32); +} +impl windows_core::TypeKind for FocusPreset { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for FocusPreset { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.FocusPreset;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FocusSettings(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(FocusSettings, windows_core::IUnknown, windows_core::IInspectable); +impl FocusSettings { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn Mode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Mode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetMode(&self, value: FocusMode) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMode)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn AutoFocusRange(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AutoFocusRange)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAutoFocusRange(&self, value: AutoFocusRange) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAutoFocusRange)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Value(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetValue(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetValue)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn Distance(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Distance)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetDistance(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDistance)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn WaitForFocus(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WaitForFocus)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetWaitForFocus(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetWaitForFocus)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn DisableDriverFallback(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisableDriverFallback)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetDisableDriverFallback(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDisableDriverFallback)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for FocusSettings { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for FocusSettings { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for FocusSettings { + const NAME: &'static str = "Windows.Media.Devices.FocusSettings"; +} +unsafe impl Send for FocusSettings {} +unsafe impl Sync for FocusSettings {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct HdrVideoControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(HdrVideoControl, windows_core::IUnknown, windows_core::IInspectable); +impl HdrVideoControl { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SupportedModes(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedModes)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Mode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Mode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetMode(&self, value: HdrVideoMode) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMode)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for HdrVideoControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for HdrVideoControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for HdrVideoControl { + const NAME: &'static str = "Windows.Media.Devices.HdrVideoControl"; +} +unsafe impl Send for HdrVideoControl {} +unsafe impl Sync for HdrVideoControl {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct HdrVideoMode(pub i32); +impl HdrVideoMode { + pub const Off: Self = Self(0i32); + pub const On: Self = Self(1i32); + pub const Auto: Self = Self(2i32); +} +impl windows_core::TypeKind for HdrVideoMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for HdrVideoMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.HdrVideoMode;i4)"); +} +windows_core::imp::define_interface!(IAdvancedPhotoCaptureSettings, IAdvancedPhotoCaptureSettings_Vtbl, 0x08f3863a_0018_445b_93d2_646d1c5ed05c); +impl windows_core::RuntimeType for IAdvancedPhotoCaptureSettings { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdvancedPhotoCaptureSettings { + const NAME: &'static str = "Windows.Media.Devices.IAdvancedPhotoCaptureSettings"; +} +pub trait IAdvancedPhotoCaptureSettings_Impl: windows_core::IUnknownImpl { + fn Mode(&self) -> windows_core::Result; + fn SetMode(&self, value: AdvancedPhotoMode) -> windows_core::Result<()>; +} +impl IAdvancedPhotoCaptureSettings_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Mode(this: *mut core::ffi::c_void, result__: *mut AdvancedPhotoMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedPhotoCaptureSettings_Impl::Mode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMode(this: *mut core::ffi::c_void, value: AdvancedPhotoMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdvancedPhotoCaptureSettings_Impl::SetMode(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Mode: Mode::, + SetMode: SetMode::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdvancedPhotoCaptureSettings_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Mode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut AdvancedPhotoMode) -> windows_core::HRESULT, + pub SetMode: unsafe extern "system" fn(*mut core::ffi::c_void, AdvancedPhotoMode) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdvancedPhotoControl, IAdvancedPhotoControl_Vtbl, 0xc5b15486_9001_4682_9309_68eae0080eec); +impl windows_core::RuntimeType for IAdvancedPhotoControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdvancedPhotoControl { + const NAME: &'static str = "Windows.Media.Devices.IAdvancedPhotoControl"; +} +pub trait IAdvancedPhotoControl_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn SupportedModes(&self) -> windows_core::Result>; + fn Mode(&self) -> windows_core::Result; + fn Configure(&self, settings: windows_core::Ref<'_, AdvancedPhotoCaptureSettings>) -> windows_core::Result<()>; +} +impl IAdvancedPhotoControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedPhotoControl_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedModes(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedPhotoControl_Impl::SupportedModes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Mode(this: *mut core::ffi::c_void, result__: *mut AdvancedPhotoMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedPhotoControl_Impl::Mode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Configure(this: *mut core::ffi::c_void, settings: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdvancedPhotoControl_Impl::Configure(this, core::mem::transmute_copy(&settings)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + SupportedModes: SupportedModes::, + Mode: Mode::, + Configure: Configure::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdvancedPhotoControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SupportedModes: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Mode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut AdvancedPhotoMode) -> windows_core::HRESULT, + pub Configure: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdvancedVideoCaptureDeviceController, IAdvancedVideoCaptureDeviceController_Vtbl, 0xde6ff4d3_2b96_4583_80ab_b5b01dc6a8d7); +impl windows_core::RuntimeType for IAdvancedVideoCaptureDeviceController { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdvancedVideoCaptureDeviceController { + const NAME: &'static str = "Windows.Media.Devices.IAdvancedVideoCaptureDeviceController"; +} +pub trait IAdvancedVideoCaptureDeviceController_Impl: windows_core::IUnknownImpl { + fn SetDeviceProperty(&self, propertyId: &windows_core::HSTRING, propertyValue: windows_core::Ref<'_, windows_core::IInspectable>) -> windows_core::Result<()>; + fn GetDeviceProperty(&self, propertyId: &windows_core::HSTRING) -> windows_core::Result; +} +impl IAdvancedVideoCaptureDeviceController_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetDeviceProperty(this: *mut core::ffi::c_void, propertyid: *mut core::ffi::c_void, propertyvalue: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdvancedVideoCaptureDeviceController_Impl::SetDeviceProperty(this, core::mem::transmute(&propertyid), core::mem::transmute_copy(&propertyvalue)).into() + } + } + unsafe extern "system" fn GetDeviceProperty(this: *mut core::ffi::c_void, propertyid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController_Impl::GetDeviceProperty(this, core::mem::transmute(&propertyid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetDeviceProperty: SetDeviceProperty::, + GetDeviceProperty: GetDeviceProperty::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdvancedVideoCaptureDeviceController_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SetDeviceProperty: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetDeviceProperty: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdvancedVideoCaptureDeviceController10, IAdvancedVideoCaptureDeviceController10_Vtbl, 0xc621b82d_d6f0_5c1b_a388_a6e938407146); +impl windows_core::RuntimeType for IAdvancedVideoCaptureDeviceController10 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdvancedVideoCaptureDeviceController10 { + const NAME: &'static str = "Windows.Media.Devices.IAdvancedVideoCaptureDeviceController10"; +} +pub trait IAdvancedVideoCaptureDeviceController10_Impl: windows_core::IUnknownImpl { + fn CameraOcclusionInfo(&self) -> windows_core::Result; +} +impl IAdvancedVideoCaptureDeviceController10_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CameraOcclusionInfo(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController10_Impl::CameraOcclusionInfo(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CameraOcclusionInfo: CameraOcclusionInfo::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdvancedVideoCaptureDeviceController10_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub CameraOcclusionInfo: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdvancedVideoCaptureDeviceController11, IAdvancedVideoCaptureDeviceController11_Vtbl, 0xd5b65ae2_3772_580c_a630_e75de9106904); +impl windows_core::RuntimeType for IAdvancedVideoCaptureDeviceController11 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Capture")] +impl windows_core::RuntimeName for IAdvancedVideoCaptureDeviceController11 { + const NAME: &'static str = "Windows.Media.Devices.IAdvancedVideoCaptureDeviceController11"; +} +#[cfg(feature = "Media_Capture")] +pub trait IAdvancedVideoCaptureDeviceController11_Impl: windows_core::IUnknownImpl { + fn TryAcquireExclusiveControl(&self, deviceId: &windows_core::HSTRING, mode: super::Capture::MediaCaptureDeviceExclusiveControlReleaseMode) -> windows_core::Result; +} +#[cfg(feature = "Media_Capture")] +impl IAdvancedVideoCaptureDeviceController11_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TryAcquireExclusiveControl(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void, mode: super::Capture::MediaCaptureDeviceExclusiveControlReleaseMode, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController11_Impl::TryAcquireExclusiveControl(this, core::mem::transmute(&deviceid), mode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + TryAcquireExclusiveControl: TryAcquireExclusiveControl::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdvancedVideoCaptureDeviceController11_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_Capture")] + pub TryAcquireExclusiveControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, super::Capture::MediaCaptureDeviceExclusiveControlReleaseMode, *mut bool) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Capture"))] + TryAcquireExclusiveControl: usize, +} +windows_core::imp::define_interface!(IAdvancedVideoCaptureDeviceController2, IAdvancedVideoCaptureDeviceController2_Vtbl, 0x8bb94f8f_f11a_43db_b402_11930b80ae56); +impl windows_core::RuntimeType for IAdvancedVideoCaptureDeviceController2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdvancedVideoCaptureDeviceController2 { + const NAME: &'static str = "Windows.Media.Devices.IAdvancedVideoCaptureDeviceController2"; +} +pub trait IAdvancedVideoCaptureDeviceController2_Impl: windows_core::IUnknownImpl { + fn LowLagPhotoSequence(&self) -> windows_core::Result; + fn LowLagPhoto(&self) -> windows_core::Result; + fn SceneModeControl(&self) -> windows_core::Result; + fn TorchControl(&self) -> windows_core::Result; + fn FlashControl(&self) -> windows_core::Result; + fn WhiteBalanceControl(&self) -> windows_core::Result; + fn ExposureControl(&self) -> windows_core::Result; + fn FocusControl(&self) -> windows_core::Result; + fn ExposureCompensationControl(&self) -> windows_core::Result; + fn IsoSpeedControl(&self) -> windows_core::Result; + fn RegionsOfInterestControl(&self) -> windows_core::Result; + fn PrimaryUse(&self) -> windows_core::Result; + fn SetPrimaryUse(&self, value: CaptureUse) -> windows_core::Result<()>; +} +impl IAdvancedVideoCaptureDeviceController2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn LowLagPhotoSequence(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController2_Impl::LowLagPhotoSequence(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn LowLagPhoto(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController2_Impl::LowLagPhoto(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SceneModeControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController2_Impl::SceneModeControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TorchControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController2_Impl::TorchControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FlashControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController2_Impl::FlashControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WhiteBalanceControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController2_Impl::WhiteBalanceControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ExposureControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController2_Impl::ExposureControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FocusControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController2_Impl::FocusControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ExposureCompensationControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController2_Impl::ExposureCompensationControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsoSpeedControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController2_Impl::IsoSpeedControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RegionsOfInterestControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController2_Impl::RegionsOfInterestControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PrimaryUse(this: *mut core::ffi::c_void, result__: *mut CaptureUse) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController2_Impl::PrimaryUse(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPrimaryUse(this: *mut core::ffi::c_void, value: CaptureUse) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdvancedVideoCaptureDeviceController2_Impl::SetPrimaryUse(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + LowLagPhotoSequence: LowLagPhotoSequence::, + LowLagPhoto: LowLagPhoto::, + SceneModeControl: SceneModeControl::, + TorchControl: TorchControl::, + FlashControl: FlashControl::, + WhiteBalanceControl: WhiteBalanceControl::, + ExposureControl: ExposureControl::, + FocusControl: FocusControl::, + ExposureCompensationControl: ExposureCompensationControl::, + IsoSpeedControl: IsoSpeedControl::, + RegionsOfInterestControl: RegionsOfInterestControl::, + PrimaryUse: PrimaryUse::, + SetPrimaryUse: SetPrimaryUse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdvancedVideoCaptureDeviceController2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub LowLagPhotoSequence: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub LowLagPhoto: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SceneModeControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub TorchControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub FlashControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub WhiteBalanceControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ExposureControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub FocusControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ExposureCompensationControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub IsoSpeedControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub RegionsOfInterestControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub PrimaryUse: unsafe extern "system" fn(*mut core::ffi::c_void, *mut CaptureUse) -> windows_core::HRESULT, + pub SetPrimaryUse: unsafe extern "system" fn(*mut core::ffi::c_void, CaptureUse) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdvancedVideoCaptureDeviceController3, IAdvancedVideoCaptureDeviceController3_Vtbl, 0xa98b8f34_ee0d_470c_b9f0_4229c4bbd089); +impl windows_core::RuntimeType for IAdvancedVideoCaptureDeviceController3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Devices_Core")] +impl windows_core::RuntimeName for IAdvancedVideoCaptureDeviceController3 { + const NAME: &'static str = "Windows.Media.Devices.IAdvancedVideoCaptureDeviceController3"; +} +#[cfg(feature = "Media_Devices_Core")] +pub trait IAdvancedVideoCaptureDeviceController3_Impl: windows_core::IUnknownImpl { + fn VariablePhotoSequenceController(&self) -> windows_core::Result; + fn PhotoConfirmationControl(&self) -> windows_core::Result; + fn ZoomControl(&self) -> windows_core::Result; +} +#[cfg(feature = "Media_Devices_Core")] +impl IAdvancedVideoCaptureDeviceController3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn VariablePhotoSequenceController(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController3_Impl::VariablePhotoSequenceController(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PhotoConfirmationControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController3_Impl::PhotoConfirmationControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ZoomControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController3_Impl::ZoomControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + VariablePhotoSequenceController: VariablePhotoSequenceController::, + PhotoConfirmationControl: PhotoConfirmationControl::, + ZoomControl: ZoomControl::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdvancedVideoCaptureDeviceController3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_Devices_Core")] + pub VariablePhotoSequenceController: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Devices_Core"))] + VariablePhotoSequenceController: usize, + pub PhotoConfirmationControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ZoomControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdvancedVideoCaptureDeviceController4, IAdvancedVideoCaptureDeviceController4_Vtbl, 0xea9fbfaf_d371_41c3_9a17_824a87ebdfd2); +impl windows_core::RuntimeType for IAdvancedVideoCaptureDeviceController4 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdvancedVideoCaptureDeviceController4 { + const NAME: &'static str = "Windows.Media.Devices.IAdvancedVideoCaptureDeviceController4"; +} +pub trait IAdvancedVideoCaptureDeviceController4_Impl: windows_core::IUnknownImpl { + fn ExposurePriorityVideoControl(&self) -> windows_core::Result; + fn DesiredOptimization(&self) -> windows_core::Result; + fn SetDesiredOptimization(&self, value: MediaCaptureOptimization) -> windows_core::Result<()>; + fn HdrVideoControl(&self) -> windows_core::Result; + fn OpticalImageStabilizationControl(&self) -> windows_core::Result; + fn AdvancedPhotoControl(&self) -> windows_core::Result; +} +impl IAdvancedVideoCaptureDeviceController4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ExposurePriorityVideoControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController4_Impl::ExposurePriorityVideoControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DesiredOptimization(this: *mut core::ffi::c_void, result__: *mut MediaCaptureOptimization) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController4_Impl::DesiredOptimization(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDesiredOptimization(this: *mut core::ffi::c_void, value: MediaCaptureOptimization) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdvancedVideoCaptureDeviceController4_Impl::SetDesiredOptimization(this, value).into() + } + } + unsafe extern "system" fn HdrVideoControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController4_Impl::HdrVideoControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OpticalImageStabilizationControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController4_Impl::OpticalImageStabilizationControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AdvancedPhotoControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController4_Impl::AdvancedPhotoControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ExposurePriorityVideoControl: ExposurePriorityVideoControl::, + DesiredOptimization: DesiredOptimization::, + SetDesiredOptimization: SetDesiredOptimization::, + HdrVideoControl: HdrVideoControl::, + OpticalImageStabilizationControl: OpticalImageStabilizationControl::, + AdvancedPhotoControl: AdvancedPhotoControl::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdvancedVideoCaptureDeviceController4_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ExposurePriorityVideoControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub DesiredOptimization: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaCaptureOptimization) -> windows_core::HRESULT, + pub SetDesiredOptimization: unsafe extern "system" fn(*mut core::ffi::c_void, MediaCaptureOptimization) -> windows_core::HRESULT, + pub HdrVideoControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub OpticalImageStabilizationControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub AdvancedPhotoControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdvancedVideoCaptureDeviceController5, IAdvancedVideoCaptureDeviceController5_Vtbl, 0x33512b17_b9cb_4a23_b875_f9eaab535492); +impl windows_core::RuntimeType for IAdvancedVideoCaptureDeviceController5 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdvancedVideoCaptureDeviceController5 { + const NAME: &'static str = "Windows.Media.Devices.IAdvancedVideoCaptureDeviceController5"; +} +pub trait IAdvancedVideoCaptureDeviceController5_Impl: windows_core::IUnknownImpl { + fn Id(&self) -> windows_core::Result; + fn GetDevicePropertyById(&self, propertyId: &windows_core::HSTRING, maxPropertyValueSize: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result; + fn SetDevicePropertyById(&self, propertyId: &windows_core::HSTRING, propertyValue: windows_core::Ref<'_, windows_core::IInspectable>) -> windows_core::Result; + fn GetDevicePropertyByExtendedId(&self, extendedPropertyId: &[u8], maxPropertyValueSize: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result; + fn SetDevicePropertyByExtendedId(&self, extendedPropertyId: &[u8], propertyValue: &[u8]) -> windows_core::Result; +} +impl IAdvancedVideoCaptureDeviceController5_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Id(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController5_Impl::Id(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDevicePropertyById(this: *mut core::ffi::c_void, propertyid: *mut core::ffi::c_void, maxpropertyvaluesize: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController5_Impl::GetDevicePropertyById(this, core::mem::transmute(&propertyid), core::mem::transmute_copy(&maxpropertyvaluesize)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDevicePropertyById(this: *mut core::ffi::c_void, propertyid: *mut core::ffi::c_void, propertyvalue: *mut core::ffi::c_void, result__: *mut VideoDeviceControllerSetDevicePropertyStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController5_Impl::SetDevicePropertyById(this, core::mem::transmute(&propertyid), core::mem::transmute_copy(&propertyvalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDevicePropertyByExtendedId(this: *mut core::ffi::c_void, extendedpropertyid_array_size: u32, extendedpropertyid: *const u8, maxpropertyvaluesize: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController5_Impl::GetDevicePropertyByExtendedId(this, core::slice::from_raw_parts(core::mem::transmute_copy(&extendedpropertyid), extendedpropertyid_array_size as usize), core::mem::transmute_copy(&maxpropertyvaluesize)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDevicePropertyByExtendedId(this: *mut core::ffi::c_void, extendedpropertyid_array_size: u32, extendedpropertyid: *const u8, propertyvalue_array_size: u32, propertyvalue: *const u8, result__: *mut VideoDeviceControllerSetDevicePropertyStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController5_Impl::SetDevicePropertyByExtendedId(this, core::slice::from_raw_parts(core::mem::transmute_copy(&extendedpropertyid), extendedpropertyid_array_size as usize), core::slice::from_raw_parts(core::mem::transmute_copy(&propertyvalue), propertyvalue_array_size as usize)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Id: Id::, + GetDevicePropertyById: GetDevicePropertyById::, + SetDevicePropertyById: SetDevicePropertyById::, + GetDevicePropertyByExtendedId: GetDevicePropertyByExtendedId::, + SetDevicePropertyByExtendedId: SetDevicePropertyByExtendedId::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdvancedVideoCaptureDeviceController5_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Id: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetDevicePropertyById: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetDevicePropertyById: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut VideoDeviceControllerSetDevicePropertyStatus) -> windows_core::HRESULT, + pub GetDevicePropertyByExtendedId: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const u8, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetDevicePropertyByExtendedId: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const u8, u32, *const u8, *mut VideoDeviceControllerSetDevicePropertyStatus) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdvancedVideoCaptureDeviceController6, IAdvancedVideoCaptureDeviceController6_Vtbl, 0xb6563a53_68a1_44b7_9f89_b5fa97ac0cbe); +impl windows_core::RuntimeType for IAdvancedVideoCaptureDeviceController6 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdvancedVideoCaptureDeviceController6 { + const NAME: &'static str = "Windows.Media.Devices.IAdvancedVideoCaptureDeviceController6"; +} +pub trait IAdvancedVideoCaptureDeviceController6_Impl: windows_core::IUnknownImpl { + fn VideoTemporalDenoisingControl(&self) -> windows_core::Result; +} +impl IAdvancedVideoCaptureDeviceController6_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn VideoTemporalDenoisingControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController6_Impl::VideoTemporalDenoisingControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + VideoTemporalDenoisingControl: VideoTemporalDenoisingControl::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdvancedVideoCaptureDeviceController6_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub VideoTemporalDenoisingControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdvancedVideoCaptureDeviceController7, IAdvancedVideoCaptureDeviceController7_Vtbl, 0x8d2927f0_a054_50e7_b7df_7c04234d10f0); +impl windows_core::RuntimeType for IAdvancedVideoCaptureDeviceController7 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdvancedVideoCaptureDeviceController7 { + const NAME: &'static str = "Windows.Media.Devices.IAdvancedVideoCaptureDeviceController7"; +} +pub trait IAdvancedVideoCaptureDeviceController7_Impl: windows_core::IUnknownImpl { + fn InfraredTorchControl(&self) -> windows_core::Result; +} +impl IAdvancedVideoCaptureDeviceController7_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn InfraredTorchControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController7_Impl::InfraredTorchControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + InfraredTorchControl: InfraredTorchControl::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdvancedVideoCaptureDeviceController7_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub InfraredTorchControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdvancedVideoCaptureDeviceController8, IAdvancedVideoCaptureDeviceController8_Vtbl, 0xd843f010_e7fb_595b_9a78_0e54c4532b43); +impl windows_core::RuntimeType for IAdvancedVideoCaptureDeviceController8 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdvancedVideoCaptureDeviceController8 { + const NAME: &'static str = "Windows.Media.Devices.IAdvancedVideoCaptureDeviceController8"; +} +pub trait IAdvancedVideoCaptureDeviceController8_Impl: windows_core::IUnknownImpl { + fn PanelBasedOptimizationControl(&self) -> windows_core::Result; +} +impl IAdvancedVideoCaptureDeviceController8_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn PanelBasedOptimizationControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController8_Impl::PanelBasedOptimizationControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + PanelBasedOptimizationControl: PanelBasedOptimizationControl::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdvancedVideoCaptureDeviceController8_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub PanelBasedOptimizationControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdvancedVideoCaptureDeviceController9, IAdvancedVideoCaptureDeviceController9_Vtbl, 0x8bdca95d_0255_51bc_a10d_5a169ec1625a); +impl windows_core::RuntimeType for IAdvancedVideoCaptureDeviceController9 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdvancedVideoCaptureDeviceController9 { + const NAME: &'static str = "Windows.Media.Devices.IAdvancedVideoCaptureDeviceController9"; +} +pub trait IAdvancedVideoCaptureDeviceController9_Impl: windows_core::IUnknownImpl { + fn DigitalWindowControl(&self) -> windows_core::Result; +} +impl IAdvancedVideoCaptureDeviceController9_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DigitalWindowControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdvancedVideoCaptureDeviceController9_Impl::DigitalWindowControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DigitalWindowControl: DigitalWindowControl::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdvancedVideoCaptureDeviceController9_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub DigitalWindowControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAudioDeviceController, IAudioDeviceController_Vtbl, 0xedd4a388_79c7_4f7c_90e8_ef934b21580a); +impl windows_core::RuntimeType for IAudioDeviceController { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] +impl windows_core::RuntimeName for IAudioDeviceController { + const NAME: &'static str = "Windows.Media.Devices.IAudioDeviceController"; +} +#[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] +pub trait IAudioDeviceController_Impl: IMediaDeviceController_Impl { + fn SetMuted(&self, value: bool) -> windows_core::Result<()>; + fn Muted(&self) -> windows_core::Result; + fn SetVolumePercent(&self, value: f32) -> windows_core::Result<()>; + fn VolumePercent(&self) -> windows_core::Result; +} +#[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] +impl IAudioDeviceController_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetMuted(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAudioDeviceController_Impl::SetMuted(this, value).into() + } + } + unsafe extern "system" fn Muted(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioDeviceController_Impl::Muted(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetVolumePercent(this: *mut core::ffi::c_void, value: f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAudioDeviceController_Impl::SetVolumePercent(this, value).into() + } + } + unsafe extern "system" fn VolumePercent(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioDeviceController_Impl::VolumePercent(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetMuted: SetMuted::, + Muted: Muted::, + SetVolumePercent: SetVolumePercent::, + VolumePercent: VolumePercent::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAudioDeviceController_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SetMuted: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub Muted: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetVolumePercent: unsafe extern "system" fn(*mut core::ffi::c_void, f32) -> windows_core::HRESULT, + pub VolumePercent: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAudioDeviceController2, IAudioDeviceController2_Vtbl, 0x85326599_4c24_48b0_81dd_0c5cc79ddf05); +impl windows_core::RuntimeType for IAudioDeviceController2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Effects")] +impl windows_core::RuntimeName for IAudioDeviceController2 { + const NAME: &'static str = "Windows.Media.Devices.IAudioDeviceController2"; +} +#[cfg(feature = "Media_Effects")] +pub trait IAudioDeviceController2_Impl: windows_core::IUnknownImpl { + fn AudioCaptureEffectsManager(&self) -> windows_core::Result; +} +#[cfg(feature = "Media_Effects")] +impl IAudioDeviceController2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AudioCaptureEffectsManager(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioDeviceController2_Impl::AudioCaptureEffectsManager(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AudioCaptureEffectsManager: AudioCaptureEffectsManager::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAudioDeviceController2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_Effects")] + pub AudioCaptureEffectsManager: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Effects"))] + AudioCaptureEffectsManager: usize, +} +windows_core::imp::define_interface!(ICameraOcclusionInfo, ICameraOcclusionInfo_Vtbl, 0xaf6c4ad0_a84d_5db6_be58_a5da21cfe011); +impl windows_core::RuntimeType for ICameraOcclusionInfo { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ICameraOcclusionInfo { + const NAME: &'static str = "Windows.Media.Devices.ICameraOcclusionInfo"; +} +pub trait ICameraOcclusionInfo_Impl: windows_core::IUnknownImpl { + fn GetState(&self) -> windows_core::Result; + fn IsOcclusionKindSupported(&self, occlusionKind: CameraOcclusionKind) -> windows_core::Result; + fn StateChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveStateChanged(&self, token: i64) -> windows_core::Result<()>; +} +impl ICameraOcclusionInfo_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetState(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraOcclusionInfo_Impl::GetState(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsOcclusionKindSupported(this: *mut core::ffi::c_void, occlusionkind: CameraOcclusionKind, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraOcclusionInfo_Impl::IsOcclusionKindSupported(this, occlusionkind) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StateChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraOcclusionInfo_Impl::StateChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveStateChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICameraOcclusionInfo_Impl::RemoveStateChanged(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetState: GetState::, + IsOcclusionKindSupported: IsOcclusionKindSupported::, + StateChanged: StateChanged::, + RemoveStateChanged: RemoveStateChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ICameraOcclusionInfo_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub GetState: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub IsOcclusionKindSupported: unsafe extern "system" fn(*mut core::ffi::c_void, CameraOcclusionKind, *mut bool) -> windows_core::HRESULT, + pub StateChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveStateChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ICameraOcclusionState, ICameraOcclusionState_Vtbl, 0x430adeb8_6842_5e55_9bde_04b4ef3a8a57); +impl windows_core::RuntimeType for ICameraOcclusionState { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ICameraOcclusionState { + const NAME: &'static str = "Windows.Media.Devices.ICameraOcclusionState"; +} +pub trait ICameraOcclusionState_Impl: windows_core::IUnknownImpl { + fn IsOccluded(&self) -> windows_core::Result; + fn IsOcclusionKind(&self, occlusionKind: CameraOcclusionKind) -> windows_core::Result; +} +impl ICameraOcclusionState_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsOccluded(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraOcclusionState_Impl::IsOccluded(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsOcclusionKind(this: *mut core::ffi::c_void, occlusionkind: CameraOcclusionKind, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraOcclusionState_Impl::IsOcclusionKind(this, occlusionkind) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsOccluded: IsOccluded::, + IsOcclusionKind: IsOcclusionKind::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ICameraOcclusionState_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsOccluded: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub IsOcclusionKind: unsafe extern "system" fn(*mut core::ffi::c_void, CameraOcclusionKind, *mut bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ICameraOcclusionStateChangedEventArgs, ICameraOcclusionStateChangedEventArgs_Vtbl, 0x8512d848_c0de_57ca_a1ca_fb2c3d23df55); +impl windows_core::RuntimeType for ICameraOcclusionStateChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ICameraOcclusionStateChangedEventArgs { + const NAME: &'static str = "Windows.Media.Devices.ICameraOcclusionStateChangedEventArgs"; +} +pub trait ICameraOcclusionStateChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn State(&self) -> windows_core::Result; +} +impl ICameraOcclusionStateChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn State(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraOcclusionStateChangedEventArgs_Impl::State(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), State: State:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ICameraOcclusionStateChangedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub State: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IDigitalWindowBounds, IDigitalWindowBounds_Vtbl, 0xdd4f21dd_d173_5c6b_8c25_bdd26d5122b1); +impl windows_core::RuntimeType for IDigitalWindowBounds { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IDigitalWindowBounds { + const NAME: &'static str = "Windows.Media.Devices.IDigitalWindowBounds"; +} +pub trait IDigitalWindowBounds_Impl: windows_core::IUnknownImpl { + fn NormalizedOriginTop(&self) -> windows_core::Result; + fn SetNormalizedOriginTop(&self, value: f64) -> windows_core::Result<()>; + fn NormalizedOriginLeft(&self) -> windows_core::Result; + fn SetNormalizedOriginLeft(&self, value: f64) -> windows_core::Result<()>; + fn Scale(&self) -> windows_core::Result; + fn SetScale(&self, value: f64) -> windows_core::Result<()>; +} +impl IDigitalWindowBounds_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn NormalizedOriginTop(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDigitalWindowBounds_Impl::NormalizedOriginTop(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetNormalizedOriginTop(this: *mut core::ffi::c_void, value: f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDigitalWindowBounds_Impl::SetNormalizedOriginTop(this, value).into() + } + } + unsafe extern "system" fn NormalizedOriginLeft(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDigitalWindowBounds_Impl::NormalizedOriginLeft(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetNormalizedOriginLeft(this: *mut core::ffi::c_void, value: f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDigitalWindowBounds_Impl::SetNormalizedOriginLeft(this, value).into() + } + } + unsafe extern "system" fn Scale(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDigitalWindowBounds_Impl::Scale(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetScale(this: *mut core::ffi::c_void, value: f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDigitalWindowBounds_Impl::SetScale(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + NormalizedOriginTop: NormalizedOriginTop::, + SetNormalizedOriginTop: SetNormalizedOriginTop::, + NormalizedOriginLeft: NormalizedOriginLeft::, + SetNormalizedOriginLeft: SetNormalizedOriginLeft::, + Scale: Scale::, + SetScale: SetScale::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IDigitalWindowBounds_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub NormalizedOriginTop: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, + pub SetNormalizedOriginTop: unsafe extern "system" fn(*mut core::ffi::c_void, f64) -> windows_core::HRESULT, + pub NormalizedOriginLeft: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, + pub SetNormalizedOriginLeft: unsafe extern "system" fn(*mut core::ffi::c_void, f64) -> windows_core::HRESULT, + pub Scale: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, + pub SetScale: unsafe extern "system" fn(*mut core::ffi::c_void, f64) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IDigitalWindowCapability, IDigitalWindowCapability_Vtbl, 0xd78bad2c_f721_5244_a196_b56ccbec606c); +impl windows_core::RuntimeType for IDigitalWindowCapability { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IDigitalWindowCapability { + const NAME: &'static str = "Windows.Media.Devices.IDigitalWindowCapability"; +} +pub trait IDigitalWindowCapability_Impl: windows_core::IUnknownImpl { + fn Width(&self) -> windows_core::Result; + fn Height(&self) -> windows_core::Result; + fn MinScaleValue(&self) -> windows_core::Result; + fn MaxScaleValue(&self) -> windows_core::Result; + fn MinScaleValueWithoutUpsampling(&self) -> windows_core::Result; + fn NormalizedFieldOfViewLimit(&self) -> windows_core::Result; +} +impl IDigitalWindowCapability_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Width(this: *mut core::ffi::c_void, result__: *mut i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDigitalWindowCapability_Impl::Width(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Height(this: *mut core::ffi::c_void, result__: *mut i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDigitalWindowCapability_Impl::Height(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MinScaleValue(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDigitalWindowCapability_Impl::MinScaleValue(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxScaleValue(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDigitalWindowCapability_Impl::MaxScaleValue(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MinScaleValueWithoutUpsampling(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDigitalWindowCapability_Impl::MinScaleValueWithoutUpsampling(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NormalizedFieldOfViewLimit(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::Rect) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDigitalWindowCapability_Impl::NormalizedFieldOfViewLimit(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Width: Width::, + Height: Height::, + MinScaleValue: MinScaleValue::, + MaxScaleValue: MaxScaleValue::, + MinScaleValueWithoutUpsampling: MinScaleValueWithoutUpsampling::, + NormalizedFieldOfViewLimit: NormalizedFieldOfViewLimit::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IDigitalWindowCapability_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Width: unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, + pub Height: unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, + pub MinScaleValue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, + pub MaxScaleValue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, + pub MinScaleValueWithoutUpsampling: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, + pub NormalizedFieldOfViewLimit: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::Rect) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IDigitalWindowControl, IDigitalWindowControl_Vtbl, 0x23b69eff_65d2_53ea_8780_de582b48b544); +impl windows_core::RuntimeType for IDigitalWindowControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IDigitalWindowControl { + const NAME: &'static str = "Windows.Media.Devices.IDigitalWindowControl"; +} +pub trait IDigitalWindowControl_Impl: windows_core::IUnknownImpl { + fn IsSupported(&self) -> windows_core::Result; + fn SupportedModes(&self) -> windows_core::Result>; + fn CurrentMode(&self) -> windows_core::Result; + fn GetBounds(&self) -> windows_core::Result; + fn Configure(&self, digitalWindowMode: DigitalWindowMode) -> windows_core::Result<()>; + fn ConfigureWithBounds(&self, digitalWindowMode: DigitalWindowMode, digitalWindowBounds: windows_core::Ref<'_, DigitalWindowBounds>) -> windows_core::Result<()>; + fn SupportedCapabilities(&self) -> windows_core::Result>; + fn GetCapabilityForSize(&self, width: i32, height: i32) -> windows_core::Result; +} +impl IDigitalWindowControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDigitalWindowControl_Impl::IsSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedModes(this: *mut core::ffi::c_void, result_size__: *mut u32, result__: *mut *mut DigitalWindowMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDigitalWindowControl_Impl::SupportedModes(this) { + Ok(ok__) => { + let (ok_data__, ok_data_len__) = ok__.into_abi(); + result__.write(core::mem::transmute(ok_data__)); + result_size__.write(ok_data_len__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CurrentMode(this: *mut core::ffi::c_void, result__: *mut DigitalWindowMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDigitalWindowControl_Impl::CurrentMode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetBounds(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDigitalWindowControl_Impl::GetBounds(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Configure(this: *mut core::ffi::c_void, digitalwindowmode: DigitalWindowMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDigitalWindowControl_Impl::Configure(this, digitalwindowmode).into() + } + } + unsafe extern "system" fn ConfigureWithBounds(this: *mut core::ffi::c_void, digitalwindowmode: DigitalWindowMode, digitalwindowbounds: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDigitalWindowControl_Impl::ConfigureWithBounds(this, digitalwindowmode, core::mem::transmute_copy(&digitalwindowbounds)).into() + } + } + unsafe extern "system" fn SupportedCapabilities(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDigitalWindowControl_Impl::SupportedCapabilities(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetCapabilityForSize(this: *mut core::ffi::c_void, width: i32, height: i32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDigitalWindowControl_Impl::GetCapabilityForSize(this, width, height) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsSupported: IsSupported::, + SupportedModes: SupportedModes::, + CurrentMode: CurrentMode::, + GetBounds: GetBounds::, + Configure: Configure::, + ConfigureWithBounds: ConfigureWithBounds::, + SupportedCapabilities: SupportedCapabilities::, + GetCapabilityForSize: GetCapabilityForSize::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IDigitalWindowControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SupportedModes: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32, *mut *mut DigitalWindowMode) -> windows_core::HRESULT, + pub CurrentMode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut DigitalWindowMode) -> windows_core::HRESULT, + pub GetBounds: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Configure: unsafe extern "system" fn(*mut core::ffi::c_void, DigitalWindowMode) -> windows_core::HRESULT, + pub ConfigureWithBounds: unsafe extern "system" fn(*mut core::ffi::c_void, DigitalWindowMode, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SupportedCapabilities: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetCapabilityForSize: unsafe extern "system" fn(*mut core::ffi::c_void, i32, i32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IExposureCompensationControl, IExposureCompensationControl_Vtbl, 0x81c8e834_dcec_4011_a610_1f3847e64aca); +impl windows_core::RuntimeType for IExposureCompensationControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IExposureCompensationControl { + const NAME: &'static str = "Windows.Media.Devices.IExposureCompensationControl"; +} +pub trait IExposureCompensationControl_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn Min(&self) -> windows_core::Result; + fn Max(&self) -> windows_core::Result; + fn Step(&self) -> windows_core::Result; + fn Value(&self) -> windows_core::Result; + fn SetValueAsync(&self, value: f32) -> windows_core::Result; +} +impl IExposureCompensationControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposureCompensationControl_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Min(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposureCompensationControl_Impl::Min(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Max(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposureCompensationControl_Impl::Max(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Step(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposureCompensationControl_Impl::Step(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposureCompensationControl_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValueAsync(this: *mut core::ffi::c_void, value: f32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposureCompensationControl_Impl::SetValueAsync(this, value) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + Min: Min::, + Max: Max::, + Step: Step::, + Value: Value::, + SetValueAsync: SetValueAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IExposureCompensationControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Min: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub Max: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub Step: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub Value: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub SetValueAsync: unsafe extern "system" fn(*mut core::ffi::c_void, f32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IExposureControl, IExposureControl_Vtbl, 0x09e8cbe2_ad96_4f28_a0e0_96ed7e1b5fd2); +impl windows_core::RuntimeType for IExposureControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IExposureControl { + const NAME: &'static str = "Windows.Media.Devices.IExposureControl"; +} +pub trait IExposureControl_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn Auto(&self) -> windows_core::Result; + fn SetAutoAsync(&self, value: bool) -> windows_core::Result; + fn Min(&self) -> windows_core::Result; + fn Max(&self) -> windows_core::Result; + fn Step(&self) -> windows_core::Result; + fn Value(&self) -> windows_core::Result; + fn SetValueAsync(&self, shutterDuration: &super::super::Foundation::TimeSpan) -> windows_core::Result; +} +impl IExposureControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposureControl_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Auto(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposureControl_Impl::Auto(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAutoAsync(this: *mut core::ffi::c_void, value: bool, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposureControl_Impl::SetAutoAsync(this, value) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Min(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposureControl_Impl::Min(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Max(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposureControl_Impl::Max(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Step(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposureControl_Impl::Step(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposureControl_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValueAsync(this: *mut core::ffi::c_void, shutterduration: super::super::Foundation::TimeSpan, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposureControl_Impl::SetValueAsync(this, core::mem::transmute(&shutterduration)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + Auto: Auto::, + SetAutoAsync: SetAutoAsync::, + Min: Min::, + Max: Max::, + Step: Step::, + Value: Value::, + SetValueAsync: SetValueAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IExposureControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Auto: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetAutoAsync: unsafe extern "system" fn(*mut core::ffi::c_void, bool, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Min: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub Max: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub Step: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub Value: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub SetValueAsync: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IExposurePriorityVideoControl, IExposurePriorityVideoControl_Vtbl, 0x2cb240a3_5168_4271_9ea5_47621a98a352); +impl windows_core::RuntimeType for IExposurePriorityVideoControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IExposurePriorityVideoControl { + const NAME: &'static str = "Windows.Media.Devices.IExposurePriorityVideoControl"; +} +pub trait IExposurePriorityVideoControl_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn Enabled(&self) -> windows_core::Result; + fn SetEnabled(&self, value: bool) -> windows_core::Result<()>; +} +impl IExposurePriorityVideoControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposurePriorityVideoControl_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Enabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IExposurePriorityVideoControl_Impl::Enabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IExposurePriorityVideoControl_Impl::SetEnabled(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + Enabled: Enabled::, + SetEnabled: SetEnabled::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IExposurePriorityVideoControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Enabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFlashControl, IFlashControl_Vtbl, 0xdef41dbe_7d68_45e3_8c0f_be7bb32837d0); +impl windows_core::RuntimeType for IFlashControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFlashControl { + const NAME: &'static str = "Windows.Media.Devices.IFlashControl"; +} +pub trait IFlashControl_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn PowerSupported(&self) -> windows_core::Result; + fn RedEyeReductionSupported(&self) -> windows_core::Result; + fn Enabled(&self) -> windows_core::Result; + fn SetEnabled(&self, value: bool) -> windows_core::Result<()>; + fn Auto(&self) -> windows_core::Result; + fn SetAuto(&self, value: bool) -> windows_core::Result<()>; + fn RedEyeReduction(&self) -> windows_core::Result; + fn SetRedEyeReduction(&self, value: bool) -> windows_core::Result<()>; + fn PowerPercent(&self) -> windows_core::Result; + fn SetPowerPercent(&self, value: f32) -> windows_core::Result<()>; +} +impl IFlashControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFlashControl_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PowerSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFlashControl_Impl::PowerSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RedEyeReductionSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFlashControl_Impl::RedEyeReductionSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Enabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFlashControl_Impl::Enabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFlashControl_Impl::SetEnabled(this, value).into() + } + } + unsafe extern "system" fn Auto(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFlashControl_Impl::Auto(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAuto(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFlashControl_Impl::SetAuto(this, value).into() + } + } + unsafe extern "system" fn RedEyeReduction(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFlashControl_Impl::RedEyeReduction(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRedEyeReduction(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFlashControl_Impl::SetRedEyeReduction(this, value).into() + } + } + unsafe extern "system" fn PowerPercent(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFlashControl_Impl::PowerPercent(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPowerPercent(this: *mut core::ffi::c_void, value: f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFlashControl_Impl::SetPowerPercent(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + PowerSupported: PowerSupported::, + RedEyeReductionSupported: RedEyeReductionSupported::, + Enabled: Enabled::, + SetEnabled: SetEnabled::, + Auto: Auto::, + SetAuto: SetAuto::, + RedEyeReduction: RedEyeReduction::, + SetRedEyeReduction: SetRedEyeReduction::, + PowerPercent: PowerPercent::, + SetPowerPercent: SetPowerPercent::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFlashControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub PowerSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub RedEyeReductionSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Enabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub Auto: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetAuto: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub RedEyeReduction: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetRedEyeReduction: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub PowerPercent: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub SetPowerPercent: unsafe extern "system" fn(*mut core::ffi::c_void, f32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFlashControl2, IFlashControl2_Vtbl, 0x7d29cc9e_75e1_4af7_bd7d_4e38e1c06cd6); +impl windows_core::RuntimeType for IFlashControl2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFlashControl2 { + const NAME: &'static str = "Windows.Media.Devices.IFlashControl2"; +} +pub trait IFlashControl2_Impl: windows_core::IUnknownImpl { + fn AssistantLightSupported(&self) -> windows_core::Result; + fn AssistantLightEnabled(&self) -> windows_core::Result; + fn SetAssistantLightEnabled(&self, value: bool) -> windows_core::Result<()>; +} +impl IFlashControl2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AssistantLightSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFlashControl2_Impl::AssistantLightSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AssistantLightEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFlashControl2_Impl::AssistantLightEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAssistantLightEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFlashControl2_Impl::SetAssistantLightEnabled(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AssistantLightSupported: AssistantLightSupported::, + AssistantLightEnabled: AssistantLightEnabled::, + SetAssistantLightEnabled: SetAssistantLightEnabled::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFlashControl2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AssistantLightSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub AssistantLightEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetAssistantLightEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFocusControl, IFocusControl_Vtbl, 0xc0d889f6_5228_4453_b153_85606592b238); +impl windows_core::RuntimeType for IFocusControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFocusControl { + const NAME: &'static str = "Windows.Media.Devices.IFocusControl"; +} +pub trait IFocusControl_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn SupportedPresets(&self) -> windows_core::Result>; + fn Preset(&self) -> windows_core::Result; + fn SetPresetAsync(&self, preset: FocusPreset) -> windows_core::Result; + fn SetPresetWithCompletionOptionAsync(&self, preset: FocusPreset, completeBeforeFocus: bool) -> windows_core::Result; + fn Min(&self) -> windows_core::Result; + fn Max(&self) -> windows_core::Result; + fn Step(&self) -> windows_core::Result; + fn Value(&self) -> windows_core::Result; + fn SetValueAsync(&self, focus: u32) -> windows_core::Result; + fn FocusAsync(&self) -> windows_core::Result; +} +impl IFocusControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedPresets(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl_Impl::SupportedPresets(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Preset(this: *mut core::ffi::c_void, result__: *mut FocusPreset) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl_Impl::Preset(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPresetAsync(this: *mut core::ffi::c_void, preset: FocusPreset, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl_Impl::SetPresetAsync(this, preset) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPresetWithCompletionOptionAsync(this: *mut core::ffi::c_void, preset: FocusPreset, completebeforefocus: bool, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl_Impl::SetPresetWithCompletionOptionAsync(this, preset, completebeforefocus) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Min(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl_Impl::Min(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Max(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl_Impl::Max(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Step(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl_Impl::Step(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValueAsync(this: *mut core::ffi::c_void, focus: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl_Impl::SetValueAsync(this, focus) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FocusAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl_Impl::FocusAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + SupportedPresets: SupportedPresets::, + Preset: Preset::, + SetPresetAsync: SetPresetAsync::, + SetPresetWithCompletionOptionAsync: SetPresetWithCompletionOptionAsync::, + Min: Min::, + Max: Max::, + Step: Step::, + Value: Value::, + SetValueAsync: SetValueAsync::, + FocusAsync: FocusAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFocusControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SupportedPresets: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Preset: unsafe extern "system" fn(*mut core::ffi::c_void, *mut FocusPreset) -> windows_core::HRESULT, + pub SetPresetAsync: unsafe extern "system" fn(*mut core::ffi::c_void, FocusPreset, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetPresetWithCompletionOptionAsync: unsafe extern "system" fn(*mut core::ffi::c_void, FocusPreset, bool, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Min: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Max: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Step: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Value: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetValueAsync: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub FocusAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFocusControl2, IFocusControl2_Vtbl, 0x3f7cff48_c534_4e9e_94c3_52ef2afd5d07); +impl windows_core::RuntimeType for IFocusControl2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFocusControl2 { + const NAME: &'static str = "Windows.Media.Devices.IFocusControl2"; +} +pub trait IFocusControl2_Impl: windows_core::IUnknownImpl { + fn FocusChangedSupported(&self) -> windows_core::Result; + fn WaitForFocusSupported(&self) -> windows_core::Result; + fn SupportedFocusModes(&self) -> windows_core::Result>; + fn SupportedFocusDistances(&self) -> windows_core::Result>; + fn SupportedFocusRanges(&self) -> windows_core::Result>; + fn Mode(&self) -> windows_core::Result; + fn FocusState(&self) -> windows_core::Result; + fn UnlockAsync(&self) -> windows_core::Result; + fn LockAsync(&self) -> windows_core::Result; + fn Configure(&self, settings: windows_core::Ref<'_, FocusSettings>) -> windows_core::Result<()>; +} +impl IFocusControl2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FocusChangedSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl2_Impl::FocusChangedSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WaitForFocusSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl2_Impl::WaitForFocusSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedFocusModes(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl2_Impl::SupportedFocusModes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedFocusDistances(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl2_Impl::SupportedFocusDistances(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedFocusRanges(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl2_Impl::SupportedFocusRanges(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Mode(this: *mut core::ffi::c_void, result__: *mut FocusMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl2_Impl::Mode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FocusState(this: *mut core::ffi::c_void, result__: *mut MediaCaptureFocusState) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl2_Impl::FocusState(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn UnlockAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl2_Impl::UnlockAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn LockAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusControl2_Impl::LockAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Configure(this: *mut core::ffi::c_void, settings: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFocusControl2_Impl::Configure(this, core::mem::transmute_copy(&settings)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FocusChangedSupported: FocusChangedSupported::, + WaitForFocusSupported: WaitForFocusSupported::, + SupportedFocusModes: SupportedFocusModes::, + SupportedFocusDistances: SupportedFocusDistances::, + SupportedFocusRanges: SupportedFocusRanges::, + Mode: Mode::, + FocusState: FocusState::, + UnlockAsync: UnlockAsync::, + LockAsync: LockAsync::, + Configure: Configure::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFocusControl2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub FocusChangedSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub WaitForFocusSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SupportedFocusModes: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SupportedFocusDistances: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SupportedFocusRanges: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Mode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut FocusMode) -> windows_core::HRESULT, + pub FocusState: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaCaptureFocusState) -> windows_core::HRESULT, + pub UnlockAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub LockAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Configure: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFocusSettings, IFocusSettings_Vtbl, 0x79958f6b_3263_4275_85d6_aeae891c96ee); +impl windows_core::RuntimeType for IFocusSettings { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFocusSettings { + const NAME: &'static str = "Windows.Media.Devices.IFocusSettings"; +} +pub trait IFocusSettings_Impl: windows_core::IUnknownImpl { + fn Mode(&self) -> windows_core::Result; + fn SetMode(&self, value: FocusMode) -> windows_core::Result<()>; + fn AutoFocusRange(&self) -> windows_core::Result; + fn SetAutoFocusRange(&self, value: AutoFocusRange) -> windows_core::Result<()>; + fn Value(&self) -> windows_core::Result>; + fn SetValue(&self, value: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn Distance(&self) -> windows_core::Result>; + fn SetDistance(&self, value: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn WaitForFocus(&self) -> windows_core::Result; + fn SetWaitForFocus(&self, value: bool) -> windows_core::Result<()>; + fn DisableDriverFallback(&self) -> windows_core::Result; + fn SetDisableDriverFallback(&self, value: bool) -> windows_core::Result<()>; +} +impl IFocusSettings_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Mode(this: *mut core::ffi::c_void, result__: *mut FocusMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusSettings_Impl::Mode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMode(this: *mut core::ffi::c_void, value: FocusMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFocusSettings_Impl::SetMode(this, value).into() + } + } + unsafe extern "system" fn AutoFocusRange(this: *mut core::ffi::c_void, result__: *mut AutoFocusRange) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusSettings_Impl::AutoFocusRange(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAutoFocusRange(this: *mut core::ffi::c_void, value: AutoFocusRange) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFocusSettings_Impl::SetAutoFocusRange(this, value).into() + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusSettings_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValue(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFocusSettings_Impl::SetValue(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Distance(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusSettings_Impl::Distance(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDistance(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFocusSettings_Impl::SetDistance(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn WaitForFocus(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusSettings_Impl::WaitForFocus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetWaitForFocus(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFocusSettings_Impl::SetWaitForFocus(this, value).into() + } + } + unsafe extern "system" fn DisableDriverFallback(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFocusSettings_Impl::DisableDriverFallback(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDisableDriverFallback(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFocusSettings_Impl::SetDisableDriverFallback(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Mode: Mode::, + SetMode: SetMode::, + AutoFocusRange: AutoFocusRange::, + SetAutoFocusRange: SetAutoFocusRange::, + Value: Value::, + SetValue: SetValue::, + Distance: Distance::, + SetDistance: SetDistance::, + WaitForFocus: WaitForFocus::, + SetWaitForFocus: SetWaitForFocus::, + DisableDriverFallback: DisableDriverFallback::, + SetDisableDriverFallback: SetDisableDriverFallback::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFocusSettings_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Mode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut FocusMode) -> windows_core::HRESULT, + pub SetMode: unsafe extern "system" fn(*mut core::ffi::c_void, FocusMode) -> windows_core::HRESULT, + pub AutoFocusRange: unsafe extern "system" fn(*mut core::ffi::c_void, *mut AutoFocusRange) -> windows_core::HRESULT, + pub SetAutoFocusRange: unsafe extern "system" fn(*mut core::ffi::c_void, AutoFocusRange) -> windows_core::HRESULT, + pub Value: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetValue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Distance: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetDistance: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub WaitForFocus: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetWaitForFocus: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub DisableDriverFallback: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetDisableDriverFallback: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IHdrVideoControl, IHdrVideoControl_Vtbl, 0x55d8e2d0_30c0_43bf_9b9a_9799d70ced94); +impl windows_core::RuntimeType for IHdrVideoControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IHdrVideoControl { + const NAME: &'static str = "Windows.Media.Devices.IHdrVideoControl"; +} +pub trait IHdrVideoControl_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn SupportedModes(&self) -> windows_core::Result>; + fn Mode(&self) -> windows_core::Result; + fn SetMode(&self, value: HdrVideoMode) -> windows_core::Result<()>; +} +impl IHdrVideoControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHdrVideoControl_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedModes(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHdrVideoControl_Impl::SupportedModes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Mode(this: *mut core::ffi::c_void, result__: *mut HdrVideoMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHdrVideoControl_Impl::Mode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMode(this: *mut core::ffi::c_void, value: HdrVideoMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHdrVideoControl_Impl::SetMode(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + SupportedModes: SupportedModes::, + Mode: Mode::, + SetMode: SetMode::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IHdrVideoControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SupportedModes: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Mode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut HdrVideoMode) -> windows_core::HRESULT, + pub SetMode: unsafe extern "system" fn(*mut core::ffi::c_void, HdrVideoMode) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IInfraredTorchControl, IInfraredTorchControl_Vtbl, 0x1cba2c83_6cb6_5a04_a6fc_3be7b33ff056); +impl windows_core::RuntimeType for IInfraredTorchControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IInfraredTorchControl { + const NAME: &'static str = "Windows.Media.Devices.IInfraredTorchControl"; +} +pub trait IInfraredTorchControl_Impl: windows_core::IUnknownImpl { + fn IsSupported(&self) -> windows_core::Result; + fn SupportedModes(&self) -> windows_core::Result>; + fn CurrentMode(&self) -> windows_core::Result; + fn SetCurrentMode(&self, value: InfraredTorchMode) -> windows_core::Result<()>; + fn MinPower(&self) -> windows_core::Result; + fn MaxPower(&self) -> windows_core::Result; + fn PowerStep(&self) -> windows_core::Result; + fn Power(&self) -> windows_core::Result; + fn SetPower(&self, value: i32) -> windows_core::Result<()>; +} +impl IInfraredTorchControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInfraredTorchControl_Impl::IsSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedModes(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInfraredTorchControl_Impl::SupportedModes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CurrentMode(this: *mut core::ffi::c_void, result__: *mut InfraredTorchMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInfraredTorchControl_Impl::CurrentMode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetCurrentMode(this: *mut core::ffi::c_void, value: InfraredTorchMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IInfraredTorchControl_Impl::SetCurrentMode(this, value).into() + } + } + unsafe extern "system" fn MinPower(this: *mut core::ffi::c_void, result__: *mut i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInfraredTorchControl_Impl::MinPower(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxPower(this: *mut core::ffi::c_void, result__: *mut i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInfraredTorchControl_Impl::MaxPower(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PowerStep(this: *mut core::ffi::c_void, result__: *mut i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInfraredTorchControl_Impl::PowerStep(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Power(this: *mut core::ffi::c_void, result__: *mut i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInfraredTorchControl_Impl::Power(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPower(this: *mut core::ffi::c_void, value: i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IInfraredTorchControl_Impl::SetPower(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsSupported: IsSupported::, + SupportedModes: SupportedModes::, + CurrentMode: CurrentMode::, + SetCurrentMode: SetCurrentMode::, + MinPower: MinPower::, + MaxPower: MaxPower::, + PowerStep: PowerStep::, + Power: Power::, + SetPower: SetPower::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IInfraredTorchControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SupportedModes: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CurrentMode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut InfraredTorchMode) -> windows_core::HRESULT, + pub SetCurrentMode: unsafe extern "system" fn(*mut core::ffi::c_void, InfraredTorchMode) -> windows_core::HRESULT, + pub MinPower: unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, + pub MaxPower: unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, + pub PowerStep: unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, + pub Power: unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, + pub SetPower: unsafe extern "system" fn(*mut core::ffi::c_void, i32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IIsoSpeedControl, IIsoSpeedControl_Vtbl, 0x27b6c322_25ad_4f1b_aaab_524ab376ca33); +impl windows_core::RuntimeType for IIsoSpeedControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIsoSpeedControl { + const NAME: &'static str = "Windows.Media.Devices.IIsoSpeedControl"; +} +pub trait IIsoSpeedControl_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn SupportedPresets(&self) -> windows_core::Result>; + fn Preset(&self) -> windows_core::Result; + fn SetPresetAsync(&self, preset: IsoSpeedPreset) -> windows_core::Result; +} +impl IIsoSpeedControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSpeedControl_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedPresets(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSpeedControl_Impl::SupportedPresets(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Preset(this: *mut core::ffi::c_void, result__: *mut IsoSpeedPreset) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSpeedControl_Impl::Preset(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPresetAsync(this: *mut core::ffi::c_void, preset: IsoSpeedPreset, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSpeedControl_Impl::SetPresetAsync(this, preset) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + SupportedPresets: SupportedPresets::, + Preset: Preset::, + SetPresetAsync: SetPresetAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIsoSpeedControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + #[cfg(feature = "deprecated")] + pub SupportedPresets: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + SupportedPresets: usize, + #[cfg(feature = "deprecated")] + pub Preset: unsafe extern "system" fn(*mut core::ffi::c_void, *mut IsoSpeedPreset) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + Preset: usize, + #[cfg(feature = "deprecated")] + pub SetPresetAsync: unsafe extern "system" fn(*mut core::ffi::c_void, IsoSpeedPreset, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + SetPresetAsync: usize, +} +windows_core::imp::define_interface!(IIsoSpeedControl2, IIsoSpeedControl2_Vtbl, 0x6f1578f2_6d77_4f8a_8c2f_6130b6395053); +impl windows_core::RuntimeType for IIsoSpeedControl2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIsoSpeedControl2 { + const NAME: &'static str = "Windows.Media.Devices.IIsoSpeedControl2"; +} +pub trait IIsoSpeedControl2_Impl: windows_core::IUnknownImpl { + fn Min(&self) -> windows_core::Result; + fn Max(&self) -> windows_core::Result; + fn Step(&self) -> windows_core::Result; + fn Value(&self) -> windows_core::Result; + fn SetValueAsync(&self, isoSpeed: u32) -> windows_core::Result; + fn Auto(&self) -> windows_core::Result; + fn SetAutoAsync(&self) -> windows_core::Result; +} +impl IIsoSpeedControl2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Min(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSpeedControl2_Impl::Min(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Max(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSpeedControl2_Impl::Max(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Step(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSpeedControl2_Impl::Step(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSpeedControl2_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValueAsync(this: *mut core::ffi::c_void, isospeed: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSpeedControl2_Impl::SetValueAsync(this, isospeed) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Auto(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSpeedControl2_Impl::Auto(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAutoAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIsoSpeedControl2_Impl::SetAutoAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Min: Min::, + Max: Max::, + Step: Step::, + Value: Value::, + SetValueAsync: SetValueAsync::, + Auto: Auto::, + SetAutoAsync: SetAutoAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIsoSpeedControl2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Min: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Max: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Step: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Value: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetValueAsync: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Auto: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetAutoAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ILowLagPhotoControl, ILowLagPhotoControl_Vtbl, 0x6d5c4dd0_fadf_415d_aee6_3baa529300c9); +impl windows_core::RuntimeType for ILowLagPhotoControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_MediaProperties")] +impl windows_core::RuntimeName for ILowLagPhotoControl { + const NAME: &'static str = "Windows.Media.Devices.ILowLagPhotoControl"; +} +#[cfg(feature = "Media_MediaProperties")] +pub trait ILowLagPhotoControl_Impl: windows_core::IUnknownImpl { + fn GetHighestConcurrentFrameRate(&self, captureProperties: windows_core::Ref<'_, super::MediaProperties::IMediaEncodingProperties>) -> windows_core::Result; + fn GetCurrentFrameRate(&self) -> windows_core::Result; + fn ThumbnailEnabled(&self) -> windows_core::Result; + fn SetThumbnailEnabled(&self, value: bool) -> windows_core::Result<()>; + fn ThumbnailFormat(&self) -> windows_core::Result; + fn SetThumbnailFormat(&self, value: super::MediaProperties::MediaThumbnailFormat) -> windows_core::Result<()>; + fn DesiredThumbnailSize(&self) -> windows_core::Result; + fn SetDesiredThumbnailSize(&self, value: u32) -> windows_core::Result<()>; + fn HardwareAcceleratedThumbnailSupported(&self) -> windows_core::Result; +} +#[cfg(feature = "Media_MediaProperties")] +impl ILowLagPhotoControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetHighestConcurrentFrameRate(this: *mut core::ffi::c_void, captureproperties: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoControl_Impl::GetHighestConcurrentFrameRate(this, core::mem::transmute_copy(&captureproperties)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetCurrentFrameRate(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoControl_Impl::GetCurrentFrameRate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ThumbnailEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoControl_Impl::ThumbnailEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetThumbnailEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ILowLagPhotoControl_Impl::SetThumbnailEnabled(this, value).into() + } + } + unsafe extern "system" fn ThumbnailFormat(this: *mut core::ffi::c_void, result__: *mut super::MediaProperties::MediaThumbnailFormat) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoControl_Impl::ThumbnailFormat(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetThumbnailFormat(this: *mut core::ffi::c_void, value: super::MediaProperties::MediaThumbnailFormat) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ILowLagPhotoControl_Impl::SetThumbnailFormat(this, value).into() + } + } + unsafe extern "system" fn DesiredThumbnailSize(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoControl_Impl::DesiredThumbnailSize(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDesiredThumbnailSize(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ILowLagPhotoControl_Impl::SetDesiredThumbnailSize(this, value).into() + } + } + unsafe extern "system" fn HardwareAcceleratedThumbnailSupported(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoControl_Impl::HardwareAcceleratedThumbnailSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetHighestConcurrentFrameRate: GetHighestConcurrentFrameRate::, + GetCurrentFrameRate: GetCurrentFrameRate::, + ThumbnailEnabled: ThumbnailEnabled::, + SetThumbnailEnabled: SetThumbnailEnabled::, + ThumbnailFormat: ThumbnailFormat::, + SetThumbnailFormat: SetThumbnailFormat::, + DesiredThumbnailSize: DesiredThumbnailSize::, + SetDesiredThumbnailSize: SetDesiredThumbnailSize::, + HardwareAcceleratedThumbnailSupported: HardwareAcceleratedThumbnailSupported::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ILowLagPhotoControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_MediaProperties")] + pub GetHighestConcurrentFrameRate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + GetHighestConcurrentFrameRate: usize, + #[cfg(feature = "Media_MediaProperties")] + pub GetCurrentFrameRate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + GetCurrentFrameRate: usize, + pub ThumbnailEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetThumbnailEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + #[cfg(feature = "Media_MediaProperties")] + pub ThumbnailFormat: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::MediaProperties::MediaThumbnailFormat) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + ThumbnailFormat: usize, + #[cfg(feature = "Media_MediaProperties")] + pub SetThumbnailFormat: unsafe extern "system" fn(*mut core::ffi::c_void, super::MediaProperties::MediaThumbnailFormat) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + SetThumbnailFormat: usize, + pub DesiredThumbnailSize: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetDesiredThumbnailSize: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub HardwareAcceleratedThumbnailSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ILowLagPhotoSequenceControl, ILowLagPhotoSequenceControl_Vtbl, 0x3dcf909d_6d16_409c_bafe_b9a594c6fde6); +impl windows_core::RuntimeType for ILowLagPhotoSequenceControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_MediaProperties")] +impl windows_core::RuntimeName for ILowLagPhotoSequenceControl { + const NAME: &'static str = "Windows.Media.Devices.ILowLagPhotoSequenceControl"; +} +#[cfg(feature = "Media_MediaProperties")] +pub trait ILowLagPhotoSequenceControl_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn MaxPastPhotos(&self) -> windows_core::Result; + fn MaxPhotosPerSecond(&self) -> windows_core::Result; + fn PastPhotoLimit(&self) -> windows_core::Result; + fn SetPastPhotoLimit(&self, value: u32) -> windows_core::Result<()>; + fn PhotosPerSecondLimit(&self) -> windows_core::Result; + fn SetPhotosPerSecondLimit(&self, value: f32) -> windows_core::Result<()>; + fn GetHighestConcurrentFrameRate(&self, captureProperties: windows_core::Ref<'_, super::MediaProperties::IMediaEncodingProperties>) -> windows_core::Result; + fn GetCurrentFrameRate(&self) -> windows_core::Result; + fn ThumbnailEnabled(&self) -> windows_core::Result; + fn SetThumbnailEnabled(&self, value: bool) -> windows_core::Result<()>; + fn ThumbnailFormat(&self) -> windows_core::Result; + fn SetThumbnailFormat(&self, value: super::MediaProperties::MediaThumbnailFormat) -> windows_core::Result<()>; + fn DesiredThumbnailSize(&self) -> windows_core::Result; + fn SetDesiredThumbnailSize(&self, value: u32) -> windows_core::Result<()>; + fn HardwareAcceleratedThumbnailSupported(&self) -> windows_core::Result; +} +#[cfg(feature = "Media_MediaProperties")] +impl ILowLagPhotoSequenceControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoSequenceControl_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxPastPhotos(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoSequenceControl_Impl::MaxPastPhotos(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxPhotosPerSecond(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoSequenceControl_Impl::MaxPhotosPerSecond(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PastPhotoLimit(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoSequenceControl_Impl::PastPhotoLimit(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPastPhotoLimit(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ILowLagPhotoSequenceControl_Impl::SetPastPhotoLimit(this, value).into() + } + } + unsafe extern "system" fn PhotosPerSecondLimit(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoSequenceControl_Impl::PhotosPerSecondLimit(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPhotosPerSecondLimit(this: *mut core::ffi::c_void, value: f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ILowLagPhotoSequenceControl_Impl::SetPhotosPerSecondLimit(this, value).into() + } + } + unsafe extern "system" fn GetHighestConcurrentFrameRate(this: *mut core::ffi::c_void, captureproperties: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoSequenceControl_Impl::GetHighestConcurrentFrameRate(this, core::mem::transmute_copy(&captureproperties)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetCurrentFrameRate(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoSequenceControl_Impl::GetCurrentFrameRate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ThumbnailEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoSequenceControl_Impl::ThumbnailEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetThumbnailEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ILowLagPhotoSequenceControl_Impl::SetThumbnailEnabled(this, value).into() + } + } + unsafe extern "system" fn ThumbnailFormat(this: *mut core::ffi::c_void, result__: *mut super::MediaProperties::MediaThumbnailFormat) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoSequenceControl_Impl::ThumbnailFormat(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetThumbnailFormat(this: *mut core::ffi::c_void, value: super::MediaProperties::MediaThumbnailFormat) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ILowLagPhotoSequenceControl_Impl::SetThumbnailFormat(this, value).into() + } + } + unsafe extern "system" fn DesiredThumbnailSize(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoSequenceControl_Impl::DesiredThumbnailSize(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDesiredThumbnailSize(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ILowLagPhotoSequenceControl_Impl::SetDesiredThumbnailSize(this, value).into() + } + } + unsafe extern "system" fn HardwareAcceleratedThumbnailSupported(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ILowLagPhotoSequenceControl_Impl::HardwareAcceleratedThumbnailSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + MaxPastPhotos: MaxPastPhotos::, + MaxPhotosPerSecond: MaxPhotosPerSecond::, + PastPhotoLimit: PastPhotoLimit::, + SetPastPhotoLimit: SetPastPhotoLimit::, + PhotosPerSecondLimit: PhotosPerSecondLimit::, + SetPhotosPerSecondLimit: SetPhotosPerSecondLimit::, + GetHighestConcurrentFrameRate: GetHighestConcurrentFrameRate::, + GetCurrentFrameRate: GetCurrentFrameRate::, + ThumbnailEnabled: ThumbnailEnabled::, + SetThumbnailEnabled: SetThumbnailEnabled::, + ThumbnailFormat: ThumbnailFormat::, + SetThumbnailFormat: SetThumbnailFormat::, + DesiredThumbnailSize: DesiredThumbnailSize::, + SetDesiredThumbnailSize: SetDesiredThumbnailSize::, + HardwareAcceleratedThumbnailSupported: HardwareAcceleratedThumbnailSupported::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ILowLagPhotoSequenceControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub MaxPastPhotos: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub MaxPhotosPerSecond: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub PastPhotoLimit: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetPastPhotoLimit: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub PhotosPerSecondLimit: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub SetPhotosPerSecondLimit: unsafe extern "system" fn(*mut core::ffi::c_void, f32) -> windows_core::HRESULT, + #[cfg(feature = "Media_MediaProperties")] + pub GetHighestConcurrentFrameRate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + GetHighestConcurrentFrameRate: usize, + #[cfg(feature = "Media_MediaProperties")] + pub GetCurrentFrameRate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + GetCurrentFrameRate: usize, + pub ThumbnailEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetThumbnailEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + #[cfg(feature = "Media_MediaProperties")] + pub ThumbnailFormat: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::MediaProperties::MediaThumbnailFormat) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + ThumbnailFormat: usize, + #[cfg(feature = "Media_MediaProperties")] + pub SetThumbnailFormat: unsafe extern "system" fn(*mut core::ffi::c_void, super::MediaProperties::MediaThumbnailFormat) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + SetThumbnailFormat: usize, + pub DesiredThumbnailSize: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetDesiredThumbnailSize: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub HardwareAcceleratedThumbnailSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaDeviceControl, IMediaDeviceControl_Vtbl, 0xefa8dfa9_6f75_4863_ba0b_583f3036b4de); +impl windows_core::RuntimeType for IMediaDeviceControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaDeviceControl { + const NAME: &'static str = "Windows.Media.Devices.IMediaDeviceControl"; +} +pub trait IMediaDeviceControl_Impl: windows_core::IUnknownImpl { + fn Capabilities(&self) -> windows_core::Result; + fn TryGetValue(&self, value: &mut f64) -> windows_core::Result; + fn TrySetValue(&self, value: f64) -> windows_core::Result; + fn TryGetAuto(&self, value: &mut bool) -> windows_core::Result; + fn TrySetAuto(&self, value: bool) -> windows_core::Result; +} +impl IMediaDeviceControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Capabilities(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaDeviceControl_Impl::Capabilities(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryGetValue(this: *mut core::ffi::c_void, value: *mut f64, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaDeviceControl_Impl::TryGetValue(this, core::mem::transmute_copy(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TrySetValue(this: *mut core::ffi::c_void, value: f64, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaDeviceControl_Impl::TrySetValue(this, value) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryGetAuto(this: *mut core::ffi::c_void, value: *mut bool, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaDeviceControl_Impl::TryGetAuto(this, core::mem::transmute_copy(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TrySetAuto(this: *mut core::ffi::c_void, value: bool, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaDeviceControl_Impl::TrySetAuto(this, value) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Capabilities: Capabilities::, + TryGetValue: TryGetValue::, + TrySetValue: TrySetValue::, + TryGetAuto: TryGetAuto::, + TrySetAuto: TrySetAuto::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaDeviceControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Capabilities: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub TryGetValue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64, *mut bool) -> windows_core::HRESULT, + pub TrySetValue: unsafe extern "system" fn(*mut core::ffi::c_void, f64, *mut bool) -> windows_core::HRESULT, + pub TryGetAuto: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool, *mut bool) -> windows_core::HRESULT, + pub TrySetAuto: unsafe extern "system" fn(*mut core::ffi::c_void, bool, *mut bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaDeviceControlCapabilities, IMediaDeviceControlCapabilities_Vtbl, 0x23005816_eb85_43e2_b92b_8240d5ee70ec); +impl windows_core::RuntimeType for IMediaDeviceControlCapabilities { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaDeviceControlCapabilities { + const NAME: &'static str = "Windows.Media.Devices.IMediaDeviceControlCapabilities"; +} +pub trait IMediaDeviceControlCapabilities_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn Min(&self) -> windows_core::Result; + fn Max(&self) -> windows_core::Result; + fn Step(&self) -> windows_core::Result; + fn Default(&self) -> windows_core::Result; + fn AutoModeSupported(&self) -> windows_core::Result; +} +impl IMediaDeviceControlCapabilities_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaDeviceControlCapabilities_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Min(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaDeviceControlCapabilities_Impl::Min(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Max(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaDeviceControlCapabilities_Impl::Max(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Step(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaDeviceControlCapabilities_Impl::Step(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Default(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaDeviceControlCapabilities_Impl::Default(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AutoModeSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaDeviceControlCapabilities_Impl::AutoModeSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + Min: Min::, + Max: Max::, + Step: Step::, + Default: Default::, + AutoModeSupported: AutoModeSupported::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaDeviceControlCapabilities_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Min: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, + pub Max: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, + pub Step: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, + pub Default: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, + pub AutoModeSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaDeviceController, IMediaDeviceController_Vtbl, 0xf6f8f5ce_209a_48fb_86fc_d44578f317e6); +impl windows_core::RuntimeType for IMediaDeviceController { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IMediaDeviceController, windows_core::IUnknown, windows_core::IInspectable); +impl IMediaDeviceController { + #[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] + pub fn GetAvailableMediaStreamProperties(&self, mediastreamtype: super::Capture::MediaStreamType) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAvailableMediaStreamProperties)(windows_core::Interface::as_raw(this), mediastreamtype, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] + pub fn GetMediaStreamProperties(&self, mediastreamtype: super::Capture::MediaStreamType) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMediaStreamProperties)(windows_core::Interface::as_raw(this), mediastreamtype, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] + pub fn SetMediaStreamPropertiesAsync(&self, mediastreamtype: super::Capture::MediaStreamType, mediaencodingproperties: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetMediaStreamPropertiesAsync)(windows_core::Interface::as_raw(this), mediastreamtype, mediaencodingproperties.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +#[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] +impl windows_core::RuntimeName for IMediaDeviceController { + const NAME: &'static str = "Windows.Media.Devices.IMediaDeviceController"; +} +#[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] +pub trait IMediaDeviceController_Impl: windows_core::IUnknownImpl { + fn GetAvailableMediaStreamProperties(&self, mediaStreamType: super::Capture::MediaStreamType) -> windows_core::Result>; + fn GetMediaStreamProperties(&self, mediaStreamType: super::Capture::MediaStreamType) -> windows_core::Result; + fn SetMediaStreamPropertiesAsync(&self, mediaStreamType: super::Capture::MediaStreamType, mediaEncodingProperties: windows_core::Ref<'_, super::MediaProperties::IMediaEncodingProperties>) -> windows_core::Result; +} +#[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] +impl IMediaDeviceController_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetAvailableMediaStreamProperties(this: *mut core::ffi::c_void, mediastreamtype: super::Capture::MediaStreamType, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaDeviceController_Impl::GetAvailableMediaStreamProperties(this, mediastreamtype) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetMediaStreamProperties(this: *mut core::ffi::c_void, mediastreamtype: super::Capture::MediaStreamType, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaDeviceController_Impl::GetMediaStreamProperties(this, mediastreamtype) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMediaStreamPropertiesAsync(this: *mut core::ffi::c_void, mediastreamtype: super::Capture::MediaStreamType, mediaencodingproperties: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaDeviceController_Impl::SetMediaStreamPropertiesAsync(this, mediastreamtype, core::mem::transmute_copy(&mediaencodingproperties)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetAvailableMediaStreamProperties: GetAvailableMediaStreamProperties::, + GetMediaStreamProperties: GetMediaStreamProperties::, + SetMediaStreamPropertiesAsync: SetMediaStreamPropertiesAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaDeviceController_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] + pub GetAvailableMediaStreamProperties: unsafe extern "system" fn(*mut core::ffi::c_void, super::Capture::MediaStreamType, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Media_Capture", feature = "Media_MediaProperties")))] + GetAvailableMediaStreamProperties: usize, + #[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] + pub GetMediaStreamProperties: unsafe extern "system" fn(*mut core::ffi::c_void, super::Capture::MediaStreamType, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Media_Capture", feature = "Media_MediaProperties")))] + GetMediaStreamProperties: usize, + #[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] + pub SetMediaStreamPropertiesAsync: unsafe extern "system" fn(*mut core::ffi::c_void, super::Capture::MediaStreamType, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Media_Capture", feature = "Media_MediaProperties")))] + SetMediaStreamPropertiesAsync: usize, +} +windows_core::imp::define_interface!(IOpticalImageStabilizationControl, IOpticalImageStabilizationControl_Vtbl, 0xbfad9c1d_00bc_423b_8eb2_a0178ca94247); +impl windows_core::RuntimeType for IOpticalImageStabilizationControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IOpticalImageStabilizationControl { + const NAME: &'static str = "Windows.Media.Devices.IOpticalImageStabilizationControl"; +} +pub trait IOpticalImageStabilizationControl_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn SupportedModes(&self) -> windows_core::Result>; + fn Mode(&self) -> windows_core::Result; + fn SetMode(&self, value: OpticalImageStabilizationMode) -> windows_core::Result<()>; +} +impl IOpticalImageStabilizationControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOpticalImageStabilizationControl_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedModes(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOpticalImageStabilizationControl_Impl::SupportedModes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Mode(this: *mut core::ffi::c_void, result__: *mut OpticalImageStabilizationMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IOpticalImageStabilizationControl_Impl::Mode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMode(this: *mut core::ffi::c_void, value: OpticalImageStabilizationMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IOpticalImageStabilizationControl_Impl::SetMode(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + SupportedModes: SupportedModes::, + Mode: Mode::, + SetMode: SetMode::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IOpticalImageStabilizationControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SupportedModes: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Mode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut OpticalImageStabilizationMode) -> windows_core::HRESULT, + pub SetMode: unsafe extern "system" fn(*mut core::ffi::c_void, OpticalImageStabilizationMode) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IPanelBasedOptimizationControl, IPanelBasedOptimizationControl_Vtbl, 0x33323223_6247_5419_a5a4_3d808645d917); +impl windows_core::RuntimeType for IPanelBasedOptimizationControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Devices_Enumeration")] +impl windows_core::RuntimeName for IPanelBasedOptimizationControl { + const NAME: &'static str = "Windows.Media.Devices.IPanelBasedOptimizationControl"; +} +#[cfg(feature = "Devices_Enumeration")] +pub trait IPanelBasedOptimizationControl_Impl: windows_core::IUnknownImpl { + fn IsSupported(&self) -> windows_core::Result; + fn Panel(&self) -> windows_core::Result; + fn SetPanel(&self, value: super::super::Devices::Enumeration::Panel) -> windows_core::Result<()>; +} +#[cfg(feature = "Devices_Enumeration")] +impl IPanelBasedOptimizationControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPanelBasedOptimizationControl_Impl::IsSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Panel(this: *mut core::ffi::c_void, result__: *mut super::super::Devices::Enumeration::Panel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPanelBasedOptimizationControl_Impl::Panel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPanel(this: *mut core::ffi::c_void, value: super::super::Devices::Enumeration::Panel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IPanelBasedOptimizationControl_Impl::SetPanel(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsSupported: IsSupported::, + Panel: Panel::, + SetPanel: SetPanel::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IPanelBasedOptimizationControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + #[cfg(feature = "Devices_Enumeration")] + pub Panel: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Devices::Enumeration::Panel) -> windows_core::HRESULT, + #[cfg(not(feature = "Devices_Enumeration"))] + Panel: usize, + #[cfg(feature = "Devices_Enumeration")] + pub SetPanel: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Devices::Enumeration::Panel) -> windows_core::HRESULT, + #[cfg(not(feature = "Devices_Enumeration"))] + SetPanel: usize, +} +windows_core::imp::define_interface!(IPhotoConfirmationControl, IPhotoConfirmationControl_Vtbl, 0xc8f3f363_ff5e_4582_a9a8_0550f85a4a76); +impl windows_core::RuntimeType for IPhotoConfirmationControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_MediaProperties")] +impl windows_core::RuntimeName for IPhotoConfirmationControl { + const NAME: &'static str = "Windows.Media.Devices.IPhotoConfirmationControl"; +} +#[cfg(feature = "Media_MediaProperties")] +pub trait IPhotoConfirmationControl_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn Enabled(&self) -> windows_core::Result; + fn SetEnabled(&self, value: bool) -> windows_core::Result<()>; + fn PixelFormat(&self) -> windows_core::Result; + fn SetPixelFormat(&self, format: super::MediaProperties::MediaPixelFormat) -> windows_core::Result<()>; +} +#[cfg(feature = "Media_MediaProperties")] +impl IPhotoConfirmationControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPhotoConfirmationControl_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Enabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPhotoConfirmationControl_Impl::Enabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IPhotoConfirmationControl_Impl::SetEnabled(this, value).into() + } + } + unsafe extern "system" fn PixelFormat(this: *mut core::ffi::c_void, result__: *mut super::MediaProperties::MediaPixelFormat) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPhotoConfirmationControl_Impl::PixelFormat(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPixelFormat(this: *mut core::ffi::c_void, format: super::MediaProperties::MediaPixelFormat) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IPhotoConfirmationControl_Impl::SetPixelFormat(this, format).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + Enabled: Enabled::, + SetEnabled: SetEnabled::, + PixelFormat: PixelFormat::, + SetPixelFormat: SetPixelFormat::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IPhotoConfirmationControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Enabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + #[cfg(feature = "Media_MediaProperties")] + pub PixelFormat: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::MediaProperties::MediaPixelFormat) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + PixelFormat: usize, + #[cfg(feature = "Media_MediaProperties")] + pub SetPixelFormat: unsafe extern "system" fn(*mut core::ffi::c_void, super::MediaProperties::MediaPixelFormat) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + SetPixelFormat: usize, +} +windows_core::imp::define_interface!(IRegionOfInterest, IRegionOfInterest_Vtbl, 0xe5ecc834_ce66_4e05_a78f_cf391a5ec2d1); +impl windows_core::RuntimeType for IRegionOfInterest { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IRegionOfInterest { + const NAME: &'static str = "Windows.Media.Devices.IRegionOfInterest"; +} +pub trait IRegionOfInterest_Impl: windows_core::IUnknownImpl { + fn AutoFocusEnabled(&self) -> windows_core::Result; + fn SetAutoFocusEnabled(&self, value: bool) -> windows_core::Result<()>; + fn AutoWhiteBalanceEnabled(&self) -> windows_core::Result; + fn SetAutoWhiteBalanceEnabled(&self, value: bool) -> windows_core::Result<()>; + fn AutoExposureEnabled(&self) -> windows_core::Result; + fn SetAutoExposureEnabled(&self, value: bool) -> windows_core::Result<()>; + fn Bounds(&self) -> windows_core::Result; + fn SetBounds(&self, value: &super::super::Foundation::Rect) -> windows_core::Result<()>; +} +impl IRegionOfInterest_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AutoFocusEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRegionOfInterest_Impl::AutoFocusEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAutoFocusEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IRegionOfInterest_Impl::SetAutoFocusEnabled(this, value).into() + } + } + unsafe extern "system" fn AutoWhiteBalanceEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRegionOfInterest_Impl::AutoWhiteBalanceEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAutoWhiteBalanceEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IRegionOfInterest_Impl::SetAutoWhiteBalanceEnabled(this, value).into() + } + } + unsafe extern "system" fn AutoExposureEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRegionOfInterest_Impl::AutoExposureEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAutoExposureEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IRegionOfInterest_Impl::SetAutoExposureEnabled(this, value).into() + } + } + unsafe extern "system" fn Bounds(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::Rect) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRegionOfInterest_Impl::Bounds(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetBounds(this: *mut core::ffi::c_void, value: super::super::Foundation::Rect) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IRegionOfInterest_Impl::SetBounds(this, core::mem::transmute(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AutoFocusEnabled: AutoFocusEnabled::, + SetAutoFocusEnabled: SetAutoFocusEnabled::, + AutoWhiteBalanceEnabled: AutoWhiteBalanceEnabled::, + SetAutoWhiteBalanceEnabled: SetAutoWhiteBalanceEnabled::, + AutoExposureEnabled: AutoExposureEnabled::, + SetAutoExposureEnabled: SetAutoExposureEnabled::, + Bounds: Bounds::, + SetBounds: SetBounds::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IRegionOfInterest_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AutoFocusEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetAutoFocusEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub AutoWhiteBalanceEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetAutoWhiteBalanceEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub AutoExposureEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetAutoExposureEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub Bounds: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::Rect) -> windows_core::HRESULT, + pub SetBounds: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::Rect) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IRegionOfInterest2, IRegionOfInterest2_Vtbl, 0x19fe2a91_73aa_4d51_8a9d_56ccf7db7f54); +impl windows_core::RuntimeType for IRegionOfInterest2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IRegionOfInterest2 { + const NAME: &'static str = "Windows.Media.Devices.IRegionOfInterest2"; +} +pub trait IRegionOfInterest2_Impl: windows_core::IUnknownImpl { + fn Type(&self) -> windows_core::Result; + fn SetType(&self, value: RegionOfInterestType) -> windows_core::Result<()>; + fn BoundsNormalized(&self) -> windows_core::Result; + fn SetBoundsNormalized(&self, value: bool) -> windows_core::Result<()>; + fn Weight(&self) -> windows_core::Result; + fn SetWeight(&self, value: u32) -> windows_core::Result<()>; +} +impl IRegionOfInterest2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Type(this: *mut core::ffi::c_void, result__: *mut RegionOfInterestType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRegionOfInterest2_Impl::Type(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetType(this: *mut core::ffi::c_void, value: RegionOfInterestType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IRegionOfInterest2_Impl::SetType(this, value).into() + } + } + unsafe extern "system" fn BoundsNormalized(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRegionOfInterest2_Impl::BoundsNormalized(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetBoundsNormalized(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IRegionOfInterest2_Impl::SetBoundsNormalized(this, value).into() + } + } + unsafe extern "system" fn Weight(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRegionOfInterest2_Impl::Weight(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetWeight(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IRegionOfInterest2_Impl::SetWeight(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Type: Type::, + SetType: SetType::, + BoundsNormalized: BoundsNormalized::, + SetBoundsNormalized: SetBoundsNormalized::, + Weight: Weight::, + SetWeight: SetWeight::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IRegionOfInterest2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Type: unsafe extern "system" fn(*mut core::ffi::c_void, *mut RegionOfInterestType) -> windows_core::HRESULT, + pub SetType: unsafe extern "system" fn(*mut core::ffi::c_void, RegionOfInterestType) -> windows_core::HRESULT, + pub BoundsNormalized: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetBoundsNormalized: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub Weight: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetWeight: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IRegionsOfInterestControl, IRegionsOfInterestControl_Vtbl, 0xc323f527_ab0b_4558_8b5b_df5693db0378); +impl windows_core::RuntimeType for IRegionsOfInterestControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IRegionsOfInterestControl { + const NAME: &'static str = "Windows.Media.Devices.IRegionsOfInterestControl"; +} +pub trait IRegionsOfInterestControl_Impl: windows_core::IUnknownImpl { + fn MaxRegions(&self) -> windows_core::Result; + fn SetRegionsAsync(&self, regions: windows_core::Ref<'_, windows_collections::IIterable>) -> windows_core::Result; + fn SetRegionsWithLockAsync(&self, regions: windows_core::Ref<'_, windows_collections::IIterable>, lockValues: bool) -> windows_core::Result; + fn ClearRegionsAsync(&self) -> windows_core::Result; + fn AutoFocusSupported(&self) -> windows_core::Result; + fn AutoWhiteBalanceSupported(&self) -> windows_core::Result; + fn AutoExposureSupported(&self) -> windows_core::Result; +} +impl IRegionsOfInterestControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn MaxRegions(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRegionsOfInterestControl_Impl::MaxRegions(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRegionsAsync(this: *mut core::ffi::c_void, regions: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRegionsOfInterestControl_Impl::SetRegionsAsync(this, core::mem::transmute_copy(®ions)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRegionsWithLockAsync(this: *mut core::ffi::c_void, regions: *mut core::ffi::c_void, lockvalues: bool, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRegionsOfInterestControl_Impl::SetRegionsWithLockAsync(this, core::mem::transmute_copy(®ions), lockvalues) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ClearRegionsAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRegionsOfInterestControl_Impl::ClearRegionsAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AutoFocusSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRegionsOfInterestControl_Impl::AutoFocusSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AutoWhiteBalanceSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRegionsOfInterestControl_Impl::AutoWhiteBalanceSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AutoExposureSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRegionsOfInterestControl_Impl::AutoExposureSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + MaxRegions: MaxRegions::, + SetRegionsAsync: SetRegionsAsync::, + SetRegionsWithLockAsync: SetRegionsWithLockAsync::, + ClearRegionsAsync: ClearRegionsAsync::, + AutoFocusSupported: AutoFocusSupported::, + AutoWhiteBalanceSupported: AutoWhiteBalanceSupported::, + AutoExposureSupported: AutoExposureSupported::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IRegionsOfInterestControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub MaxRegions: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetRegionsAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetRegionsWithLockAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, bool, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ClearRegionsAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub AutoFocusSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub AutoWhiteBalanceSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub AutoExposureSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISceneModeControl, ISceneModeControl_Vtbl, 0xd48e5af7_8d59_4854_8c62_12c70ba89b7c); +impl windows_core::RuntimeType for ISceneModeControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISceneModeControl { + const NAME: &'static str = "Windows.Media.Devices.ISceneModeControl"; +} +pub trait ISceneModeControl_Impl: windows_core::IUnknownImpl { + fn SupportedModes(&self) -> windows_core::Result>; + fn Value(&self) -> windows_core::Result; + fn SetValueAsync(&self, sceneMode: CaptureSceneMode) -> windows_core::Result; +} +impl ISceneModeControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SupportedModes(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISceneModeControl_Impl::SupportedModes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut CaptureSceneMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISceneModeControl_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValueAsync(this: *mut core::ffi::c_void, scenemode: CaptureSceneMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISceneModeControl_Impl::SetValueAsync(this, scenemode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SupportedModes: SupportedModes::, + Value: Value::, + SetValueAsync: SetValueAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISceneModeControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SupportedModes: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Value: unsafe extern "system" fn(*mut core::ffi::c_void, *mut CaptureSceneMode) -> windows_core::HRESULT, + pub SetValueAsync: unsafe extern "system" fn(*mut core::ffi::c_void, CaptureSceneMode, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ITorchControl, ITorchControl_Vtbl, 0xa6053665_8250_416c_919a_724296afa306); +impl windows_core::RuntimeType for ITorchControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ITorchControl { + const NAME: &'static str = "Windows.Media.Devices.ITorchControl"; +} +pub trait ITorchControl_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn PowerSupported(&self) -> windows_core::Result; + fn Enabled(&self) -> windows_core::Result; + fn SetEnabled(&self, value: bool) -> windows_core::Result<()>; + fn PowerPercent(&self) -> windows_core::Result; + fn SetPowerPercent(&self, value: f32) -> windows_core::Result<()>; +} +impl ITorchControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITorchControl_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PowerSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITorchControl_Impl::PowerSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Enabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITorchControl_Impl::Enabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ITorchControl_Impl::SetEnabled(this, value).into() + } + } + unsafe extern "system" fn PowerPercent(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITorchControl_Impl::PowerPercent(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPowerPercent(this: *mut core::ffi::c_void, value: f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ITorchControl_Impl::SetPowerPercent(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + PowerSupported: PowerSupported::, + Enabled: Enabled::, + SetEnabled: SetEnabled::, + PowerPercent: PowerPercent::, + SetPowerPercent: SetPowerPercent::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ITorchControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub PowerSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Enabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub PowerPercent: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub SetPowerPercent: unsafe extern "system" fn(*mut core::ffi::c_void, f32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoDeviceController, IVideoDeviceController_Vtbl, 0x99555575_2e2e_40b8_b6c7_f82d10013210); +impl windows_core::RuntimeType for IVideoDeviceController { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] +impl windows_core::RuntimeName for IVideoDeviceController { + const NAME: &'static str = "Windows.Media.Devices.IVideoDeviceController"; +} +#[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] +pub trait IVideoDeviceController_Impl: IMediaDeviceController_Impl { + fn Brightness(&self) -> windows_core::Result; + fn Contrast(&self) -> windows_core::Result; + fn Hue(&self) -> windows_core::Result; + fn WhiteBalance(&self) -> windows_core::Result; + fn BacklightCompensation(&self) -> windows_core::Result; + fn Pan(&self) -> windows_core::Result; + fn Tilt(&self) -> windows_core::Result; + fn Zoom(&self) -> windows_core::Result; + fn Roll(&self) -> windows_core::Result; + fn Exposure(&self) -> windows_core::Result; + fn Focus(&self) -> windows_core::Result; + fn TrySetPowerlineFrequency(&self, value: super::Capture::PowerlineFrequency) -> windows_core::Result; + fn TryGetPowerlineFrequency(&self, value: &mut super::Capture::PowerlineFrequency) -> windows_core::Result; +} +#[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] +impl IVideoDeviceController_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Brightness(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDeviceController_Impl::Brightness(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Contrast(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDeviceController_Impl::Contrast(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Hue(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDeviceController_Impl::Hue(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WhiteBalance(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDeviceController_Impl::WhiteBalance(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn BacklightCompensation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDeviceController_Impl::BacklightCompensation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Pan(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDeviceController_Impl::Pan(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Tilt(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDeviceController_Impl::Tilt(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Zoom(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDeviceController_Impl::Zoom(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Roll(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDeviceController_Impl::Roll(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Exposure(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDeviceController_Impl::Exposure(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Focus(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDeviceController_Impl::Focus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TrySetPowerlineFrequency(this: *mut core::ffi::c_void, value: super::Capture::PowerlineFrequency, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDeviceController_Impl::TrySetPowerlineFrequency(this, value) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryGetPowerlineFrequency(this: *mut core::ffi::c_void, value: *mut super::Capture::PowerlineFrequency, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDeviceController_Impl::TryGetPowerlineFrequency(this, core::mem::transmute_copy(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Brightness: Brightness::, + Contrast: Contrast::, + Hue: Hue::, + WhiteBalance: WhiteBalance::, + BacklightCompensation: BacklightCompensation::, + Pan: Pan::, + Tilt: Tilt::, + Zoom: Zoom::, + Roll: Roll::, + Exposure: Exposure::, + Focus: Focus::, + TrySetPowerlineFrequency: TrySetPowerlineFrequency::, + TryGetPowerlineFrequency: TryGetPowerlineFrequency::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoDeviceController_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Brightness: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Contrast: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Hue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub WhiteBalance: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub BacklightCompensation: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Pan: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Tilt: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Zoom: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Roll: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Exposure: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Focus: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Media_Capture")] + pub TrySetPowerlineFrequency: unsafe extern "system" fn(*mut core::ffi::c_void, super::Capture::PowerlineFrequency, *mut bool) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Capture"))] + TrySetPowerlineFrequency: usize, + #[cfg(feature = "Media_Capture")] + pub TryGetPowerlineFrequency: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::Capture::PowerlineFrequency, *mut bool) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Capture"))] + TryGetPowerlineFrequency: usize, +} +windows_core::imp::define_interface!(IVideoDeviceControllerGetDevicePropertyResult, IVideoDeviceControllerGetDevicePropertyResult_Vtbl, 0xc5d88395_6ed5_4790_8b5d_0ef13935d0f8); +impl windows_core::RuntimeType for IVideoDeviceControllerGetDevicePropertyResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoDeviceControllerGetDevicePropertyResult { + const NAME: &'static str = "Windows.Media.Devices.IVideoDeviceControllerGetDevicePropertyResult"; +} +pub trait IVideoDeviceControllerGetDevicePropertyResult_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; + fn Value(&self) -> windows_core::Result; +} +impl IVideoDeviceControllerGetDevicePropertyResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut VideoDeviceControllerGetDevicePropertyStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDeviceControllerGetDevicePropertyResult_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoDeviceControllerGetDevicePropertyResult_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Status: Status::, + Value: Value::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoDeviceControllerGetDevicePropertyResult_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Status: unsafe extern "system" fn(*mut core::ffi::c_void, *mut VideoDeviceControllerGetDevicePropertyStatus) -> windows_core::HRESULT, + pub Value: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoTemporalDenoisingControl, IVideoTemporalDenoisingControl_Vtbl, 0x7ab34735_3e2a_4a32_baff_4358c4fbdd57); +impl windows_core::RuntimeType for IVideoTemporalDenoisingControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoTemporalDenoisingControl { + const NAME: &'static str = "Windows.Media.Devices.IVideoTemporalDenoisingControl"; +} +pub trait IVideoTemporalDenoisingControl_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn SupportedModes(&self) -> windows_core::Result>; + fn Mode(&self) -> windows_core::Result; + fn SetMode(&self, value: VideoTemporalDenoisingMode) -> windows_core::Result<()>; +} +impl IVideoTemporalDenoisingControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoTemporalDenoisingControl_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedModes(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoTemporalDenoisingControl_Impl::SupportedModes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Mode(this: *mut core::ffi::c_void, result__: *mut VideoTemporalDenoisingMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoTemporalDenoisingControl_Impl::Mode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMode(this: *mut core::ffi::c_void, value: VideoTemporalDenoisingMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVideoTemporalDenoisingControl_Impl::SetMode(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + SupportedModes: SupportedModes::, + Mode: Mode::, + SetMode: SetMode::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoTemporalDenoisingControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SupportedModes: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Mode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut VideoTemporalDenoisingMode) -> windows_core::HRESULT, + pub SetMode: unsafe extern "system" fn(*mut core::ffi::c_void, VideoTemporalDenoisingMode) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IWhiteBalanceControl, IWhiteBalanceControl_Vtbl, 0x781f047e_7162_49c8_a8f9_9481c565363e); +impl windows_core::RuntimeType for IWhiteBalanceControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IWhiteBalanceControl { + const NAME: &'static str = "Windows.Media.Devices.IWhiteBalanceControl"; +} +pub trait IWhiteBalanceControl_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn Preset(&self) -> windows_core::Result; + fn SetPresetAsync(&self, preset: ColorTemperaturePreset) -> windows_core::Result; + fn Min(&self) -> windows_core::Result; + fn Max(&self) -> windows_core::Result; + fn Step(&self) -> windows_core::Result; + fn Value(&self) -> windows_core::Result; + fn SetValueAsync(&self, temperature: u32) -> windows_core::Result; +} +impl IWhiteBalanceControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWhiteBalanceControl_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Preset(this: *mut core::ffi::c_void, result__: *mut ColorTemperaturePreset) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWhiteBalanceControl_Impl::Preset(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPresetAsync(this: *mut core::ffi::c_void, preset: ColorTemperaturePreset, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWhiteBalanceControl_Impl::SetPresetAsync(this, preset) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Min(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWhiteBalanceControl_Impl::Min(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Max(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWhiteBalanceControl_Impl::Max(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Step(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWhiteBalanceControl_Impl::Step(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWhiteBalanceControl_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValueAsync(this: *mut core::ffi::c_void, temperature: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWhiteBalanceControl_Impl::SetValueAsync(this, temperature) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + Preset: Preset::, + SetPresetAsync: SetPresetAsync::, + Min: Min::, + Max: Max::, + Step: Step::, + Value: Value::, + SetValueAsync: SetValueAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IWhiteBalanceControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Preset: unsafe extern "system" fn(*mut core::ffi::c_void, *mut ColorTemperaturePreset) -> windows_core::HRESULT, + pub SetPresetAsync: unsafe extern "system" fn(*mut core::ffi::c_void, ColorTemperaturePreset, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Min: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Max: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Step: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Value: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetValueAsync: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IZoomControl, IZoomControl_Vtbl, 0x3a1e0b12_32da_4c17_bfd7_8d0c73c8f5a5); +impl windows_core::RuntimeType for IZoomControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IZoomControl { + const NAME: &'static str = "Windows.Media.Devices.IZoomControl"; +} +pub trait IZoomControl_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn Min(&self) -> windows_core::Result; + fn Max(&self) -> windows_core::Result; + fn Step(&self) -> windows_core::Result; + fn Value(&self) -> windows_core::Result; + fn SetValue(&self, value: f32) -> windows_core::Result<()>; +} +impl IZoomControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IZoomControl_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Min(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IZoomControl_Impl::Min(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Max(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IZoomControl_Impl::Max(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Step(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IZoomControl_Impl::Step(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IZoomControl_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValue(this: *mut core::ffi::c_void, value: f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IZoomControl_Impl::SetValue(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + Min: Min::, + Max: Max::, + Step: Step::, + Value: Value::, + SetValue: SetValue::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IZoomControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Min: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub Max: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub Step: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub Value: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub SetValue: unsafe extern "system" fn(*mut core::ffi::c_void, f32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IZoomControl2, IZoomControl2_Vtbl, 0x69843db0_2e99_4641_8529_184f319d1671); +impl windows_core::RuntimeType for IZoomControl2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IZoomControl2 { + const NAME: &'static str = "Windows.Media.Devices.IZoomControl2"; +} +pub trait IZoomControl2_Impl: windows_core::IUnknownImpl { + fn SupportedModes(&self) -> windows_core::Result>; + fn Mode(&self) -> windows_core::Result; + fn Configure(&self, settings: windows_core::Ref<'_, ZoomSettings>) -> windows_core::Result<()>; +} +impl IZoomControl2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SupportedModes(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IZoomControl2_Impl::SupportedModes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Mode(this: *mut core::ffi::c_void, result__: *mut ZoomTransitionMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IZoomControl2_Impl::Mode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Configure(this: *mut core::ffi::c_void, settings: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IZoomControl2_Impl::Configure(this, core::mem::transmute_copy(&settings)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SupportedModes: SupportedModes::, + Mode: Mode::, + Configure: Configure::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IZoomControl2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SupportedModes: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Mode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut ZoomTransitionMode) -> windows_core::HRESULT, + pub Configure: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IZoomSettings, IZoomSettings_Vtbl, 0x6ad66b24_14b4_4bfd_b18f_88fe24463b52); +impl windows_core::RuntimeType for IZoomSettings { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IZoomSettings { + const NAME: &'static str = "Windows.Media.Devices.IZoomSettings"; +} +pub trait IZoomSettings_Impl: windows_core::IUnknownImpl { + fn Mode(&self) -> windows_core::Result; + fn SetMode(&self, value: ZoomTransitionMode) -> windows_core::Result<()>; + fn Value(&self) -> windows_core::Result; + fn SetValue(&self, value: f32) -> windows_core::Result<()>; +} +impl IZoomSettings_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Mode(this: *mut core::ffi::c_void, result__: *mut ZoomTransitionMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IZoomSettings_Impl::Mode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMode(this: *mut core::ffi::c_void, value: ZoomTransitionMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IZoomSettings_Impl::SetMode(this, value).into() + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IZoomSettings_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValue(this: *mut core::ffi::c_void, value: f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IZoomSettings_Impl::SetValue(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Mode: Mode::, + SetMode: SetMode::, + Value: Value::, + SetValue: SetValue::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IZoomSettings_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Mode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut ZoomTransitionMode) -> windows_core::HRESULT, + pub SetMode: unsafe extern "system" fn(*mut core::ffi::c_void, ZoomTransitionMode) -> windows_core::HRESULT, + pub Value: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub SetValue: unsafe extern "system" fn(*mut core::ffi::c_void, f32) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct InfraredTorchControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(InfraredTorchControl, windows_core::IUnknown, windows_core::IInspectable); +impl InfraredTorchControl { + pub fn IsSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SupportedModes(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedModes)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CurrentMode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CurrentMode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetCurrentMode(&self, value: InfraredTorchMode) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetCurrentMode)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn MinPower(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinPower)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaxPower(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxPower)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PowerStep(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PowerStep)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Power(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Power)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetPower(&self, value: i32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPower)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for InfraredTorchControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for InfraredTorchControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for InfraredTorchControl { + const NAME: &'static str = "Windows.Media.Devices.InfraredTorchControl"; +} +unsafe impl Send for InfraredTorchControl {} +unsafe impl Sync for InfraredTorchControl {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct InfraredTorchMode(pub i32); +impl InfraredTorchMode { + pub const Off: Self = Self(0i32); + pub const On: Self = Self(1i32); + pub const AlternatingFrameIllumination: Self = Self(2i32); +} +impl windows_core::TypeKind for InfraredTorchMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for InfraredTorchMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.InfraredTorchMode;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct IsoSpeedControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(IsoSpeedControl, windows_core::IUnknown, windows_core::IInspectable); +impl IsoSpeedControl { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "deprecated")] + pub fn SupportedPresets(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedPresets)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "deprecated")] + pub fn Preset(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Preset)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "deprecated")] + pub fn SetPresetAsync(&self, preset: IsoSpeedPreset) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetPresetAsync)(windows_core::Interface::as_raw(this), preset, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Min(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Min)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Max(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Max)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Step(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Step)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Value(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetValueAsync(&self, isospeed: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetValueAsync)(windows_core::Interface::as_raw(this), isospeed, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Auto(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Auto)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAutoAsync(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetAutoAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for IsoSpeedControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for IsoSpeedControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for IsoSpeedControl { + const NAME: &'static str = "Windows.Media.Devices.IsoSpeedControl"; +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct IsoSpeedPreset(pub i32); +impl IsoSpeedPreset { + pub const Auto: Self = Self(0i32); + pub const Iso50: Self = Self(1i32); + pub const Iso80: Self = Self(2i32); + pub const Iso100: Self = Self(3i32); + pub const Iso200: Self = Self(4i32); + pub const Iso400: Self = Self(5i32); + pub const Iso800: Self = Self(6i32); + pub const Iso1600: Self = Self(7i32); + pub const Iso3200: Self = Self(8i32); + pub const Iso6400: Self = Self(9i32); + pub const Iso12800: Self = Self(10i32); + pub const Iso25600: Self = Self(11i32); +} +impl windows_core::TypeKind for IsoSpeedPreset { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for IsoSpeedPreset { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.IsoSpeedPreset;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct LowLagPhotoControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(LowLagPhotoControl, windows_core::IUnknown, windows_core::IInspectable); +impl LowLagPhotoControl { + #[cfg(feature = "Media_MediaProperties")] + pub fn GetHighestConcurrentFrameRate(&self, captureproperties: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetHighestConcurrentFrameRate)(windows_core::Interface::as_raw(this), captureproperties.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Media_MediaProperties")] + pub fn GetCurrentFrameRate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentFrameRate)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ThumbnailEnabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ThumbnailEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetThumbnailEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetThumbnailEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Media_MediaProperties")] + pub fn ThumbnailFormat(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ThumbnailFormat)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Media_MediaProperties")] + pub fn SetThumbnailFormat(&self, value: super::MediaProperties::MediaThumbnailFormat) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetThumbnailFormat)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn DesiredThumbnailSize(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DesiredThumbnailSize)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetDesiredThumbnailSize(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDesiredThumbnailSize)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn HardwareAcceleratedThumbnailSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HardwareAcceleratedThumbnailSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for LowLagPhotoControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for LowLagPhotoControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for LowLagPhotoControl { + const NAME: &'static str = "Windows.Media.Devices.LowLagPhotoControl"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct LowLagPhotoSequenceControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(LowLagPhotoSequenceControl, windows_core::IUnknown, windows_core::IInspectable); +impl LowLagPhotoSequenceControl { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaxPastPhotos(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxPastPhotos)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaxPhotosPerSecond(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxPhotosPerSecond)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PastPhotoLimit(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PastPhotoLimit)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetPastPhotoLimit(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPastPhotoLimit)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn PhotosPerSecondLimit(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PhotosPerSecondLimit)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetPhotosPerSecondLimit(&self, value: f32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPhotosPerSecondLimit)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Media_MediaProperties")] + pub fn GetHighestConcurrentFrameRate(&self, captureproperties: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetHighestConcurrentFrameRate)(windows_core::Interface::as_raw(this), captureproperties.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Media_MediaProperties")] + pub fn GetCurrentFrameRate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentFrameRate)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ThumbnailEnabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ThumbnailEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetThumbnailEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetThumbnailEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Media_MediaProperties")] + pub fn ThumbnailFormat(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ThumbnailFormat)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Media_MediaProperties")] + pub fn SetThumbnailFormat(&self, value: super::MediaProperties::MediaThumbnailFormat) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetThumbnailFormat)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn DesiredThumbnailSize(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DesiredThumbnailSize)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetDesiredThumbnailSize(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDesiredThumbnailSize)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn HardwareAcceleratedThumbnailSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HardwareAcceleratedThumbnailSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for LowLagPhotoSequenceControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for LowLagPhotoSequenceControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for LowLagPhotoSequenceControl { + const NAME: &'static str = "Windows.Media.Devices.LowLagPhotoSequenceControl"; +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct ManualFocusDistance(pub i32); +impl ManualFocusDistance { + pub const Infinity: Self = Self(0i32); + pub const Hyperfocal: Self = Self(1i32); + pub const Nearest: Self = Self(2i32); +} +impl windows_core::TypeKind for ManualFocusDistance { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for ManualFocusDistance { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.ManualFocusDistance;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaCaptureFocusState(pub i32); +impl MediaCaptureFocusState { + pub const Uninitialized: Self = Self(0i32); + pub const Lost: Self = Self(1i32); + pub const Searching: Self = Self(2i32); + pub const Focused: Self = Self(3i32); + pub const Failed: Self = Self(4i32); +} +impl windows_core::TypeKind for MediaCaptureFocusState { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaCaptureFocusState { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.MediaCaptureFocusState;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaCaptureOptimization(pub i32); +impl MediaCaptureOptimization { + pub const Default: Self = Self(0i32); + pub const Quality: Self = Self(1i32); + pub const Latency: Self = Self(2i32); + pub const Power: Self = Self(3i32); + pub const LatencyThenQuality: Self = Self(4i32); + pub const LatencyThenPower: Self = Self(5i32); + pub const PowerAndQuality: Self = Self(6i32); +} +impl windows_core::TypeKind for MediaCaptureOptimization { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaCaptureOptimization { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.MediaCaptureOptimization;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaDeviceControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaDeviceControl, windows_core::IUnknown, windows_core::IInspectable); +impl MediaDeviceControl { + pub fn Capabilities(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Capabilities)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryGetValue(&self, value: &mut f64) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryGetValue)(windows_core::Interface::as_raw(this), value, &mut result__).map(|| result__) + } + } + pub fn TrySetValue(&self, value: f64) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrySetValue)(windows_core::Interface::as_raw(this), value, &mut result__).map(|| result__) + } + } + pub fn TryGetAuto(&self, value: &mut bool) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryGetAuto)(windows_core::Interface::as_raw(this), value, &mut result__).map(|| result__) + } + } + pub fn TrySetAuto(&self, value: bool) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrySetAuto)(windows_core::Interface::as_raw(this), value, &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for MediaDeviceControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaDeviceControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaDeviceControl { + const NAME: &'static str = "Windows.Media.Devices.MediaDeviceControl"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaDeviceControlCapabilities(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaDeviceControlCapabilities, windows_core::IUnknown, windows_core::IInspectable); +impl MediaDeviceControlCapabilities { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Min(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Min)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Max(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Max)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Step(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Step)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Default(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Default)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AutoModeSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AutoModeSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for MediaDeviceControlCapabilities { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaDeviceControlCapabilities { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaDeviceControlCapabilities { + const NAME: &'static str = "Windows.Media.Devices.MediaDeviceControlCapabilities"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct OpticalImageStabilizationControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(OpticalImageStabilizationControl, windows_core::IUnknown, windows_core::IInspectable); +impl OpticalImageStabilizationControl { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SupportedModes(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedModes)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Mode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Mode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetMode(&self, value: OpticalImageStabilizationMode) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMode)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for OpticalImageStabilizationControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for OpticalImageStabilizationControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for OpticalImageStabilizationControl { + const NAME: &'static str = "Windows.Media.Devices.OpticalImageStabilizationControl"; +} +unsafe impl Send for OpticalImageStabilizationControl {} +unsafe impl Sync for OpticalImageStabilizationControl {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct OpticalImageStabilizationMode(pub i32); +impl OpticalImageStabilizationMode { + pub const Off: Self = Self(0i32); + pub const On: Self = Self(1i32); + pub const Auto: Self = Self(2i32); +} +impl windows_core::TypeKind for OpticalImageStabilizationMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for OpticalImageStabilizationMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.OpticalImageStabilizationMode;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct PanelBasedOptimizationControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(PanelBasedOptimizationControl, windows_core::IUnknown, windows_core::IInspectable); +impl PanelBasedOptimizationControl { + pub fn IsSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Devices_Enumeration")] + pub fn Panel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Panel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Devices_Enumeration")] + pub fn SetPanel(&self, value: super::super::Devices::Enumeration::Panel) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPanel)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for PanelBasedOptimizationControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for PanelBasedOptimizationControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for PanelBasedOptimizationControl { + const NAME: &'static str = "Windows.Media.Devices.PanelBasedOptimizationControl"; +} +unsafe impl Send for PanelBasedOptimizationControl {} +unsafe impl Sync for PanelBasedOptimizationControl {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct PhotoConfirmationControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(PhotoConfirmationControl, windows_core::IUnknown, windows_core::IInspectable); +impl PhotoConfirmationControl { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Enabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Enabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Media_MediaProperties")] + pub fn PixelFormat(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PixelFormat)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Media_MediaProperties")] + pub fn SetPixelFormat(&self, format: super::MediaProperties::MediaPixelFormat) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPixelFormat)(windows_core::Interface::as_raw(this), format).ok() } + } +} +impl windows_core::RuntimeType for PhotoConfirmationControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for PhotoConfirmationControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for PhotoConfirmationControl { + const NAME: &'static str = "Windows.Media.Devices.PhotoConfirmationControl"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct RegionOfInterest(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(RegionOfInterest, windows_core::IUnknown, windows_core::IInspectable); +impl RegionOfInterest { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn AutoFocusEnabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AutoFocusEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAutoFocusEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAutoFocusEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn AutoWhiteBalanceEnabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AutoWhiteBalanceEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAutoWhiteBalanceEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAutoWhiteBalanceEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn AutoExposureEnabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AutoExposureEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAutoExposureEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAutoExposureEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Bounds(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Bounds)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetBounds(&self, value: super::super::Foundation::Rect) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetBounds)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetType(&self, value: RegionOfInterestType) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetType)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn BoundsNormalized(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BoundsNormalized)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetBoundsNormalized(&self, value: bool) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetBoundsNormalized)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Weight(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Weight)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetWeight(&self, value: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetWeight)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for RegionOfInterest { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for RegionOfInterest { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for RegionOfInterest { + const NAME: &'static str = "Windows.Media.Devices.RegionOfInterest"; +} +unsafe impl Send for RegionOfInterest {} +unsafe impl Sync for RegionOfInterest {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct RegionOfInterestType(pub i32); +impl RegionOfInterestType { + pub const Unknown: Self = Self(0i32); + pub const Face: Self = Self(1i32); +} +impl windows_core::TypeKind for RegionOfInterestType { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for RegionOfInterestType { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.RegionOfInterestType;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct RegionsOfInterestControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(RegionsOfInterestControl, windows_core::IUnknown, windows_core::IInspectable); +impl RegionsOfInterestControl { + pub fn MaxRegions(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxRegions)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetRegionsAsync(&self, regions: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetRegionsAsync)(windows_core::Interface::as_raw(this), regions.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetRegionsWithLockAsync(&self, regions: P0, lockvalues: bool) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetRegionsWithLockAsync)(windows_core::Interface::as_raw(this), regions.param().abi(), lockvalues, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ClearRegionsAsync(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ClearRegionsAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn AutoFocusSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AutoFocusSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AutoWhiteBalanceSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AutoWhiteBalanceSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AutoExposureSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AutoExposureSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for RegionsOfInterestControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for RegionsOfInterestControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for RegionsOfInterestControl { + const NAME: &'static str = "Windows.Media.Devices.RegionsOfInterestControl"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SceneModeControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SceneModeControl, windows_core::IUnknown, windows_core::IInspectable); +impl SceneModeControl { + pub fn SupportedModes(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedModes)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetValueAsync(&self, scenemode: CaptureSceneMode) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetValueAsync)(windows_core::Interface::as_raw(this), scenemode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for SceneModeControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SceneModeControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SceneModeControl { + const NAME: &'static str = "Windows.Media.Devices.SceneModeControl"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct TorchControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(TorchControl, windows_core::IUnknown, windows_core::IInspectable); +impl TorchControl { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PowerSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PowerSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Enabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Enabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn PowerPercent(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PowerPercent)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetPowerPercent(&self, value: f32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPowerPercent)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for TorchControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for TorchControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for TorchControl { + const NAME: &'static str = "Windows.Media.Devices.TorchControl"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VideoDeviceController(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(VideoDeviceController, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(VideoDeviceController, IMediaDeviceController); +impl VideoDeviceController { + pub fn SetDeviceProperty(&self, propertyid: &windows_core::HSTRING, propertyvalue: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetDeviceProperty)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(propertyid), propertyvalue.param().abi()).ok() } + } + pub fn GetDeviceProperty(&self, propertyid: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeviceProperty)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(propertyid), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CameraOcclusionInfo(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CameraOcclusionInfo)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Media_Capture")] + pub fn TryAcquireExclusiveControl(&self, deviceid: &windows_core::HSTRING, mode: super::Capture::MediaCaptureDeviceExclusiveControlReleaseMode) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryAcquireExclusiveControl)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid), mode, &mut result__).map(|| result__) + } + } + pub fn LowLagPhotoSequence(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LowLagPhotoSequence)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn LowLagPhoto(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LowLagPhoto)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SceneModeControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SceneModeControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TorchControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TorchControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn FlashControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FlashControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn WhiteBalanceControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WhiteBalanceControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ExposureControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExposureControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn FocusControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FocusControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ExposureCompensationControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExposureCompensationControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IsoSpeedControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsoSpeedControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RegionsOfInterestControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RegionsOfInterestControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PrimaryUse(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PrimaryUse)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetPrimaryUse(&self, value: CaptureUse) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetPrimaryUse)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Media_Devices_Core")] + pub fn VariablePhotoSequenceController(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).VariablePhotoSequenceController)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PhotoConfirmationControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PhotoConfirmationControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ZoomControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ZoomControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ExposurePriorityVideoControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExposurePriorityVideoControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DesiredOptimization(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DesiredOptimization)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetDesiredOptimization(&self, value: MediaCaptureOptimization) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetDesiredOptimization)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn HdrVideoControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HdrVideoControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn OpticalImageStabilizationControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpticalImageStabilizationControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn AdvancedPhotoControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AdvancedPhotoControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Id(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Id)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetDevicePropertyById(&self, propertyid: &windows_core::HSTRING, maxpropertyvaluesize: P1) -> windows_core::Result + where + P1: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDevicePropertyById)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(propertyid), maxpropertyvaluesize.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetDevicePropertyById(&self, propertyid: &windows_core::HSTRING, propertyvalue: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetDevicePropertyById)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(propertyid), propertyvalue.param().abi(), &mut result__).map(|| result__) + } + } + pub fn GetDevicePropertyByExtendedId(&self, extendedpropertyid: &[u8], maxpropertyvaluesize: P1) -> windows_core::Result + where + P1: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDevicePropertyByExtendedId)(windows_core::Interface::as_raw(this), extendedpropertyid.len().try_into().unwrap(), extendedpropertyid.as_ptr(), maxpropertyvaluesize.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetDevicePropertyByExtendedId(&self, extendedpropertyid: &[u8], propertyvalue: &[u8]) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetDevicePropertyByExtendedId)(windows_core::Interface::as_raw(this), extendedpropertyid.len().try_into().unwrap(), extendedpropertyid.as_ptr(), propertyvalue.len().try_into().unwrap(), propertyvalue.as_ptr(), &mut result__).map(|| result__) + } + } + pub fn VideoTemporalDenoisingControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).VideoTemporalDenoisingControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn InfraredTorchControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InfraredTorchControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PanelBasedOptimizationControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PanelBasedOptimizationControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DigitalWindowControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DigitalWindowControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] + pub fn GetAvailableMediaStreamProperties(&self, mediastreamtype: super::Capture::MediaStreamType) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAvailableMediaStreamProperties)(windows_core::Interface::as_raw(this), mediastreamtype, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] + pub fn GetMediaStreamProperties(&self, mediastreamtype: super::Capture::MediaStreamType) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMediaStreamProperties)(windows_core::Interface::as_raw(this), mediastreamtype, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Media_Capture", feature = "Media_MediaProperties"))] + pub fn SetMediaStreamPropertiesAsync(&self, mediastreamtype: super::Capture::MediaStreamType, mediaencodingproperties: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetMediaStreamPropertiesAsync)(windows_core::Interface::as_raw(this), mediastreamtype, mediaencodingproperties.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Brightness(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Brightness)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Contrast(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Contrast)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Hue(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Hue)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn WhiteBalance(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WhiteBalance)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn BacklightCompensation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BacklightCompensation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Pan(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Pan)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Tilt(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Tilt)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Zoom(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Zoom)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Roll(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Roll)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Exposure(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Exposure)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Focus(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Focus)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Media_Capture")] + pub fn TrySetPowerlineFrequency(&self, value: super::Capture::PowerlineFrequency) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrySetPowerlineFrequency)(windows_core::Interface::as_raw(this), value, &mut result__).map(|| result__) + } + } + #[cfg(feature = "Media_Capture")] + pub fn TryGetPowerlineFrequency(&self, value: &mut super::Capture::PowerlineFrequency) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryGetPowerlineFrequency)(windows_core::Interface::as_raw(this), value, &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for VideoDeviceController { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for VideoDeviceController { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for VideoDeviceController { + const NAME: &'static str = "Windows.Media.Devices.VideoDeviceController"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VideoDeviceControllerGetDevicePropertyResult(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(VideoDeviceControllerGetDevicePropertyResult, windows_core::IUnknown, windows_core::IInspectable); +impl VideoDeviceControllerGetDevicePropertyResult { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for VideoDeviceControllerGetDevicePropertyResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for VideoDeviceControllerGetDevicePropertyResult { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for VideoDeviceControllerGetDevicePropertyResult { + const NAME: &'static str = "Windows.Media.Devices.VideoDeviceControllerGetDevicePropertyResult"; +} +unsafe impl Send for VideoDeviceControllerGetDevicePropertyResult {} +unsafe impl Sync for VideoDeviceControllerGetDevicePropertyResult {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct VideoDeviceControllerGetDevicePropertyStatus(pub i32); +impl VideoDeviceControllerGetDevicePropertyStatus { + pub const Success: Self = Self(0i32); + pub const UnknownFailure: Self = Self(1i32); + pub const BufferTooSmall: Self = Self(2i32); + pub const NotSupported: Self = Self(3i32); + pub const DeviceNotAvailable: Self = Self(4i32); + pub const MaxPropertyValueSizeTooSmall: Self = Self(5i32); + pub const MaxPropertyValueSizeRequired: Self = Self(6i32); +} +impl windows_core::TypeKind for VideoDeviceControllerGetDevicePropertyStatus { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for VideoDeviceControllerGetDevicePropertyStatus { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.VideoDeviceControllerGetDevicePropertyStatus;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct VideoDeviceControllerSetDevicePropertyStatus(pub i32); +impl VideoDeviceControllerSetDevicePropertyStatus { + pub const Success: Self = Self(0i32); + pub const UnknownFailure: Self = Self(1i32); + pub const NotSupported: Self = Self(2i32); + pub const InvalidValue: Self = Self(3i32); + pub const DeviceNotAvailable: Self = Self(4i32); + pub const NotInControl: Self = Self(5i32); +} +impl windows_core::TypeKind for VideoDeviceControllerSetDevicePropertyStatus { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for VideoDeviceControllerSetDevicePropertyStatus { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.VideoDeviceControllerSetDevicePropertyStatus;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VideoTemporalDenoisingControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(VideoTemporalDenoisingControl, windows_core::IUnknown, windows_core::IInspectable); +impl VideoTemporalDenoisingControl { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SupportedModes(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedModes)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Mode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Mode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetMode(&self, value: VideoTemporalDenoisingMode) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMode)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for VideoTemporalDenoisingControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for VideoTemporalDenoisingControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for VideoTemporalDenoisingControl { + const NAME: &'static str = "Windows.Media.Devices.VideoTemporalDenoisingControl"; +} +unsafe impl Send for VideoTemporalDenoisingControl {} +unsafe impl Sync for VideoTemporalDenoisingControl {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct VideoTemporalDenoisingMode(pub i32); +impl VideoTemporalDenoisingMode { + pub const Off: Self = Self(0i32); + pub const On: Self = Self(1i32); + pub const Auto: Self = Self(2i32); +} +impl windows_core::TypeKind for VideoTemporalDenoisingMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for VideoTemporalDenoisingMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.VideoTemporalDenoisingMode;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct WhiteBalanceControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(WhiteBalanceControl, windows_core::IUnknown, windows_core::IInspectable); +impl WhiteBalanceControl { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Preset(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Preset)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetPresetAsync(&self, preset: ColorTemperaturePreset) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetPresetAsync)(windows_core::Interface::as_raw(this), preset, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Min(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Min)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Max(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Max)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Step(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Step)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetValueAsync(&self, temperature: u32) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetValueAsync)(windows_core::Interface::as_raw(this), temperature, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for WhiteBalanceControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for WhiteBalanceControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for WhiteBalanceControl { + const NAME: &'static str = "Windows.Media.Devices.WhiteBalanceControl"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ZoomControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(ZoomControl, windows_core::IUnknown, windows_core::IInspectable); +impl ZoomControl { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Min(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Min)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Max(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Max)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Step(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Step)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetValue(&self, value: f32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetValue)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn SupportedModes(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedModes)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Mode(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Mode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Configure(&self, settings: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Configure)(windows_core::Interface::as_raw(this), settings.param().abi()).ok() } + } +} +impl windows_core::RuntimeType for ZoomControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for ZoomControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for ZoomControl { + const NAME: &'static str = "Windows.Media.Devices.ZoomControl"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ZoomSettings(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(ZoomSettings, windows_core::IUnknown, windows_core::IInspectable); +impl ZoomSettings { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn Mode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Mode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetMode(&self, value: ZoomTransitionMode) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMode)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetValue(&self, value: f32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetValue)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for ZoomSettings { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for ZoomSettings { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for ZoomSettings { + const NAME: &'static str = "Windows.Media.Devices.ZoomSettings"; +} +unsafe impl Send for ZoomSettings {} +unsafe impl Sync for ZoomSettings {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct ZoomTransitionMode(pub i32); +impl ZoomTransitionMode { + pub const Auto: Self = Self(0i32); + pub const Direct: Self = Self(1i32); + pub const Smooth: Self = Self(2i32); +} +impl windows_core::TypeKind for ZoomTransitionMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for ZoomTransitionMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.ZoomTransitionMode;i4)"); +} +#[cfg(feature = "Media_Devices_Core")] +pub mod Core{ +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct CameraIntrinsics(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(CameraIntrinsics, windows_core::IUnknown, windows_core::IInspectable); +impl CameraIntrinsics { + pub fn FocalLength(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FocalLength)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PrincipalPoint(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PrincipalPoint)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn RadialDistortion(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RadialDistortion)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn TangentialDistortion(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TangentialDistortion)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ImageWidth(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ImageWidth)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ImageHeight(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ImageHeight)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ProjectOntoFrame(&self, coordinate: windows_numerics::Vector3) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProjectOntoFrame)(windows_core::Interface::as_raw(this), coordinate, &mut result__).map(|| result__) + } + } + pub fn UnprojectAtUnitDepth(&self, pixelcoordinate: super::super::super::Foundation::Point) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UnprojectAtUnitDepth)(windows_core::Interface::as_raw(this), pixelcoordinate, &mut result__).map(|| result__) + } + } + pub fn ProjectManyOntoFrame(&self, coordinates: &[windows_numerics::Vector3], results: &mut [super::super::super::Foundation::Point]) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ProjectManyOntoFrame)(windows_core::Interface::as_raw(this), coordinates.len().try_into().unwrap(), coordinates.as_ptr(), results.len().try_into().unwrap(), results.as_mut_ptr()).ok() } + } + pub fn UnprojectPixelsAtUnitDepth(&self, pixelcoordinates: &[super::super::super::Foundation::Point], results: &mut [windows_numerics::Vector2]) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).UnprojectPixelsAtUnitDepth)(windows_core::Interface::as_raw(this), pixelcoordinates.len().try_into().unwrap(), pixelcoordinates.as_ptr(), results.len().try_into().unwrap(), results.as_mut_ptr()).ok() } + } + pub fn UndistortedProjectionTransform(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UndistortedProjectionTransform)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DistortPoint(&self, input: super::super::super::Foundation::Point) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DistortPoint)(windows_core::Interface::as_raw(this), input, &mut result__).map(|| result__) + } + } + pub fn DistortPoints(&self, inputs: &[super::super::super::Foundation::Point], results: &mut [super::super::super::Foundation::Point]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).DistortPoints)(windows_core::Interface::as_raw(this), inputs.len().try_into().unwrap(), inputs.as_ptr(), results.len().try_into().unwrap(), results.as_mut_ptr()).ok() } + } + pub fn UndistortPoint(&self, input: super::super::super::Foundation::Point) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UndistortPoint)(windows_core::Interface::as_raw(this), input, &mut result__).map(|| result__) + } + } + pub fn UndistortPoints(&self, inputs: &[super::super::super::Foundation::Point], results: &mut [super::super::super::Foundation::Point]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).UndistortPoints)(windows_core::Interface::as_raw(this), inputs.len().try_into().unwrap(), inputs.as_ptr(), results.len().try_into().unwrap(), results.as_mut_ptr()).ok() } + } + pub fn Create(focallength: windows_numerics::Vector2, principalpoint: windows_numerics::Vector2, radialdistortion: windows_numerics::Vector3, tangentialdistortion: windows_numerics::Vector2, imagewidth: u32, imageheight: u32) -> windows_core::Result { + Self::ICameraIntrinsicsFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), focallength, principalpoint, radialdistortion, tangentialdistortion, imagewidth, imageheight, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn ICameraIntrinsicsFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for CameraIntrinsics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for CameraIntrinsics { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for CameraIntrinsics { + const NAME: &'static str = "Windows.Media.Devices.Core.CameraIntrinsics"; +} +unsafe impl Send for CameraIntrinsics {} +unsafe impl Sync for CameraIntrinsics {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FrameControlCapabilities(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(FrameControlCapabilities, windows_core::IUnknown, windows_core::IInspectable); +impl FrameControlCapabilities { + pub fn Exposure(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Exposure)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ExposureCompensation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExposureCompensation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IsoSpeed(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsoSpeed)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Focus(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Focus)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PhotoConfirmationSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PhotoConfirmationSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Flash(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Flash)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for FrameControlCapabilities { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for FrameControlCapabilities { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for FrameControlCapabilities { + const NAME: &'static str = "Windows.Media.Devices.Core.FrameControlCapabilities"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FrameController(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(FrameController, windows_core::IUnknown, windows_core::IInspectable); +impl FrameController { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn ExposureControl(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExposureControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ExposureCompensationControl(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExposureCompensationControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IsoSpeedControl(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsoSpeedControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn FocusControl(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FocusControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PhotoConfirmationEnabled(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PhotoConfirmationEnabled)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetPhotoConfirmationEnabled(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPhotoConfirmationEnabled)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn FlashControl(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FlashControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for FrameController { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for FrameController { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for FrameController { + const NAME: &'static str = "Windows.Media.Devices.Core.FrameController"; +} +unsafe impl Send for FrameController {} +unsafe impl Sync for FrameController {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FrameExposureCapabilities(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(FrameExposureCapabilities, windows_core::IUnknown, windows_core::IInspectable); +impl FrameExposureCapabilities { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Min(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Min)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Max(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Max)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Step(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Step)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for FrameExposureCapabilities { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for FrameExposureCapabilities { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for FrameExposureCapabilities { + const NAME: &'static str = "Windows.Media.Devices.Core.FrameExposureCapabilities"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FrameExposureCompensationCapabilities(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(FrameExposureCompensationCapabilities, windows_core::IUnknown, windows_core::IInspectable); +impl FrameExposureCompensationCapabilities { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Min(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Min)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Max(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Max)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Step(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Step)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for FrameExposureCompensationCapabilities { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for FrameExposureCompensationCapabilities { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for FrameExposureCompensationCapabilities { + const NAME: &'static str = "Windows.Media.Devices.Core.FrameExposureCompensationCapabilities"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FrameExposureCompensationControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(FrameExposureCompensationControl, windows_core::IUnknown, windows_core::IInspectable); +impl FrameExposureCompensationControl { + pub fn Value(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetValue(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetValue)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } +} +impl windows_core::RuntimeType for FrameExposureCompensationControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for FrameExposureCompensationControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for FrameExposureCompensationControl { + const NAME: &'static str = "Windows.Media.Devices.Core.FrameExposureCompensationControl"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FrameExposureControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(FrameExposureControl, windows_core::IUnknown, windows_core::IInspectable); +impl FrameExposureControl { + pub fn Auto(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Auto)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAuto(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAuto)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Value(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetValue(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetValue)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } +} +impl windows_core::RuntimeType for FrameExposureControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for FrameExposureControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for FrameExposureControl { + const NAME: &'static str = "Windows.Media.Devices.Core.FrameExposureControl"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FrameFlashCapabilities(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(FrameFlashCapabilities, windows_core::IUnknown, windows_core::IInspectable); +impl FrameFlashCapabilities { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn RedEyeReductionSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RedEyeReductionSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PowerSupported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PowerSupported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for FrameFlashCapabilities { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for FrameFlashCapabilities { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for FrameFlashCapabilities { + const NAME: &'static str = "Windows.Media.Devices.Core.FrameFlashCapabilities"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FrameFlashControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(FrameFlashControl, windows_core::IUnknown, windows_core::IInspectable); +impl FrameFlashControl { + pub fn Mode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Mode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetMode(&self, value: FrameFlashMode) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMode)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Auto(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Auto)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAuto(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAuto)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn RedEyeReduction(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RedEyeReduction)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetRedEyeReduction(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetRedEyeReduction)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn PowerPercent(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PowerPercent)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetPowerPercent(&self, value: f32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPowerPercent)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for FrameFlashControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for FrameFlashControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for FrameFlashControl { + const NAME: &'static str = "Windows.Media.Devices.Core.FrameFlashControl"; +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct FrameFlashMode(pub i32); +impl FrameFlashMode { + pub const Disable: Self = Self(0i32); + pub const Enable: Self = Self(1i32); + pub const Global: Self = Self(2i32); +} +impl windows_core::TypeKind for FrameFlashMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for FrameFlashMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Devices.Core.FrameFlashMode;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FrameFocusCapabilities(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(FrameFocusCapabilities, windows_core::IUnknown, windows_core::IInspectable); +impl FrameFocusCapabilities { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Min(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Min)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Max(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Max)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Step(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Step)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for FrameFocusCapabilities { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for FrameFocusCapabilities { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for FrameFocusCapabilities { + const NAME: &'static str = "Windows.Media.Devices.Core.FrameFocusCapabilities"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FrameFocusControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(FrameFocusControl, windows_core::IUnknown, windows_core::IInspectable); +impl FrameFocusControl { + pub fn Value(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetValue(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetValue)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } +} +impl windows_core::RuntimeType for FrameFocusControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for FrameFocusControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for FrameFocusControl { + const NAME: &'static str = "Windows.Media.Devices.Core.FrameFocusControl"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FrameIsoSpeedCapabilities(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(FrameIsoSpeedCapabilities, windows_core::IUnknown, windows_core::IInspectable); +impl FrameIsoSpeedCapabilities { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Min(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Min)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Max(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Max)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Step(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Step)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for FrameIsoSpeedCapabilities { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for FrameIsoSpeedCapabilities { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for FrameIsoSpeedCapabilities { + const NAME: &'static str = "Windows.Media.Devices.Core.FrameIsoSpeedCapabilities"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct FrameIsoSpeedControl(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(FrameIsoSpeedControl, windows_core::IUnknown, windows_core::IInspectable); +impl FrameIsoSpeedControl { + pub fn Auto(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Auto)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAuto(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAuto)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Value(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetValue(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetValue)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } +} +impl windows_core::RuntimeType for FrameIsoSpeedControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for FrameIsoSpeedControl { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for FrameIsoSpeedControl { + const NAME: &'static str = "Windows.Media.Devices.Core.FrameIsoSpeedControl"; +} +windows_core::imp::define_interface!(ICameraIntrinsics, ICameraIntrinsics_Vtbl, 0x0aa6ed32_6589_49da_afde_594270ca0aac); +impl windows_core::RuntimeType for ICameraIntrinsics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ICameraIntrinsics { + const NAME: &'static str = "Windows.Media.Devices.Core.ICameraIntrinsics"; +} +pub trait ICameraIntrinsics_Impl: windows_core::IUnknownImpl { + fn FocalLength(&self) -> windows_core::Result; + fn PrincipalPoint(&self) -> windows_core::Result; + fn RadialDistortion(&self) -> windows_core::Result; + fn TangentialDistortion(&self) -> windows_core::Result; + fn ImageWidth(&self) -> windows_core::Result; + fn ImageHeight(&self) -> windows_core::Result; + fn ProjectOntoFrame(&self, coordinate: &windows_numerics::Vector3) -> windows_core::Result; + fn UnprojectAtUnitDepth(&self, pixelCoordinate: &super::super::super::Foundation::Point) -> windows_core::Result; + fn ProjectManyOntoFrame(&self, coordinates: &[windows_numerics::Vector3], results: &mut [super::super::super::Foundation::Point]) -> windows_core::Result<()>; + fn UnprojectPixelsAtUnitDepth(&self, pixelCoordinates: &[super::super::super::Foundation::Point], results: &mut [windows_numerics::Vector2]) -> windows_core::Result<()>; +} +impl ICameraIntrinsics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FocalLength(this: *mut core::ffi::c_void, result__: *mut windows_numerics::Vector2) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraIntrinsics_Impl::FocalLength(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PrincipalPoint(this: *mut core::ffi::c_void, result__: *mut windows_numerics::Vector2) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraIntrinsics_Impl::PrincipalPoint(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RadialDistortion(this: *mut core::ffi::c_void, result__: *mut windows_numerics::Vector3) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraIntrinsics_Impl::RadialDistortion(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TangentialDistortion(this: *mut core::ffi::c_void, result__: *mut windows_numerics::Vector2) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraIntrinsics_Impl::TangentialDistortion(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ImageWidth(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraIntrinsics_Impl::ImageWidth(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ImageHeight(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraIntrinsics_Impl::ImageHeight(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ProjectOntoFrame(this: *mut core::ffi::c_void, coordinate: windows_numerics::Vector3, result__: *mut super::super::super::Foundation::Point) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraIntrinsics_Impl::ProjectOntoFrame(this, core::mem::transmute(&coordinate)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn UnprojectAtUnitDepth(this: *mut core::ffi::c_void, pixelcoordinate: super::super::super::Foundation::Point, result__: *mut windows_numerics::Vector2) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraIntrinsics_Impl::UnprojectAtUnitDepth(this, core::mem::transmute(&pixelcoordinate)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ProjectManyOntoFrame(this: *mut core::ffi::c_void, coordinates_array_size: u32, coordinates: *const windows_numerics::Vector3, results_array_size: u32, results: *mut super::super::super::Foundation::Point) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICameraIntrinsics_Impl::ProjectManyOntoFrame(this, core::slice::from_raw_parts(core::mem::transmute_copy(&coordinates), coordinates_array_size as usize), core::slice::from_raw_parts_mut(core::mem::transmute_copy(&results), results_array_size as usize)).into() + } + } + unsafe extern "system" fn UnprojectPixelsAtUnitDepth(this: *mut core::ffi::c_void, pixelcoordinates_array_size: u32, pixelcoordinates: *const super::super::super::Foundation::Point, results_array_size: u32, results: *mut windows_numerics::Vector2) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICameraIntrinsics_Impl::UnprojectPixelsAtUnitDepth(this, core::slice::from_raw_parts(core::mem::transmute_copy(&pixelcoordinates), pixelcoordinates_array_size as usize), core::slice::from_raw_parts_mut(core::mem::transmute_copy(&results), results_array_size as usize)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FocalLength: FocalLength::, + PrincipalPoint: PrincipalPoint::, + RadialDistortion: RadialDistortion::, + TangentialDistortion: TangentialDistortion::, + ImageWidth: ImageWidth::, + ImageHeight: ImageHeight::, + ProjectOntoFrame: ProjectOntoFrame::, + UnprojectAtUnitDepth: UnprojectAtUnitDepth::, + ProjectManyOntoFrame: ProjectManyOntoFrame::, + UnprojectPixelsAtUnitDepth: UnprojectPixelsAtUnitDepth::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ICameraIntrinsics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub FocalLength: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_numerics::Vector2) -> windows_core::HRESULT, + pub PrincipalPoint: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_numerics::Vector2) -> windows_core::HRESULT, + pub RadialDistortion: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_numerics::Vector3) -> windows_core::HRESULT, + pub TangentialDistortion: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_numerics::Vector2) -> windows_core::HRESULT, + pub ImageWidth: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub ImageHeight: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub ProjectOntoFrame: unsafe extern "system" fn(*mut core::ffi::c_void, windows_numerics::Vector3, *mut super::super::super::Foundation::Point) -> windows_core::HRESULT, + pub UnprojectAtUnitDepth: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::super::Foundation::Point, *mut windows_numerics::Vector2) -> windows_core::HRESULT, + pub ProjectManyOntoFrame: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const windows_numerics::Vector3, u32, *mut super::super::super::Foundation::Point) -> windows_core::HRESULT, + pub UnprojectPixelsAtUnitDepth: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const super::super::super::Foundation::Point, u32, *mut windows_numerics::Vector2) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ICameraIntrinsics2, ICameraIntrinsics2_Vtbl, 0x0cdaa447_0798_4b4d_839f_c5ec414db27a); +impl windows_core::RuntimeType for ICameraIntrinsics2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ICameraIntrinsics2 { + const NAME: &'static str = "Windows.Media.Devices.Core.ICameraIntrinsics2"; +} +pub trait ICameraIntrinsics2_Impl: windows_core::IUnknownImpl { + fn UndistortedProjectionTransform(&self) -> windows_core::Result; + fn DistortPoint(&self, input: &super::super::super::Foundation::Point) -> windows_core::Result; + fn DistortPoints(&self, inputs: &[super::super::super::Foundation::Point], results: &mut [super::super::super::Foundation::Point]) -> windows_core::Result<()>; + fn UndistortPoint(&self, input: &super::super::super::Foundation::Point) -> windows_core::Result; + fn UndistortPoints(&self, inputs: &[super::super::super::Foundation::Point], results: &mut [super::super::super::Foundation::Point]) -> windows_core::Result<()>; +} +impl ICameraIntrinsics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn UndistortedProjectionTransform(this: *mut core::ffi::c_void, result__: *mut windows_numerics::Matrix4x4) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraIntrinsics2_Impl::UndistortedProjectionTransform(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DistortPoint(this: *mut core::ffi::c_void, input: super::super::super::Foundation::Point, result__: *mut super::super::super::Foundation::Point) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraIntrinsics2_Impl::DistortPoint(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DistortPoints(this: *mut core::ffi::c_void, inputs_array_size: u32, inputs: *const super::super::super::Foundation::Point, results_array_size: u32, results: *mut super::super::super::Foundation::Point) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICameraIntrinsics2_Impl::DistortPoints(this, core::slice::from_raw_parts(core::mem::transmute_copy(&inputs), inputs_array_size as usize), core::slice::from_raw_parts_mut(core::mem::transmute_copy(&results), results_array_size as usize)).into() + } + } + unsafe extern "system" fn UndistortPoint(this: *mut core::ffi::c_void, input: super::super::super::Foundation::Point, result__: *mut super::super::super::Foundation::Point) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraIntrinsics2_Impl::UndistortPoint(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn UndistortPoints(this: *mut core::ffi::c_void, inputs_array_size: u32, inputs: *const super::super::super::Foundation::Point, results_array_size: u32, results: *mut super::super::super::Foundation::Point) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICameraIntrinsics2_Impl::UndistortPoints(this, core::slice::from_raw_parts(core::mem::transmute_copy(&inputs), inputs_array_size as usize), core::slice::from_raw_parts_mut(core::mem::transmute_copy(&results), results_array_size as usize)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + UndistortedProjectionTransform: UndistortedProjectionTransform::, + DistortPoint: DistortPoint::, + DistortPoints: DistortPoints::, + UndistortPoint: UndistortPoint::, + UndistortPoints: UndistortPoints::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ICameraIntrinsics2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub UndistortedProjectionTransform: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_numerics::Matrix4x4) -> windows_core::HRESULT, + pub DistortPoint: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::super::Foundation::Point, *mut super::super::super::Foundation::Point) -> windows_core::HRESULT, + pub DistortPoints: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const super::super::super::Foundation::Point, u32, *mut super::super::super::Foundation::Point) -> windows_core::HRESULT, + pub UndistortPoint: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::super::Foundation::Point, *mut super::super::super::Foundation::Point) -> windows_core::HRESULT, + pub UndistortPoints: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const super::super::super::Foundation::Point, u32, *mut super::super::super::Foundation::Point) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ICameraIntrinsicsFactory, ICameraIntrinsicsFactory_Vtbl, 0xc0ddc486_2132_4a34_a659_9bfe2a055712); +impl windows_core::RuntimeType for ICameraIntrinsicsFactory { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ICameraIntrinsicsFactory { + const NAME: &'static str = "Windows.Media.Devices.Core.ICameraIntrinsicsFactory"; +} +pub trait ICameraIntrinsicsFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, focalLength: &windows_numerics::Vector2, principalPoint: &windows_numerics::Vector2, radialDistortion: &windows_numerics::Vector3, tangentialDistortion: &windows_numerics::Vector2, imageWidth: u32, imageHeight: u32) -> windows_core::Result; +} +impl ICameraIntrinsicsFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, focallength: windows_numerics::Vector2, principalpoint: windows_numerics::Vector2, radialdistortion: windows_numerics::Vector3, tangentialdistortion: windows_numerics::Vector2, imagewidth: u32, imageheight: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICameraIntrinsicsFactory_Impl::Create(this, core::mem::transmute(&focallength), core::mem::transmute(&principalpoint), core::mem::transmute(&radialdistortion), core::mem::transmute(&tangentialdistortion), imagewidth, imageheight) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ICameraIntrinsicsFactory_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Create: unsafe extern "system" fn(*mut core::ffi::c_void, windows_numerics::Vector2, windows_numerics::Vector2, windows_numerics::Vector3, windows_numerics::Vector2, u32, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFrameControlCapabilities, IFrameControlCapabilities_Vtbl, 0xa8ffae60_4e9e_4377_a789_e24c4ae7e544); +impl windows_core::RuntimeType for IFrameControlCapabilities { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFrameControlCapabilities { + const NAME: &'static str = "Windows.Media.Devices.Core.IFrameControlCapabilities"; +} +pub trait IFrameControlCapabilities_Impl: windows_core::IUnknownImpl { + fn Exposure(&self) -> windows_core::Result; + fn ExposureCompensation(&self) -> windows_core::Result; + fn IsoSpeed(&self) -> windows_core::Result; + fn Focus(&self) -> windows_core::Result; + fn PhotoConfirmationSupported(&self) -> windows_core::Result; +} +impl IFrameControlCapabilities_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Exposure(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameControlCapabilities_Impl::Exposure(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ExposureCompensation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameControlCapabilities_Impl::ExposureCompensation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsoSpeed(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameControlCapabilities_Impl::IsoSpeed(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Focus(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameControlCapabilities_Impl::Focus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PhotoConfirmationSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameControlCapabilities_Impl::PhotoConfirmationSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Exposure: Exposure::, + ExposureCompensation: ExposureCompensation::, + IsoSpeed: IsoSpeed::, + Focus: Focus::, + PhotoConfirmationSupported: PhotoConfirmationSupported::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFrameControlCapabilities_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Exposure: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ExposureCompensation: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub IsoSpeed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Focus: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub PhotoConfirmationSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFrameControlCapabilities2, IFrameControlCapabilities2_Vtbl, 0xce9b0464_4730_440f_bd3e_efe8a8f230a8); +impl windows_core::RuntimeType for IFrameControlCapabilities2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFrameControlCapabilities2 { + const NAME: &'static str = "Windows.Media.Devices.Core.IFrameControlCapabilities2"; +} +pub trait IFrameControlCapabilities2_Impl: windows_core::IUnknownImpl { + fn Flash(&self) -> windows_core::Result; +} +impl IFrameControlCapabilities2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Flash(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameControlCapabilities2_Impl::Flash(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Flash: Flash:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFrameControlCapabilities2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Flash: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFrameController, IFrameController_Vtbl, 0xc16459d9_baef_4052_9177_48aff2af7522); +impl windows_core::RuntimeType for IFrameController { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFrameController { + const NAME: &'static str = "Windows.Media.Devices.Core.IFrameController"; +} +pub trait IFrameController_Impl: windows_core::IUnknownImpl { + fn ExposureControl(&self) -> windows_core::Result; + fn ExposureCompensationControl(&self) -> windows_core::Result; + fn IsoSpeedControl(&self) -> windows_core::Result; + fn FocusControl(&self) -> windows_core::Result; + fn PhotoConfirmationEnabled(&self) -> windows_core::Result>; + fn SetPhotoConfirmationEnabled(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; +} +impl IFrameController_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ExposureControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameController_Impl::ExposureControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ExposureCompensationControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameController_Impl::ExposureCompensationControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsoSpeedControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameController_Impl::IsoSpeedControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FocusControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameController_Impl::FocusControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PhotoConfirmationEnabled(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameController_Impl::PhotoConfirmationEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPhotoConfirmationEnabled(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFrameController_Impl::SetPhotoConfirmationEnabled(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ExposureControl: ExposureControl::, + ExposureCompensationControl: ExposureCompensationControl::, + IsoSpeedControl: IsoSpeedControl::, + FocusControl: FocusControl::, + PhotoConfirmationEnabled: PhotoConfirmationEnabled::, + SetPhotoConfirmationEnabled: SetPhotoConfirmationEnabled::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFrameController_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ExposureControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ExposureCompensationControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub IsoSpeedControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub FocusControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub PhotoConfirmationEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetPhotoConfirmationEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFrameController2, IFrameController2_Vtbl, 0x00d3bc75_d87c_485b_8a09_5c358568b427); +impl windows_core::RuntimeType for IFrameController2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFrameController2 { + const NAME: &'static str = "Windows.Media.Devices.Core.IFrameController2"; +} +pub trait IFrameController2_Impl: windows_core::IUnknownImpl { + fn FlashControl(&self) -> windows_core::Result; +} +impl IFrameController2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FlashControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameController2_Impl::FlashControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), FlashControl: FlashControl:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFrameController2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub FlashControl: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFrameExposureCapabilities, IFrameExposureCapabilities_Vtbl, 0xbdbe9ce3_3985_4e72_97c2_0590d61307a1); +impl windows_core::RuntimeType for IFrameExposureCapabilities { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFrameExposureCapabilities { + const NAME: &'static str = "Windows.Media.Devices.Core.IFrameExposureCapabilities"; +} +pub trait IFrameExposureCapabilities_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn Min(&self) -> windows_core::Result; + fn Max(&self) -> windows_core::Result; + fn Step(&self) -> windows_core::Result; +} +impl IFrameExposureCapabilities_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameExposureCapabilities_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Min(this: *mut core::ffi::c_void, result__: *mut super::super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameExposureCapabilities_Impl::Min(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Max(this: *mut core::ffi::c_void, result__: *mut super::super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameExposureCapabilities_Impl::Max(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Step(this: *mut core::ffi::c_void, result__: *mut super::super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameExposureCapabilities_Impl::Step(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + Min: Min::, + Max: Max::, + Step: Step::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFrameExposureCapabilities_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Min: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub Max: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub Step: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::super::Foundation::TimeSpan) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFrameExposureCompensationCapabilities, IFrameExposureCompensationCapabilities_Vtbl, 0xb988a823_8065_41ee_b04f_722265954500); +impl windows_core::RuntimeType for IFrameExposureCompensationCapabilities { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFrameExposureCompensationCapabilities { + const NAME: &'static str = "Windows.Media.Devices.Core.IFrameExposureCompensationCapabilities"; +} +pub trait IFrameExposureCompensationCapabilities_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn Min(&self) -> windows_core::Result; + fn Max(&self) -> windows_core::Result; + fn Step(&self) -> windows_core::Result; +} +impl IFrameExposureCompensationCapabilities_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameExposureCompensationCapabilities_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Min(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameExposureCompensationCapabilities_Impl::Min(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Max(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameExposureCompensationCapabilities_Impl::Max(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Step(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameExposureCompensationCapabilities_Impl::Step(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + Min: Min::, + Max: Max::, + Step: Step::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFrameExposureCompensationCapabilities_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Min: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub Max: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub Step: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFrameExposureCompensationControl, IFrameExposureCompensationControl_Vtbl, 0xe95896c9_f7f9_48ca_8591_a26531cb1578); +impl windows_core::RuntimeType for IFrameExposureCompensationControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFrameExposureCompensationControl { + const NAME: &'static str = "Windows.Media.Devices.Core.IFrameExposureCompensationControl"; +} +pub trait IFrameExposureCompensationControl_Impl: windows_core::IUnknownImpl { + fn Value(&self) -> windows_core::Result>; + fn SetValue(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; +} +impl IFrameExposureCompensationControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameExposureCompensationControl_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValue(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFrameExposureCompensationControl_Impl::SetValue(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Value: Value::, + SetValue: SetValue::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFrameExposureCompensationControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Value: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetValue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFrameExposureControl, IFrameExposureControl_Vtbl, 0xb1605a61_ffaf_4752_b621_f5b6f117f432); +impl windows_core::RuntimeType for IFrameExposureControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFrameExposureControl { + const NAME: &'static str = "Windows.Media.Devices.Core.IFrameExposureControl"; +} +pub trait IFrameExposureControl_Impl: windows_core::IUnknownImpl { + fn Auto(&self) -> windows_core::Result; + fn SetAuto(&self, value: bool) -> windows_core::Result<()>; + fn Value(&self) -> windows_core::Result>; + fn SetValue(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; +} +impl IFrameExposureControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Auto(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameExposureControl_Impl::Auto(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAuto(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFrameExposureControl_Impl::SetAuto(this, value).into() + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameExposureControl_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValue(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFrameExposureControl_Impl::SetValue(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Auto: Auto::, + SetAuto: SetAuto::, + Value: Value::, + SetValue: SetValue::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFrameExposureControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Auto: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetAuto: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub Value: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetValue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFrameFlashCapabilities, IFrameFlashCapabilities_Vtbl, 0xbb9341a2_5ebe_4f62_8223_0e2b05bfbbd0); +impl windows_core::RuntimeType for IFrameFlashCapabilities { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFrameFlashCapabilities { + const NAME: &'static str = "Windows.Media.Devices.Core.IFrameFlashCapabilities"; +} +pub trait IFrameFlashCapabilities_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn RedEyeReductionSupported(&self) -> windows_core::Result; + fn PowerSupported(&self) -> windows_core::Result; +} +impl IFrameFlashCapabilities_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameFlashCapabilities_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RedEyeReductionSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameFlashCapabilities_Impl::RedEyeReductionSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PowerSupported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameFlashCapabilities_Impl::PowerSupported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + RedEyeReductionSupported: RedEyeReductionSupported::, + PowerSupported: PowerSupported::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFrameFlashCapabilities_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub RedEyeReductionSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub PowerSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFrameFlashControl, IFrameFlashControl_Vtbl, 0x75d5f6c7_bd45_4fab_9375_45ac04b332c2); +impl windows_core::RuntimeType for IFrameFlashControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFrameFlashControl { + const NAME: &'static str = "Windows.Media.Devices.Core.IFrameFlashControl"; +} +pub trait IFrameFlashControl_Impl: windows_core::IUnknownImpl { + fn Mode(&self) -> windows_core::Result; + fn SetMode(&self, value: FrameFlashMode) -> windows_core::Result<()>; + fn Auto(&self) -> windows_core::Result; + fn SetAuto(&self, value: bool) -> windows_core::Result<()>; + fn RedEyeReduction(&self) -> windows_core::Result; + fn SetRedEyeReduction(&self, value: bool) -> windows_core::Result<()>; + fn PowerPercent(&self) -> windows_core::Result; + fn SetPowerPercent(&self, value: f32) -> windows_core::Result<()>; +} +impl IFrameFlashControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Mode(this: *mut core::ffi::c_void, result__: *mut FrameFlashMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameFlashControl_Impl::Mode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMode(this: *mut core::ffi::c_void, value: FrameFlashMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFrameFlashControl_Impl::SetMode(this, value).into() + } + } + unsafe extern "system" fn Auto(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameFlashControl_Impl::Auto(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAuto(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFrameFlashControl_Impl::SetAuto(this, value).into() + } + } + unsafe extern "system" fn RedEyeReduction(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameFlashControl_Impl::RedEyeReduction(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRedEyeReduction(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFrameFlashControl_Impl::SetRedEyeReduction(this, value).into() + } + } + unsafe extern "system" fn PowerPercent(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameFlashControl_Impl::PowerPercent(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPowerPercent(this: *mut core::ffi::c_void, value: f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFrameFlashControl_Impl::SetPowerPercent(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Mode: Mode::, + SetMode: SetMode::, + Auto: Auto::, + SetAuto: SetAuto::, + RedEyeReduction: RedEyeReduction::, + SetRedEyeReduction: SetRedEyeReduction::, + PowerPercent: PowerPercent::, + SetPowerPercent: SetPowerPercent::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFrameFlashControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Mode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut FrameFlashMode) -> windows_core::HRESULT, + pub SetMode: unsafe extern "system" fn(*mut core::ffi::c_void, FrameFlashMode) -> windows_core::HRESULT, + pub Auto: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetAuto: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub RedEyeReduction: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetRedEyeReduction: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub PowerPercent: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub SetPowerPercent: unsafe extern "system" fn(*mut core::ffi::c_void, f32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFrameFocusCapabilities, IFrameFocusCapabilities_Vtbl, 0x7b25cd58_01c0_4065_9c40_c1a721425c1a); +impl windows_core::RuntimeType for IFrameFocusCapabilities { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFrameFocusCapabilities { + const NAME: &'static str = "Windows.Media.Devices.Core.IFrameFocusCapabilities"; +} +pub trait IFrameFocusCapabilities_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn Min(&self) -> windows_core::Result; + fn Max(&self) -> windows_core::Result; + fn Step(&self) -> windows_core::Result; +} +impl IFrameFocusCapabilities_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameFocusCapabilities_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Min(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameFocusCapabilities_Impl::Min(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Max(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameFocusCapabilities_Impl::Max(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Step(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameFocusCapabilities_Impl::Step(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + Min: Min::, + Max: Max::, + Step: Step::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFrameFocusCapabilities_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Min: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Max: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Step: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFrameFocusControl, IFrameFocusControl_Vtbl, 0x272df1d0_d912_4214_a67b_e38a8d48d8c6); +impl windows_core::RuntimeType for IFrameFocusControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFrameFocusControl { + const NAME: &'static str = "Windows.Media.Devices.Core.IFrameFocusControl"; +} +pub trait IFrameFocusControl_Impl: windows_core::IUnknownImpl { + fn Value(&self) -> windows_core::Result>; + fn SetValue(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; +} +impl IFrameFocusControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameFocusControl_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValue(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFrameFocusControl_Impl::SetValue(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Value: Value::, + SetValue: SetValue::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFrameFocusControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Value: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetValue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFrameIsoSpeedCapabilities, IFrameIsoSpeedCapabilities_Vtbl, 0x16bdff61_6df6_4ac9_b92a_9f6ecd1ad2fa); +impl windows_core::RuntimeType for IFrameIsoSpeedCapabilities { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFrameIsoSpeedCapabilities { + const NAME: &'static str = "Windows.Media.Devices.Core.IFrameIsoSpeedCapabilities"; +} +pub trait IFrameIsoSpeedCapabilities_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn Min(&self) -> windows_core::Result; + fn Max(&self) -> windows_core::Result; + fn Step(&self) -> windows_core::Result; +} +impl IFrameIsoSpeedCapabilities_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameIsoSpeedCapabilities_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Min(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameIsoSpeedCapabilities_Impl::Min(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Max(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameIsoSpeedCapabilities_Impl::Max(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Step(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameIsoSpeedCapabilities_Impl::Step(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + Min: Min::, + Max: Max::, + Step: Step::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFrameIsoSpeedCapabilities_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Min: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Max: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Step: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IFrameIsoSpeedControl, IFrameIsoSpeedControl_Vtbl, 0x1a03efed_786a_4c75_a557_7ab9a85f588c); +impl windows_core::RuntimeType for IFrameIsoSpeedControl { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IFrameIsoSpeedControl { + const NAME: &'static str = "Windows.Media.Devices.Core.IFrameIsoSpeedControl"; +} +pub trait IFrameIsoSpeedControl_Impl: windows_core::IUnknownImpl { + fn Auto(&self) -> windows_core::Result; + fn SetAuto(&self, value: bool) -> windows_core::Result<()>; + fn Value(&self) -> windows_core::Result>; + fn SetValue(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; +} +impl IFrameIsoSpeedControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Auto(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameIsoSpeedControl_Impl::Auto(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAuto(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFrameIsoSpeedControl_Impl::SetAuto(this, value).into() + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFrameIsoSpeedControl_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValue(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IFrameIsoSpeedControl_Impl::SetValue(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Auto: Auto::, + SetAuto: SetAuto::, + Value: Value::, + SetValue: SetValue::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IFrameIsoSpeedControl_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Auto: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetAuto: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub Value: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetValue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVariablePhotoSequenceController, IVariablePhotoSequenceController_Vtbl, 0x7fbff880_ed8c_43fd_a7c3_b35809e4229a); +impl windows_core::RuntimeType for IVariablePhotoSequenceController { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_MediaProperties")] +impl windows_core::RuntimeName for IVariablePhotoSequenceController { + const NAME: &'static str = "Windows.Media.Devices.Core.IVariablePhotoSequenceController"; +} +#[cfg(feature = "Media_MediaProperties")] +pub trait IVariablePhotoSequenceController_Impl: windows_core::IUnknownImpl { + fn Supported(&self) -> windows_core::Result; + fn MaxPhotosPerSecond(&self) -> windows_core::Result; + fn PhotosPerSecondLimit(&self) -> windows_core::Result; + fn SetPhotosPerSecondLimit(&self, value: f32) -> windows_core::Result<()>; + fn GetHighestConcurrentFrameRate(&self, captureProperties: windows_core::Ref<'_, super::super::MediaProperties::IMediaEncodingProperties>) -> windows_core::Result; + fn GetCurrentFrameRate(&self) -> windows_core::Result; + fn FrameCapabilities(&self) -> windows_core::Result; + fn DesiredFrameControllers(&self) -> windows_core::Result>; +} +#[cfg(feature = "Media_MediaProperties")] +impl IVariablePhotoSequenceController_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Supported(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVariablePhotoSequenceController_Impl::Supported(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxPhotosPerSecond(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVariablePhotoSequenceController_Impl::MaxPhotosPerSecond(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PhotosPerSecondLimit(this: *mut core::ffi::c_void, result__: *mut f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVariablePhotoSequenceController_Impl::PhotosPerSecondLimit(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPhotosPerSecondLimit(this: *mut core::ffi::c_void, value: f32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVariablePhotoSequenceController_Impl::SetPhotosPerSecondLimit(this, value).into() + } + } + unsafe extern "system" fn GetHighestConcurrentFrameRate(this: *mut core::ffi::c_void, captureproperties: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVariablePhotoSequenceController_Impl::GetHighestConcurrentFrameRate(this, core::mem::transmute_copy(&captureproperties)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetCurrentFrameRate(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVariablePhotoSequenceController_Impl::GetCurrentFrameRate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FrameCapabilities(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVariablePhotoSequenceController_Impl::FrameCapabilities(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DesiredFrameControllers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVariablePhotoSequenceController_Impl::DesiredFrameControllers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Supported: Supported::, + MaxPhotosPerSecond: MaxPhotosPerSecond::, + PhotosPerSecondLimit: PhotosPerSecondLimit::, + SetPhotosPerSecondLimit: SetPhotosPerSecondLimit::, + GetHighestConcurrentFrameRate: GetHighestConcurrentFrameRate::, + GetCurrentFrameRate: GetCurrentFrameRate::, + FrameCapabilities: FrameCapabilities::, + DesiredFrameControllers: DesiredFrameControllers::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVariablePhotoSequenceController_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Supported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub MaxPhotosPerSecond: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub PhotosPerSecondLimit: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f32) -> windows_core::HRESULT, + pub SetPhotosPerSecondLimit: unsafe extern "system" fn(*mut core::ffi::c_void, f32) -> windows_core::HRESULT, + #[cfg(feature = "Media_MediaProperties")] + pub GetHighestConcurrentFrameRate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + GetHighestConcurrentFrameRate: usize, + #[cfg(feature = "Media_MediaProperties")] + pub GetCurrentFrameRate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_MediaProperties"))] + GetCurrentFrameRate: usize, + pub FrameCapabilities: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub DesiredFrameControllers: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VariablePhotoSequenceController(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(VariablePhotoSequenceController, windows_core::IUnknown, windows_core::IInspectable); +impl VariablePhotoSequenceController { + pub fn Supported(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Supported)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MaxPhotosPerSecond(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxPhotosPerSecond)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PhotosPerSecondLimit(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PhotosPerSecondLimit)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetPhotosPerSecondLimit(&self, value: f32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPhotosPerSecondLimit)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Media_MediaProperties")] + pub fn GetHighestConcurrentFrameRate(&self, captureproperties: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetHighestConcurrentFrameRate)(windows_core::Interface::as_raw(this), captureproperties.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Media_MediaProperties")] + pub fn GetCurrentFrameRate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentFrameRate)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn FrameCapabilities(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FrameCapabilities)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DesiredFrameControllers(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DesiredFrameControllers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for VariablePhotoSequenceController { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for VariablePhotoSequenceController { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for VariablePhotoSequenceController { + const NAME: &'static str = "Windows.Media.Devices.Core.VariablePhotoSequenceController"; +} +} +} +#[cfg(feature = "Media_Effects")] +pub mod Effects{ +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AcousticEchoCancellationConfiguration(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AcousticEchoCancellationConfiguration, windows_core::IUnknown, windows_core::IInspectable); +impl AcousticEchoCancellationConfiguration { + pub fn SetEchoCancellationRenderEndpoint(&self, deviceid: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetEchoCancellationRenderEndpoint)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(deviceid)).ok() } + } +} +impl windows_core::RuntimeType for AcousticEchoCancellationConfiguration { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AcousticEchoCancellationConfiguration { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AcousticEchoCancellationConfiguration { + const NAME: &'static str = "Windows.Media.Effects.AcousticEchoCancellationConfiguration"; +} +unsafe impl Send for AcousticEchoCancellationConfiguration {} +unsafe impl Sync for AcousticEchoCancellationConfiguration {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AudioCaptureEffectsManager(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AudioCaptureEffectsManager, windows_core::IUnknown, windows_core::IInspectable); +impl AudioCaptureEffectsManager { + pub fn AudioCaptureEffectsChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AudioCaptureEffectsChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveAudioCaptureEffectsChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveAudioCaptureEffectsChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn GetAudioCaptureEffects(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAudioCaptureEffects)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for AudioCaptureEffectsManager { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AudioCaptureEffectsManager { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AudioCaptureEffectsManager { + const NAME: &'static str = "Windows.Media.Effects.AudioCaptureEffectsManager"; +} +unsafe impl Send for AudioCaptureEffectsManager {} +unsafe impl Sync for AudioCaptureEffectsManager {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AudioEffect(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AudioEffect, windows_core::IUnknown, windows_core::IInspectable); +impl AudioEffect { + pub fn AudioEffectType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AudioEffectType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AcousticEchoCancellationConfiguration(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AcousticEchoCancellationConfiguration)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CanSetState(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanSetState)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn State(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).State)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetState(&self, newstate: AudioEffectState) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetState)(windows_core::Interface::as_raw(this), newstate).ok() } + } +} +impl windows_core::RuntimeType for AudioEffect { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AudioEffect { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AudioEffect { + const NAME: &'static str = "Windows.Media.Effects.AudioEffect"; +} +unsafe impl Send for AudioEffect {} +unsafe impl Sync for AudioEffect {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct AudioEffectState(pub i32); +impl AudioEffectState { + pub const Off: Self = Self(0i32); + pub const On: Self = Self(1i32); +} +impl windows_core::TypeKind for AudioEffectState { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for AudioEffectState { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Effects.AudioEffectState;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct AudioEffectType(pub i32); +impl AudioEffectType { + pub const Other: Self = Self(0i32); + pub const AcousticEchoCancellation: Self = Self(1i32); + pub const NoiseSuppression: Self = Self(2i32); + pub const AutomaticGainControl: Self = Self(3i32); + pub const BeamForming: Self = Self(4i32); + pub const ConstantToneRemoval: Self = Self(5i32); + pub const Equalizer: Self = Self(6i32); + pub const LoudnessEqualizer: Self = Self(7i32); + pub const BassBoost: Self = Self(8i32); + pub const VirtualSurround: Self = Self(9i32); + pub const VirtualHeadphones: Self = Self(10i32); + pub const SpeakerFill: Self = Self(11i32); + pub const RoomCorrection: Self = Self(12i32); + pub const BassManagement: Self = Self(13i32); + pub const EnvironmentalEffects: Self = Self(14i32); + pub const SpeakerProtection: Self = Self(15i32); + pub const SpeakerCompensation: Self = Self(16i32); + pub const DynamicRangeCompression: Self = Self(17i32); + pub const FarFieldBeamForming: Self = Self(18i32); + pub const DeepNoiseSuppression: Self = Self(19i32); +} +impl windows_core::TypeKind for AudioEffectType { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for AudioEffectType { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Effects.AudioEffectType;i4)"); +} +windows_core::imp::define_interface!(IAcousticEchoCancellationConfiguration, IAcousticEchoCancellationConfiguration_Vtbl, 0x587e735b_175b_5177_a407_2e33bafe33a5); +impl windows_core::RuntimeType for IAcousticEchoCancellationConfiguration { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAcousticEchoCancellationConfiguration { + const NAME: &'static str = "Windows.Media.Effects.IAcousticEchoCancellationConfiguration"; +} +pub trait IAcousticEchoCancellationConfiguration_Impl: windows_core::IUnknownImpl { + fn SetEchoCancellationRenderEndpoint(&self, deviceId: &windows_core::HSTRING) -> windows_core::Result<()>; +} +impl IAcousticEchoCancellationConfiguration_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetEchoCancellationRenderEndpoint(this: *mut core::ffi::c_void, deviceid: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAcousticEchoCancellationConfiguration_Impl::SetEchoCancellationRenderEndpoint(this, core::mem::transmute(&deviceid)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetEchoCancellationRenderEndpoint: SetEchoCancellationRenderEndpoint::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAcousticEchoCancellationConfiguration_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SetEchoCancellationRenderEndpoint: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAudioCaptureEffectsManager, IAudioCaptureEffectsManager_Vtbl, 0x8f85c271_038d_4393_8298_540110608eef); +impl windows_core::RuntimeType for IAudioCaptureEffectsManager { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAudioCaptureEffectsManager { + const NAME: &'static str = "Windows.Media.Effects.IAudioCaptureEffectsManager"; +} +pub trait IAudioCaptureEffectsManager_Impl: windows_core::IUnknownImpl { + fn AudioCaptureEffectsChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveAudioCaptureEffectsChanged(&self, token: i64) -> windows_core::Result<()>; + fn GetAudioCaptureEffects(&self) -> windows_core::Result>; +} +impl IAudioCaptureEffectsManager_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AudioCaptureEffectsChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioCaptureEffectsManager_Impl::AudioCaptureEffectsChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveAudioCaptureEffectsChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAudioCaptureEffectsManager_Impl::RemoveAudioCaptureEffectsChanged(this, token).into() + } + } + unsafe extern "system" fn GetAudioCaptureEffects(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioCaptureEffectsManager_Impl::GetAudioCaptureEffects(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AudioCaptureEffectsChanged: AudioCaptureEffectsChanged::, + RemoveAudioCaptureEffectsChanged: RemoveAudioCaptureEffectsChanged::, + GetAudioCaptureEffects: GetAudioCaptureEffects::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAudioCaptureEffectsManager_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AudioCaptureEffectsChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveAudioCaptureEffectsChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub GetAudioCaptureEffects: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAudioEffect, IAudioEffect_Vtbl, 0x34aafa51_9207_4055_be93_6e5734a86ae4); +impl windows_core::RuntimeType for IAudioEffect { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAudioEffect { + const NAME: &'static str = "Windows.Media.Effects.IAudioEffect"; +} +pub trait IAudioEffect_Impl: windows_core::IUnknownImpl { + fn AudioEffectType(&self) -> windows_core::Result; +} +impl IAudioEffect_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AudioEffectType(this: *mut core::ffi::c_void, result__: *mut AudioEffectType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEffect_Impl::AudioEffectType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), AudioEffectType: AudioEffectType:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAudioEffect_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AudioEffectType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut AudioEffectType) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAudioEffect2, IAudioEffect2_Vtbl, 0x06703cb0_757e_5757_8af0_6ba58a8b2990); +impl windows_core::RuntimeType for IAudioEffect2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAudioEffect2 { + const NAME: &'static str = "Windows.Media.Effects.IAudioEffect2"; +} +pub trait IAudioEffect2_Impl: windows_core::IUnknownImpl { + fn AcousticEchoCancellationConfiguration(&self) -> windows_core::Result; + fn CanSetState(&self) -> windows_core::Result; + fn State(&self) -> windows_core::Result; + fn SetState(&self, newState: AudioEffectState) -> windows_core::Result<()>; +} +impl IAudioEffect2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AcousticEchoCancellationConfiguration(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEffect2_Impl::AcousticEchoCancellationConfiguration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CanSetState(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEffect2_Impl::CanSetState(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn State(this: *mut core::ffi::c_void, result__: *mut AudioEffectState) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEffect2_Impl::State(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetState(this: *mut core::ffi::c_void, newstate: AudioEffectState) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAudioEffect2_Impl::SetState(this, newstate).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AcousticEchoCancellationConfiguration: AcousticEchoCancellationConfiguration::, + CanSetState: CanSetState::, + State: State::, + SetState: SetState::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAudioEffect2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AcousticEchoCancellationConfiguration: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CanSetState: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub State: unsafe extern "system" fn(*mut core::ffi::c_void, *mut AudioEffectState) -> windows_core::HRESULT, + pub SetState: unsafe extern "system" fn(*mut core::ffi::c_void, AudioEffectState) -> windows_core::HRESULT, +} +} +#[cfg(feature = "Media_MediaProperties")] +pub mod MediaProperties{ +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AudioEncodingProperties(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AudioEncodingProperties, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(AudioEncodingProperties, IMediaEncodingProperties); +impl AudioEncodingProperties { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn SetBitrate(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetBitrate)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Bitrate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Bitrate)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetChannelCount(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetChannelCount)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ChannelCount(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ChannelCount)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetSampleRate(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSampleRate)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn SampleRate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SampleRate)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetBitsPerSample(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetBitsPerSample)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn BitsPerSample(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BitsPerSample)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsSpatial(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsSpatial)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Copy(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Copy)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateAac(samplerate: u32, channelcount: u32, bitrate: u32) -> windows_core::Result { + Self::IAudioEncodingPropertiesStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateAac)(windows_core::Interface::as_raw(this), samplerate, channelcount, bitrate, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateAacAdts(samplerate: u32, channelcount: u32, bitrate: u32) -> windows_core::Result { + Self::IAudioEncodingPropertiesStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateAacAdts)(windows_core::Interface::as_raw(this), samplerate, channelcount, bitrate, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateMp3(samplerate: u32, channelcount: u32, bitrate: u32) -> windows_core::Result { + Self::IAudioEncodingPropertiesStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateMp3)(windows_core::Interface::as_raw(this), samplerate, channelcount, bitrate, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreatePcm(samplerate: u32, channelcount: u32, bitspersample: u32) -> windows_core::Result { + Self::IAudioEncodingPropertiesStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreatePcm)(windows_core::Interface::as_raw(this), samplerate, channelcount, bitspersample, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateWma(samplerate: u32, channelcount: u32, bitrate: u32) -> windows_core::Result { + Self::IAudioEncodingPropertiesStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWma)(windows_core::Interface::as_raw(this), samplerate, channelcount, bitrate, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateAlac(samplerate: u32, channelcount: u32, bitspersample: u32) -> windows_core::Result { + Self::IAudioEncodingPropertiesStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateAlac)(windows_core::Interface::as_raw(this), samplerate, channelcount, bitspersample, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFlac(samplerate: u32, channelcount: u32, bitspersample: u32) -> windows_core::Result { + Self::IAudioEncodingPropertiesStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFlac)(windows_core::Interface::as_raw(this), samplerate, channelcount, bitspersample, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn SetFormatUserData(&self, value: &[u8]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetFormatUserData)(windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr()).ok() } + } + pub fn GetFormatUserData(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetFormatUserData)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn Properties(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetSubtype(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetSubtype)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Subtype(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Subtype)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + fn IAudioEncodingPropertiesStatics windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn IAudioEncodingPropertiesStatics2 windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for AudioEncodingProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AudioEncodingProperties { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AudioEncodingProperties { + const NAME: &'static str = "Windows.Media.MediaProperties.AudioEncodingProperties"; +} +unsafe impl Send for AudioEncodingProperties {} +unsafe impl Sync for AudioEncodingProperties {} +windows_core::imp::define_interface!(IAudioEncodingProperties, IAudioEncodingProperties_Vtbl, 0x62bc7a16_005c_4b3b_8a0b_0a090e9687f3); +impl windows_core::RuntimeType for IAudioEncodingProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAudioEncodingProperties { + const NAME: &'static str = "Windows.Media.MediaProperties.IAudioEncodingProperties"; +} +pub trait IAudioEncodingProperties_Impl: IMediaEncodingProperties_Impl { + fn SetBitrate(&self, value: u32) -> windows_core::Result<()>; + fn Bitrate(&self) -> windows_core::Result; + fn SetChannelCount(&self, value: u32) -> windows_core::Result<()>; + fn ChannelCount(&self) -> windows_core::Result; + fn SetSampleRate(&self, value: u32) -> windows_core::Result<()>; + fn SampleRate(&self) -> windows_core::Result; + fn SetBitsPerSample(&self, value: u32) -> windows_core::Result<()>; + fn BitsPerSample(&self) -> windows_core::Result; +} +impl IAudioEncodingProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetBitrate(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAudioEncodingProperties_Impl::SetBitrate(this, value).into() + } + } + unsafe extern "system" fn Bitrate(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEncodingProperties_Impl::Bitrate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetChannelCount(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAudioEncodingProperties_Impl::SetChannelCount(this, value).into() + } + } + unsafe extern "system" fn ChannelCount(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEncodingProperties_Impl::ChannelCount(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetSampleRate(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAudioEncodingProperties_Impl::SetSampleRate(this, value).into() + } + } + unsafe extern "system" fn SampleRate(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEncodingProperties_Impl::SampleRate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetBitsPerSample(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAudioEncodingProperties_Impl::SetBitsPerSample(this, value).into() + } + } + unsafe extern "system" fn BitsPerSample(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEncodingProperties_Impl::BitsPerSample(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetBitrate: SetBitrate::, + Bitrate: Bitrate::, + SetChannelCount: SetChannelCount::, + ChannelCount: ChannelCount::, + SetSampleRate: SetSampleRate::, + SampleRate: SampleRate::, + SetBitsPerSample: SetBitsPerSample::, + BitsPerSample: BitsPerSample::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAudioEncodingProperties_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SetBitrate: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub Bitrate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetChannelCount: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub ChannelCount: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetSampleRate: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub SampleRate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetBitsPerSample: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub BitsPerSample: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAudioEncodingProperties2, IAudioEncodingProperties2_Vtbl, 0xc45d54da_80bd_4c23_80d5_72d4a181e894); +impl windows_core::RuntimeType for IAudioEncodingProperties2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAudioEncodingProperties2 { + const NAME: &'static str = "Windows.Media.MediaProperties.IAudioEncodingProperties2"; +} +pub trait IAudioEncodingProperties2_Impl: windows_core::IUnknownImpl { + fn IsSpatial(&self) -> windows_core::Result; +} +impl IAudioEncodingProperties2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsSpatial(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEncodingProperties2_Impl::IsSpatial(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), IsSpatial: IsSpatial:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAudioEncodingProperties2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsSpatial: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAudioEncodingProperties3, IAudioEncodingProperties3_Vtbl, 0x87600341_748c_4f8d_b0fd_10caf08ff087); +impl windows_core::RuntimeType for IAudioEncodingProperties3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAudioEncodingProperties3 { + const NAME: &'static str = "Windows.Media.MediaProperties.IAudioEncodingProperties3"; +} +pub trait IAudioEncodingProperties3_Impl: windows_core::IUnknownImpl { + fn Copy(&self) -> windows_core::Result; +} +impl IAudioEncodingProperties3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Copy(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEncodingProperties3_Impl::Copy(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Copy: Copy:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAudioEncodingProperties3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Copy: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAudioEncodingPropertiesStatics, IAudioEncodingPropertiesStatics_Vtbl, 0x0cad332c_ebe9_4527_b36d_e42a13cf38db); +impl windows_core::RuntimeType for IAudioEncodingPropertiesStatics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAudioEncodingPropertiesStatics { + const NAME: &'static str = "Windows.Media.MediaProperties.IAudioEncodingPropertiesStatics"; +} +pub trait IAudioEncodingPropertiesStatics_Impl: windows_core::IUnknownImpl { + fn CreateAac(&self, sampleRate: u32, channelCount: u32, bitrate: u32) -> windows_core::Result; + fn CreateAacAdts(&self, sampleRate: u32, channelCount: u32, bitrate: u32) -> windows_core::Result; + fn CreateMp3(&self, sampleRate: u32, channelCount: u32, bitrate: u32) -> windows_core::Result; + fn CreatePcm(&self, sampleRate: u32, channelCount: u32, bitsPerSample: u32) -> windows_core::Result; + fn CreateWma(&self, sampleRate: u32, channelCount: u32, bitrate: u32) -> windows_core::Result; +} +impl IAudioEncodingPropertiesStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateAac(this: *mut core::ffi::c_void, samplerate: u32, channelcount: u32, bitrate: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEncodingPropertiesStatics_Impl::CreateAac(this, samplerate, channelcount, bitrate) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateAacAdts(this: *mut core::ffi::c_void, samplerate: u32, channelcount: u32, bitrate: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEncodingPropertiesStatics_Impl::CreateAacAdts(this, samplerate, channelcount, bitrate) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateMp3(this: *mut core::ffi::c_void, samplerate: u32, channelcount: u32, bitrate: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEncodingPropertiesStatics_Impl::CreateMp3(this, samplerate, channelcount, bitrate) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreatePcm(this: *mut core::ffi::c_void, samplerate: u32, channelcount: u32, bitspersample: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEncodingPropertiesStatics_Impl::CreatePcm(this, samplerate, channelcount, bitspersample) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateWma(this: *mut core::ffi::c_void, samplerate: u32, channelcount: u32, bitrate: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEncodingPropertiesStatics_Impl::CreateWma(this, samplerate, channelcount, bitrate) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateAac: CreateAac::, + CreateAacAdts: CreateAacAdts::, + CreateMp3: CreateMp3::, + CreatePcm: CreatePcm::, + CreateWma: CreateWma::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAudioEncodingPropertiesStatics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub CreateAac: unsafe extern "system" fn(*mut core::ffi::c_void, u32, u32, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateAacAdts: unsafe extern "system" fn(*mut core::ffi::c_void, u32, u32, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateMp3: unsafe extern "system" fn(*mut core::ffi::c_void, u32, u32, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreatePcm: unsafe extern "system" fn(*mut core::ffi::c_void, u32, u32, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateWma: unsafe extern "system" fn(*mut core::ffi::c_void, u32, u32, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAudioEncodingPropertiesStatics2, IAudioEncodingPropertiesStatics2_Vtbl, 0x7489316f_77a0_433d_8ed5_4040280e8665); +impl windows_core::RuntimeType for IAudioEncodingPropertiesStatics2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAudioEncodingPropertiesStatics2 { + const NAME: &'static str = "Windows.Media.MediaProperties.IAudioEncodingPropertiesStatics2"; +} +pub trait IAudioEncodingPropertiesStatics2_Impl: windows_core::IUnknownImpl { + fn CreateAlac(&self, sampleRate: u32, channelCount: u32, bitsPerSample: u32) -> windows_core::Result; + fn CreateFlac(&self, sampleRate: u32, channelCount: u32, bitsPerSample: u32) -> windows_core::Result; +} +impl IAudioEncodingPropertiesStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateAlac(this: *mut core::ffi::c_void, samplerate: u32, channelcount: u32, bitspersample: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEncodingPropertiesStatics2_Impl::CreateAlac(this, samplerate, channelcount, bitspersample) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFlac(this: *mut core::ffi::c_void, samplerate: u32, channelcount: u32, bitspersample: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAudioEncodingPropertiesStatics2_Impl::CreateFlac(this, samplerate, channelcount, bitspersample) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateAlac: CreateAlac::, + CreateFlac: CreateFlac::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAudioEncodingPropertiesStatics2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub CreateAlac: unsafe extern "system" fn(*mut core::ffi::c_void, u32, u32, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateFlac: unsafe extern "system" fn(*mut core::ffi::c_void, u32, u32, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAudioEncodingPropertiesWithFormatUserData, IAudioEncodingPropertiesWithFormatUserData_Vtbl, 0x98f10d79_13ea_49ff_be70_2673db69702c); +impl windows_core::RuntimeType for IAudioEncodingPropertiesWithFormatUserData { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAudioEncodingPropertiesWithFormatUserData { + const NAME: &'static str = "Windows.Media.MediaProperties.IAudioEncodingPropertiesWithFormatUserData"; +} +pub trait IAudioEncodingPropertiesWithFormatUserData_Impl: windows_core::IUnknownImpl { + fn SetFormatUserData(&self, value: &[u8]) -> windows_core::Result<()>; + fn GetFormatUserData(&self, value: &mut windows_core::Array) -> windows_core::Result<()>; +} +impl IAudioEncodingPropertiesWithFormatUserData_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetFormatUserData(this: *mut core::ffi::c_void, value_array_size: u32, value: *const u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAudioEncodingPropertiesWithFormatUserData_Impl::SetFormatUserData(this, core::slice::from_raw_parts(core::mem::transmute_copy(&value), value_array_size as usize)).into() + } + } + unsafe extern "system" fn GetFormatUserData(this: *mut core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAudioEncodingPropertiesWithFormatUserData_Impl::GetFormatUserData(this, &mut windows_core::imp::array_proxy(core::mem::transmute_copy(&value), value_array_size)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetFormatUserData: SetFormatUserData::, + GetFormatUserData: GetFormatUserData::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAudioEncodingPropertiesWithFormatUserData_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SetFormatUserData: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const u8) -> windows_core::HRESULT, + pub GetFormatUserData: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32, *mut *mut u8) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaEncodingProperties, IMediaEncodingProperties_Vtbl, 0xb4002af6_acd4_4e5a_a24b_5d7498a8b8c4); +impl windows_core::RuntimeType for IMediaEncodingProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IMediaEncodingProperties, windows_core::IUnknown, windows_core::IInspectable); +impl IMediaEncodingProperties { + pub fn Properties(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetSubtype(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSubtype)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Subtype(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Subtype)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} +impl windows_core::RuntimeName for IMediaEncodingProperties { + const NAME: &'static str = "Windows.Media.MediaProperties.IMediaEncodingProperties"; +} +pub trait IMediaEncodingProperties_Impl: windows_core::IUnknownImpl { + fn Properties(&self) -> windows_core::Result; + fn Type(&self) -> windows_core::Result; + fn SetSubtype(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Subtype(&self) -> windows_core::Result; +} +impl IMediaEncodingProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaEncodingProperties_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Type(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaEncodingProperties_Impl::Type(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetSubtype(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaEncodingProperties_Impl::SetSubtype(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Subtype(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaEncodingProperties_Impl::Subtype(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Properties: Properties::, + Type: Type::, + SetSubtype: SetSubtype::, + Subtype: Subtype::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaEncodingProperties_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Properties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Type: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetSubtype: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Subtype: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaRatio, IMediaRatio_Vtbl, 0xd2d0fee5_8929_401d_ac78_7d357e378163); +impl windows_core::RuntimeType for IMediaRatio { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaRatio { + const NAME: &'static str = "Windows.Media.MediaProperties.IMediaRatio"; +} +pub trait IMediaRatio_Impl: windows_core::IUnknownImpl { + fn SetNumerator(&self, value: u32) -> windows_core::Result<()>; + fn Numerator(&self) -> windows_core::Result; + fn SetDenominator(&self, value: u32) -> windows_core::Result<()>; + fn Denominator(&self) -> windows_core::Result; +} +impl IMediaRatio_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetNumerator(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaRatio_Impl::SetNumerator(this, value).into() + } + } + unsafe extern "system" fn Numerator(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaRatio_Impl::Numerator(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDenominator(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaRatio_Impl::SetDenominator(this, value).into() + } + } + unsafe extern "system" fn Denominator(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaRatio_Impl::Denominator(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetNumerator: SetNumerator::, + Numerator: Numerator::, + SetDenominator: SetDenominator::, + Denominator: Denominator::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaRatio_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SetNumerator: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub Numerator: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetDenominator: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub Denominator: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoEncodingProperties, IVideoEncodingProperties_Vtbl, 0x76ee6c9a_37c2_4f2a_880a_1282bbb4373d); +impl windows_core::RuntimeType for IVideoEncodingProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoEncodingProperties { + const NAME: &'static str = "Windows.Media.MediaProperties.IVideoEncodingProperties"; +} +pub trait IVideoEncodingProperties_Impl: IMediaEncodingProperties_Impl { + fn SetBitrate(&self, value: u32) -> windows_core::Result<()>; + fn Bitrate(&self) -> windows_core::Result; + fn SetWidth(&self, value: u32) -> windows_core::Result<()>; + fn Width(&self) -> windows_core::Result; + fn SetHeight(&self, value: u32) -> windows_core::Result<()>; + fn Height(&self) -> windows_core::Result; + fn FrameRate(&self) -> windows_core::Result; + fn PixelAspectRatio(&self) -> windows_core::Result; +} +impl IVideoEncodingProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetBitrate(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVideoEncodingProperties_Impl::SetBitrate(this, value).into() + } + } + unsafe extern "system" fn Bitrate(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoEncodingProperties_Impl::Bitrate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetWidth(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVideoEncodingProperties_Impl::SetWidth(this, value).into() + } + } + unsafe extern "system" fn Width(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoEncodingProperties_Impl::Width(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetHeight(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVideoEncodingProperties_Impl::SetHeight(this, value).into() + } + } + unsafe extern "system" fn Height(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoEncodingProperties_Impl::Height(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FrameRate(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoEncodingProperties_Impl::FrameRate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PixelAspectRatio(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoEncodingProperties_Impl::PixelAspectRatio(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetBitrate: SetBitrate::, + Bitrate: Bitrate::, + SetWidth: SetWidth::, + Width: Width::, + SetHeight: SetHeight::, + Height: Height::, + FrameRate: FrameRate::, + PixelAspectRatio: PixelAspectRatio::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoEncodingProperties_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SetBitrate: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub Bitrate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetWidth: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub Width: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetHeight: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub Height: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub FrameRate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub PixelAspectRatio: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoEncodingProperties2, IVideoEncodingProperties2_Vtbl, 0xf743a1ef_d465_4290_a94b_ef0f1528f8e3); +impl windows_core::RuntimeType for IVideoEncodingProperties2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoEncodingProperties2 { + const NAME: &'static str = "Windows.Media.MediaProperties.IVideoEncodingProperties2"; +} +pub trait IVideoEncodingProperties2_Impl: windows_core::IUnknownImpl { + fn SetFormatUserData(&self, value: &[u8]) -> windows_core::Result<()>; + fn GetFormatUserData(&self, value: &mut windows_core::Array) -> windows_core::Result<()>; + fn SetProfileId(&self, value: i32) -> windows_core::Result<()>; + fn ProfileId(&self) -> windows_core::Result; +} +impl IVideoEncodingProperties2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetFormatUserData(this: *mut core::ffi::c_void, value_array_size: u32, value: *const u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVideoEncodingProperties2_Impl::SetFormatUserData(this, core::slice::from_raw_parts(core::mem::transmute_copy(&value), value_array_size as usize)).into() + } + } + unsafe extern "system" fn GetFormatUserData(this: *mut core::ffi::c_void, value_array_size: *mut u32, value: *mut *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVideoEncodingProperties2_Impl::GetFormatUserData(this, &mut windows_core::imp::array_proxy(core::mem::transmute_copy(&value), value_array_size)).into() + } + } + unsafe extern "system" fn SetProfileId(this: *mut core::ffi::c_void, value: i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVideoEncodingProperties2_Impl::SetProfileId(this, value).into() + } + } + unsafe extern "system" fn ProfileId(this: *mut core::ffi::c_void, result__: *mut i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoEncodingProperties2_Impl::ProfileId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetFormatUserData: SetFormatUserData::, + GetFormatUserData: GetFormatUserData::, + SetProfileId: SetProfileId::, + ProfileId: ProfileId::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoEncodingProperties2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SetFormatUserData: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const u8) -> windows_core::HRESULT, + pub GetFormatUserData: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32, *mut *mut u8) -> windows_core::HRESULT, + pub SetProfileId: unsafe extern "system" fn(*mut core::ffi::c_void, i32) -> windows_core::HRESULT, + pub ProfileId: unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoEncodingProperties3, IVideoEncodingProperties3_Vtbl, 0x386bcdc4_873a_479f_b3eb_56c1fcbec6d7); +impl windows_core::RuntimeType for IVideoEncodingProperties3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoEncodingProperties3 { + const NAME: &'static str = "Windows.Media.MediaProperties.IVideoEncodingProperties3"; +} +pub trait IVideoEncodingProperties3_Impl: windows_core::IUnknownImpl { + fn StereoscopicVideoPackingMode(&self) -> windows_core::Result; +} +impl IVideoEncodingProperties3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn StereoscopicVideoPackingMode(this: *mut core::ffi::c_void, result__: *mut StereoscopicVideoPackingMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoEncodingProperties3_Impl::StereoscopicVideoPackingMode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + StereoscopicVideoPackingMode: StereoscopicVideoPackingMode::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoEncodingProperties3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub StereoscopicVideoPackingMode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut StereoscopicVideoPackingMode) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoEncodingProperties4, IVideoEncodingProperties4_Vtbl, 0x724ef014_c10c_40f2_9d72_3ee13b45fa8e); +impl windows_core::RuntimeType for IVideoEncodingProperties4 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoEncodingProperties4 { + const NAME: &'static str = "Windows.Media.MediaProperties.IVideoEncodingProperties4"; +} +pub trait IVideoEncodingProperties4_Impl: windows_core::IUnknownImpl { + fn SphericalVideoFrameFormat(&self) -> windows_core::Result; +} +impl IVideoEncodingProperties4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SphericalVideoFrameFormat(this: *mut core::ffi::c_void, result__: *mut SphericalVideoFrameFormat) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoEncodingProperties4_Impl::SphericalVideoFrameFormat(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SphericalVideoFrameFormat: SphericalVideoFrameFormat::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoEncodingProperties4_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SphericalVideoFrameFormat: unsafe extern "system" fn(*mut core::ffi::c_void, *mut SphericalVideoFrameFormat) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoEncodingProperties5, IVideoEncodingProperties5_Vtbl, 0x4959080f_272f_4ece_a4df_c0ccdb33d840); +impl windows_core::RuntimeType for IVideoEncodingProperties5 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoEncodingProperties5 { + const NAME: &'static str = "Windows.Media.MediaProperties.IVideoEncodingProperties5"; +} +pub trait IVideoEncodingProperties5_Impl: windows_core::IUnknownImpl { + fn Copy(&self) -> windows_core::Result; +} +impl IVideoEncodingProperties5_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Copy(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoEncodingProperties5_Impl::Copy(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Copy: Copy:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoEncodingProperties5_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Copy: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoEncodingPropertiesStatics, IVideoEncodingPropertiesStatics_Vtbl, 0x3ce14d44_1dc5_43db_9f38_ebebf90152cb); +impl windows_core::RuntimeType for IVideoEncodingPropertiesStatics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoEncodingPropertiesStatics { + const NAME: &'static str = "Windows.Media.MediaProperties.IVideoEncodingPropertiesStatics"; +} +pub trait IVideoEncodingPropertiesStatics_Impl: windows_core::IUnknownImpl { + fn CreateH264(&self) -> windows_core::Result; + fn CreateMpeg2(&self) -> windows_core::Result; + fn CreateUncompressed(&self, subtype: &windows_core::HSTRING, width: u32, height: u32) -> windows_core::Result; +} +impl IVideoEncodingPropertiesStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateH264(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoEncodingPropertiesStatics_Impl::CreateH264(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateMpeg2(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoEncodingPropertiesStatics_Impl::CreateMpeg2(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateUncompressed(this: *mut core::ffi::c_void, subtype: *mut core::ffi::c_void, width: u32, height: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoEncodingPropertiesStatics_Impl::CreateUncompressed(this, core::mem::transmute(&subtype), width, height) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateH264: CreateH264::, + CreateMpeg2: CreateMpeg2::, + CreateUncompressed: CreateUncompressed::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoEncodingPropertiesStatics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub CreateH264: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateMpeg2: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateUncompressed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, u32, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoEncodingPropertiesStatics2, IVideoEncodingPropertiesStatics2_Vtbl, 0xcf1ebd5d_49fe_4d00_b59a_cfa4dfc51944); +impl windows_core::RuntimeType for IVideoEncodingPropertiesStatics2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoEncodingPropertiesStatics2 { + const NAME: &'static str = "Windows.Media.MediaProperties.IVideoEncodingPropertiesStatics2"; +} +pub trait IVideoEncodingPropertiesStatics2_Impl: windows_core::IUnknownImpl { + fn CreateHevc(&self) -> windows_core::Result; +} +impl IVideoEncodingPropertiesStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateHevc(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoEncodingPropertiesStatics2_Impl::CreateHevc(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), CreateHevc: CreateHevc:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoEncodingPropertiesStatics2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub CreateHevc: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoEncodingPropertiesStatics3, IVideoEncodingPropertiesStatics3_Vtbl, 0x65b46685_60da_5e51_91a2_b38c4763b872); +impl windows_core::RuntimeType for IVideoEncodingPropertiesStatics3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoEncodingPropertiesStatics3 { + const NAME: &'static str = "Windows.Media.MediaProperties.IVideoEncodingPropertiesStatics3"; +} +pub trait IVideoEncodingPropertiesStatics3_Impl: windows_core::IUnknownImpl { + fn CreateVp9(&self) -> windows_core::Result; + fn CreateAv1(&self) -> windows_core::Result; +} +impl IVideoEncodingPropertiesStatics3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateVp9(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoEncodingPropertiesStatics3_Impl::CreateVp9(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateAv1(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoEncodingPropertiesStatics3_Impl::CreateAv1(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateVp9: CreateVp9::, + CreateAv1: CreateAv1::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoEncodingPropertiesStatics3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub CreateVp9: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateAv1: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaPixelFormat(pub i32); +impl MediaPixelFormat { + pub const Nv12: Self = Self(0i32); + pub const Bgra8: Self = Self(1i32); + pub const P010: Self = Self(2i32); +} +impl windows_core::TypeKind for MediaPixelFormat { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaPixelFormat { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.MediaProperties.MediaPixelFormat;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaPropertySet(windows_core::IUnknown); +windows_core::imp::interface_hierarchy ! ( MediaPropertySet , windows_core::IUnknown , windows_core::IInspectable , windows_collections:: IMap < windows_core::GUID , windows_core::IInspectable > ); +windows_core::imp::required_hierarchy!(MediaPropertySet, windows_collections::IIterable>); +impl MediaPropertySet { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn First(&self) -> windows_core::Result>> { + let this = &windows_core::Interface::cast::>>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Lookup(&self, key: windows_core::GUID) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Lookup)(windows_core::Interface::as_raw(this), key, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn HasKey(&self, key: windows_core::GUID) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HasKey)(windows_core::Interface::as_raw(this), key, &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Insert(&self, key: windows_core::GUID, value: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Insert)(windows_core::Interface::as_raw(this), key, value.param().abi(), &mut result__).map(|| result__) + } + } + pub fn Remove(&self, key: windows_core::GUID) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Remove)(windows_core::Interface::as_raw(this), key).ok() } + } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } +} +impl windows_core::RuntimeType for MediaPropertySet { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::>(); +} +unsafe impl windows_core::Interface for MediaPropertySet { + type Vtable = as windows_core::Interface>::Vtable; + const IID: windows_core::GUID = as windows_core::Interface>::IID; +} +impl windows_core::RuntimeName for MediaPropertySet { + const NAME: &'static str = "Windows.Media.MediaProperties.MediaPropertySet"; +} +unsafe impl Send for MediaPropertySet {} +unsafe impl Sync for MediaPropertySet {} +impl IntoIterator for MediaPropertySet { + type Item = windows_collections::IKeyValuePair; + type IntoIter = windows_collections::IIterator; + fn into_iter(self) -> Self::IntoIter { + IntoIterator::into_iter(&self) + } +} +impl IntoIterator for &MediaPropertySet { + type Item = windows_collections::IKeyValuePair; + type IntoIter = windows_collections::IIterator; + fn into_iter(self) -> Self::IntoIter { + self.First().unwrap() + } +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaRatio(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaRatio, windows_core::IUnknown, windows_core::IInspectable); +impl MediaRatio { + pub fn SetNumerator(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetNumerator)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Numerator(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Numerator)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetDenominator(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDenominator)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Denominator(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Denominator)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for MediaRatio { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaRatio { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaRatio { + const NAME: &'static str = "Windows.Media.MediaProperties.MediaRatio"; +} +unsafe impl Send for MediaRatio {} +unsafe impl Sync for MediaRatio {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaThumbnailFormat(pub i32); +impl MediaThumbnailFormat { + pub const Bmp: Self = Self(0i32); + pub const Bgra8: Self = Self(1i32); +} +impl windows_core::TypeKind for MediaThumbnailFormat { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaThumbnailFormat { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.MediaProperties.MediaThumbnailFormat;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct SphericalVideoFrameFormat(pub i32); +impl SphericalVideoFrameFormat { + pub const None: Self = Self(0i32); + pub const Unsupported: Self = Self(1i32); + pub const Equirectangular: Self = Self(2i32); +} +impl windows_core::TypeKind for SphericalVideoFrameFormat { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for SphericalVideoFrameFormat { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.MediaProperties.SphericalVideoFrameFormat;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct StereoscopicVideoPackingMode(pub i32); +impl StereoscopicVideoPackingMode { + pub const None: Self = Self(0i32); + pub const SideBySide: Self = Self(1i32); + pub const TopBottom: Self = Self(2i32); +} +impl windows_core::TypeKind for StereoscopicVideoPackingMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for StereoscopicVideoPackingMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.MediaProperties.StereoscopicVideoPackingMode;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VideoEncodingProperties(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(VideoEncodingProperties, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(VideoEncodingProperties, IMediaEncodingProperties); +impl VideoEncodingProperties { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn Properties(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetSubtype(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetSubtype)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Subtype(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Subtype)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetBitrate(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetBitrate)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Bitrate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Bitrate)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetWidth(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetWidth)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Width(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Width)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetHeight(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetHeight)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Height(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Height)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn FrameRate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FrameRate)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PixelAspectRatio(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PixelAspectRatio)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetFormatUserData(&self, value: &[u8]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetFormatUserData)(windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr()).ok() } + } + pub fn GetFormatUserData(&self, value: &mut windows_core::Array) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).GetFormatUserData)(windows_core::Interface::as_raw(this), value.set_abi_len(), value as *mut _ as _).ok() } + } + pub fn SetProfileId(&self, value: i32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetProfileId)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ProfileId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProfileId)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn StereoscopicVideoPackingMode(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StereoscopicVideoPackingMode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SphericalVideoFrameFormat(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SphericalVideoFrameFormat)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Copy(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Copy)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateH264() -> windows_core::Result { + Self::IVideoEncodingPropertiesStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateH264)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateMpeg2() -> windows_core::Result { + Self::IVideoEncodingPropertiesStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateMpeg2)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateUncompressed(subtype: &windows_core::HSTRING, width: u32, height: u32) -> windows_core::Result { + Self::IVideoEncodingPropertiesStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateUncompressed)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(subtype), width, height, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateHevc() -> windows_core::Result { + Self::IVideoEncodingPropertiesStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateHevc)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateVp9() -> windows_core::Result { + Self::IVideoEncodingPropertiesStatics3(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateVp9)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateAv1() -> windows_core::Result { + Self::IVideoEncodingPropertiesStatics3(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateAv1)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn IVideoEncodingPropertiesStatics windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn IVideoEncodingPropertiesStatics2 windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn IVideoEncodingPropertiesStatics3 windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for VideoEncodingProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for VideoEncodingProperties { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for VideoEncodingProperties { + const NAME: &'static str = "Windows.Media.MediaProperties.VideoEncodingProperties"; +} +unsafe impl Send for VideoEncodingProperties {} +unsafe impl Sync for VideoEncodingProperties {} +} +#[cfg(feature = "Media_Playback")] +pub mod Playback{ +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct AutoLoadedDisplayPropertyKind(pub i32); +impl AutoLoadedDisplayPropertyKind { + pub const None: Self = Self(0i32); + pub const MusicOrVideo: Self = Self(1i32); + pub const Music: Self = Self(2i32); + pub const Video: Self = Self(3i32); +} +impl windows_core::TypeKind for AutoLoadedDisplayPropertyKind { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for AutoLoadedDisplayPropertyKind { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Playback.AutoLoadedDisplayPropertyKind;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct CurrentMediaPlaybackItemChangedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(CurrentMediaPlaybackItemChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl CurrentMediaPlaybackItemChangedEventArgs { + pub fn NewItem(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NewItem)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn OldItem(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OldItem)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Reason(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Reason)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for CurrentMediaPlaybackItemChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for CurrentMediaPlaybackItemChangedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for CurrentMediaPlaybackItemChangedEventArgs { + const NAME: &'static str = "Windows.Media.Playback.CurrentMediaPlaybackItemChangedEventArgs"; +} +unsafe impl Send for CurrentMediaPlaybackItemChangedEventArgs {} +unsafe impl Sync for CurrentMediaPlaybackItemChangedEventArgs {} +windows_core::imp::define_interface!(ICurrentMediaPlaybackItemChangedEventArgs, ICurrentMediaPlaybackItemChangedEventArgs_Vtbl, 0x1743a892_5c43_4a15_967a_572d2d0f26c6); +impl windows_core::RuntimeType for ICurrentMediaPlaybackItemChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ICurrentMediaPlaybackItemChangedEventArgs { + const NAME: &'static str = "Windows.Media.Playback.ICurrentMediaPlaybackItemChangedEventArgs"; +} +pub trait ICurrentMediaPlaybackItemChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn NewItem(&self) -> windows_core::Result; + fn OldItem(&self) -> windows_core::Result; +} +impl ICurrentMediaPlaybackItemChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn NewItem(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICurrentMediaPlaybackItemChangedEventArgs_Impl::NewItem(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OldItem(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICurrentMediaPlaybackItemChangedEventArgs_Impl::OldItem(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + NewItem: NewItem::, + OldItem: OldItem::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ICurrentMediaPlaybackItemChangedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub NewItem: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub OldItem: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ICurrentMediaPlaybackItemChangedEventArgs2, ICurrentMediaPlaybackItemChangedEventArgs2_Vtbl, 0x1d80a51e_996e_40a9_be48_e66ec90b2b7d); +impl windows_core::RuntimeType for ICurrentMediaPlaybackItemChangedEventArgs2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ICurrentMediaPlaybackItemChangedEventArgs2 { + const NAME: &'static str = "Windows.Media.Playback.ICurrentMediaPlaybackItemChangedEventArgs2"; +} +pub trait ICurrentMediaPlaybackItemChangedEventArgs2_Impl: ICurrentMediaPlaybackItemChangedEventArgs_Impl { + fn Reason(&self) -> windows_core::Result; +} +impl ICurrentMediaPlaybackItemChangedEventArgs2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Reason(this: *mut core::ffi::c_void, result__: *mut MediaPlaybackItemChangedReason) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICurrentMediaPlaybackItemChangedEventArgs2_Impl::Reason(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Reason: Reason::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ICurrentMediaPlaybackItemChangedEventArgs2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Reason: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaPlaybackItemChangedReason) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaBreak, IMediaBreak_Vtbl, 0x714be270_0def_4ebc_a489_6b34930e1558); +impl windows_core::RuntimeType for IMediaBreak { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Foundation_Collections")] +impl windows_core::RuntimeName for IMediaBreak { + const NAME: &'static str = "Windows.Media.Playback.IMediaBreak"; +} +#[cfg(feature = "Foundation_Collections")] +pub trait IMediaBreak_Impl: windows_core::IUnknownImpl { + fn PlaybackList(&self) -> windows_core::Result; + fn PresentationPosition(&self) -> windows_core::Result>; + fn InsertionMethod(&self) -> windows_core::Result; + fn CustomProperties(&self) -> windows_core::Result; + fn CanStart(&self) -> windows_core::Result; + fn SetCanStart(&self, value: bool) -> windows_core::Result<()>; +} +#[cfg(feature = "Foundation_Collections")] +impl IMediaBreak_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn PlaybackList(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBreak_Impl::PlaybackList(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PresentationPosition(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBreak_Impl::PresentationPosition(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn InsertionMethod(this: *mut core::ffi::c_void, result__: *mut MediaBreakInsertionMethod) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBreak_Impl::InsertionMethod(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CustomProperties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBreak_Impl::CustomProperties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CanStart(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBreak_Impl::CanStart(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetCanStart(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaBreak_Impl::SetCanStart(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + PlaybackList: PlaybackList::, + PresentationPosition: PresentationPosition::, + InsertionMethod: InsertionMethod::, + CustomProperties: CustomProperties::, + CanStart: CanStart::, + SetCanStart: SetCanStart::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaBreak_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub PlaybackList: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub PresentationPosition: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub InsertionMethod: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaBreakInsertionMethod) -> windows_core::HRESULT, + #[cfg(feature = "Foundation_Collections")] + pub CustomProperties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Foundation_Collections"))] + CustomProperties: usize, + pub CanStart: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetCanStart: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaBreakFactory, IMediaBreakFactory_Vtbl, 0x4516e002_18e0_4079_8b5f_d33495c15d2e); +impl windows_core::RuntimeType for IMediaBreakFactory { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaBreakFactory { + const NAME: &'static str = "Windows.Media.Playback.IMediaBreakFactory"; +} +pub trait IMediaBreakFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, insertionMethod: MediaBreakInsertionMethod) -> windows_core::Result; + fn CreateWithPresentationPosition(&self, insertionMethod: MediaBreakInsertionMethod, presentationPosition: &super::super::Foundation::TimeSpan) -> windows_core::Result; +} +impl IMediaBreakFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, insertionmethod: MediaBreakInsertionMethod, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBreakFactory_Impl::Create(this, insertionmethod) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateWithPresentationPosition(this: *mut core::ffi::c_void, insertionmethod: MediaBreakInsertionMethod, presentationposition: super::super::Foundation::TimeSpan, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBreakFactory_Impl::CreateWithPresentationPosition(this, insertionmethod, core::mem::transmute(&presentationposition)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Create: Create::, + CreateWithPresentationPosition: CreateWithPresentationPosition::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaBreakFactory_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Create: unsafe extern "system" fn(*mut core::ffi::c_void, MediaBreakInsertionMethod, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateWithPresentationPosition: unsafe extern "system" fn(*mut core::ffi::c_void, MediaBreakInsertionMethod, super::super::Foundation::TimeSpan, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaBreakSchedule, IMediaBreakSchedule_Vtbl, 0xa19a5813_98b6_41d8_83da_f971d22b7bba); +impl windows_core::RuntimeType for IMediaBreakSchedule { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaBreakSchedule { + const NAME: &'static str = "Windows.Media.Playback.IMediaBreakSchedule"; +} +pub trait IMediaBreakSchedule_Impl: windows_core::IUnknownImpl { + fn ScheduleChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveScheduleChanged(&self, token: i64) -> windows_core::Result<()>; + fn InsertMidrollBreak(&self, mediaBreak: windows_core::Ref<'_, MediaBreak>) -> windows_core::Result<()>; + fn RemoveMidrollBreak(&self, mediaBreak: windows_core::Ref<'_, MediaBreak>) -> windows_core::Result<()>; + fn MidrollBreaks(&self) -> windows_core::Result>; + fn SetPrerollBreak(&self, value: windows_core::Ref<'_, MediaBreak>) -> windows_core::Result<()>; + fn PrerollBreak(&self) -> windows_core::Result; + fn SetPostrollBreak(&self, value: windows_core::Ref<'_, MediaBreak>) -> windows_core::Result<()>; + fn PostrollBreak(&self) -> windows_core::Result; + fn PlaybackItem(&self) -> windows_core::Result; +} +impl IMediaBreakSchedule_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ScheduleChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBreakSchedule_Impl::ScheduleChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveScheduleChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaBreakSchedule_Impl::RemoveScheduleChanged(this, token).into() + } + } + unsafe extern "system" fn InsertMidrollBreak(this: *mut core::ffi::c_void, mediabreak: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaBreakSchedule_Impl::InsertMidrollBreak(this, core::mem::transmute_copy(&mediabreak)).into() + } + } + unsafe extern "system" fn RemoveMidrollBreak(this: *mut core::ffi::c_void, mediabreak: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaBreakSchedule_Impl::RemoveMidrollBreak(this, core::mem::transmute_copy(&mediabreak)).into() + } + } + unsafe extern "system" fn MidrollBreaks(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBreakSchedule_Impl::MidrollBreaks(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPrerollBreak(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaBreakSchedule_Impl::SetPrerollBreak(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn PrerollBreak(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBreakSchedule_Impl::PrerollBreak(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPostrollBreak(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaBreakSchedule_Impl::SetPostrollBreak(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn PostrollBreak(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBreakSchedule_Impl::PostrollBreak(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PlaybackItem(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaBreakSchedule_Impl::PlaybackItem(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ScheduleChanged: ScheduleChanged::, + RemoveScheduleChanged: RemoveScheduleChanged::, + InsertMidrollBreak: InsertMidrollBreak::, + RemoveMidrollBreak: RemoveMidrollBreak::, + MidrollBreaks: MidrollBreaks::, + SetPrerollBreak: SetPrerollBreak::, + PrerollBreak: PrerollBreak::, + SetPostrollBreak: SetPostrollBreak::, + PostrollBreak: PostrollBreak::, + PlaybackItem: PlaybackItem::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaBreakSchedule_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ScheduleChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveScheduleChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub InsertMidrollBreak: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub RemoveMidrollBreak: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub MidrollBreaks: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetPrerollBreak: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub PrerollBreak: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetPostrollBreak: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub PostrollBreak: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub PlaybackItem: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaItemDisplayProperties, IMediaItemDisplayProperties_Vtbl, 0x1e3c1b48_7097_4384_a217_c1291dfa8c16); +impl windows_core::RuntimeType for IMediaItemDisplayProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IMediaItemDisplayProperties { + const NAME: &'static str = "Windows.Media.Playback.IMediaItemDisplayProperties"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IMediaItemDisplayProperties_Impl: windows_core::IUnknownImpl { + fn Type(&self) -> windows_core::Result; + fn SetType(&self, value: super::MediaPlaybackType) -> windows_core::Result<()>; + fn MusicProperties(&self) -> windows_core::Result; + fn VideoProperties(&self) -> windows_core::Result; + fn Thumbnail(&self) -> windows_core::Result; + fn SetThumbnail(&self, value: windows_core::Ref<'_, super::super::Storage::Streams::RandomAccessStreamReference>) -> windows_core::Result<()>; + fn ClearAll(&self) -> windows_core::Result<()>; +} +#[cfg(feature = "Storage_Streams")] +impl IMediaItemDisplayProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Type(this: *mut core::ffi::c_void, result__: *mut super::MediaPlaybackType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaItemDisplayProperties_Impl::Type(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetType(this: *mut core::ffi::c_void, value: super::MediaPlaybackType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaItemDisplayProperties_Impl::SetType(this, value).into() + } + } + unsafe extern "system" fn MusicProperties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaItemDisplayProperties_Impl::MusicProperties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn VideoProperties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaItemDisplayProperties_Impl::VideoProperties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Thumbnail(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaItemDisplayProperties_Impl::Thumbnail(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetThumbnail(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaItemDisplayProperties_Impl::SetThumbnail(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn ClearAll(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaItemDisplayProperties_Impl::ClearAll(this).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Type: Type::, + SetType: SetType::, + MusicProperties: MusicProperties::, + VideoProperties: VideoProperties::, + Thumbnail: Thumbnail::, + SetThumbnail: SetThumbnail::, + ClearAll: ClearAll::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaItemDisplayProperties_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Type: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::MediaPlaybackType) -> windows_core::HRESULT, + pub SetType: unsafe extern "system" fn(*mut core::ffi::c_void, super::MediaPlaybackType) -> windows_core::HRESULT, + pub MusicProperties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub VideoProperties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Storage_Streams")] + pub Thumbnail: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + Thumbnail: usize, + #[cfg(feature = "Storage_Streams")] + pub SetThumbnail: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + SetThumbnail: usize, + pub ClearAll: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaPlaybackItem, IMediaPlaybackItem_Vtbl, 0x047097d2_e4af_48ab_b283_6929e674ece2); +impl windows_core::RuntimeType for IMediaPlaybackItem { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Core"))] +impl windows_core::RuntimeName for IMediaPlaybackItem { + const NAME: &'static str = "Windows.Media.Playback.IMediaPlaybackItem"; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Core"))] +pub trait IMediaPlaybackItem_Impl: IMediaPlaybackSource_Impl { + fn AudioTracksChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveAudioTracksChanged(&self, token: i64) -> windows_core::Result<()>; + fn VideoTracksChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveVideoTracksChanged(&self, token: i64) -> windows_core::Result<()>; + fn TimedMetadataTracksChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveTimedMetadataTracksChanged(&self, token: i64) -> windows_core::Result<()>; + fn Source(&self) -> windows_core::Result; + fn AudioTracks(&self) -> windows_core::Result; + fn VideoTracks(&self) -> windows_core::Result; + fn TimedMetadataTracks(&self) -> windows_core::Result; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Core"))] +impl IMediaPlaybackItem_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AudioTracksChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItem_Impl::AudioTracksChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveAudioTracksChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackItem_Impl::RemoveAudioTracksChanged(this, token).into() + } + } + unsafe extern "system" fn VideoTracksChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItem_Impl::VideoTracksChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveVideoTracksChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackItem_Impl::RemoveVideoTracksChanged(this, token).into() + } + } + unsafe extern "system" fn TimedMetadataTracksChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItem_Impl::TimedMetadataTracksChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveTimedMetadataTracksChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackItem_Impl::RemoveTimedMetadataTracksChanged(this, token).into() + } + } + unsafe extern "system" fn Source(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItem_Impl::Source(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AudioTracks(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItem_Impl::AudioTracks(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn VideoTracks(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItem_Impl::VideoTracks(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TimedMetadataTracks(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItem_Impl::TimedMetadataTracks(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AudioTracksChanged: AudioTracksChanged::, + RemoveAudioTracksChanged: RemoveAudioTracksChanged::, + VideoTracksChanged: VideoTracksChanged::, + RemoveVideoTracksChanged: RemoveVideoTracksChanged::, + TimedMetadataTracksChanged: TimedMetadataTracksChanged::, + RemoveTimedMetadataTracksChanged: RemoveTimedMetadataTracksChanged::, + Source: Source::, + AudioTracks: AudioTracks::, + VideoTracks: VideoTracks::, + TimedMetadataTracks: TimedMetadataTracks::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaPlaybackItem_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Foundation_Collections")] + pub AudioTracksChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + #[cfg(not(feature = "Foundation_Collections"))] + AudioTracksChanged: usize, + pub RemoveAudioTracksChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + #[cfg(feature = "Foundation_Collections")] + pub VideoTracksChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + #[cfg(not(feature = "Foundation_Collections"))] + VideoTracksChanged: usize, + pub RemoveVideoTracksChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + #[cfg(feature = "Foundation_Collections")] + pub TimedMetadataTracksChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + #[cfg(not(feature = "Foundation_Collections"))] + TimedMetadataTracksChanged: usize, + pub RemoveTimedMetadataTracksChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + #[cfg(feature = "Media_Core")] + pub Source: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Core"))] + Source: usize, + #[cfg(feature = "Media_Core")] + pub AudioTracks: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Core"))] + AudioTracks: usize, + #[cfg(feature = "Media_Core")] + pub VideoTracks: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Core"))] + VideoTracks: usize, + #[cfg(feature = "Media_Core")] + pub TimedMetadataTracks: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Core"))] + TimedMetadataTracks: usize, +} +windows_core::imp::define_interface!(IMediaPlaybackItem2, IMediaPlaybackItem2_Vtbl, 0xd859d171_d7ef_4b81_ac1f_f40493cbb091); +impl windows_core::RuntimeType for IMediaPlaybackItem2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Core"))] +impl windows_core::RuntimeName for IMediaPlaybackItem2 { + const NAME: &'static str = "Windows.Media.Playback.IMediaPlaybackItem2"; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Core"))] +pub trait IMediaPlaybackItem2_Impl: IMediaPlaybackItem_Impl + IMediaPlaybackSource_Impl { + fn BreakSchedule(&self) -> windows_core::Result; + fn StartTime(&self) -> windows_core::Result; + fn DurationLimit(&self) -> windows_core::Result>; + fn CanSkip(&self) -> windows_core::Result; + fn SetCanSkip(&self, value: bool) -> windows_core::Result<()>; + fn GetDisplayProperties(&self) -> windows_core::Result; + fn ApplyDisplayProperties(&self, value: windows_core::Ref<'_, MediaItemDisplayProperties>) -> windows_core::Result<()>; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Core"))] +impl IMediaPlaybackItem2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn BreakSchedule(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItem2_Impl::BreakSchedule(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StartTime(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItem2_Impl::StartTime(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DurationLimit(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItem2_Impl::DurationLimit(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CanSkip(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItem2_Impl::CanSkip(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetCanSkip(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackItem2_Impl::SetCanSkip(this, value).into() + } + } + unsafe extern "system" fn GetDisplayProperties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItem2_Impl::GetDisplayProperties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ApplyDisplayProperties(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackItem2_Impl::ApplyDisplayProperties(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + BreakSchedule: BreakSchedule::, + StartTime: StartTime::, + DurationLimit: DurationLimit::, + CanSkip: CanSkip::, + SetCanSkip: SetCanSkip::, + GetDisplayProperties: GetDisplayProperties::, + ApplyDisplayProperties: ApplyDisplayProperties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaPlaybackItem2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub BreakSchedule: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub StartTime: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub DurationLimit: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CanSkip: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetCanSkip: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub GetDisplayProperties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ApplyDisplayProperties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaPlaybackItem3, IMediaPlaybackItem3_Vtbl, 0x0d328220_b80a_4d09_9ff8_f87094a1c831); +impl windows_core::RuntimeType for IMediaPlaybackItem3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Core"))] +impl windows_core::RuntimeName for IMediaPlaybackItem3 { + const NAME: &'static str = "Windows.Media.Playback.IMediaPlaybackItem3"; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Core"))] +pub trait IMediaPlaybackItem3_Impl: IMediaPlaybackItem_Impl + IMediaPlaybackItem2_Impl + IMediaPlaybackSource_Impl { + fn IsDisabledInPlaybackList(&self) -> windows_core::Result; + fn SetIsDisabledInPlaybackList(&self, value: bool) -> windows_core::Result<()>; + fn TotalDownloadProgress(&self) -> windows_core::Result; + fn AutoLoadedDisplayProperties(&self) -> windows_core::Result; + fn SetAutoLoadedDisplayProperties(&self, value: AutoLoadedDisplayPropertyKind) -> windows_core::Result<()>; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Media_Core"))] +impl IMediaPlaybackItem3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsDisabledInPlaybackList(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItem3_Impl::IsDisabledInPlaybackList(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetIsDisabledInPlaybackList(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackItem3_Impl::SetIsDisabledInPlaybackList(this, value).into() + } + } + unsafe extern "system" fn TotalDownloadProgress(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItem3_Impl::TotalDownloadProgress(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AutoLoadedDisplayProperties(this: *mut core::ffi::c_void, result__: *mut AutoLoadedDisplayPropertyKind) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItem3_Impl::AutoLoadedDisplayProperties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAutoLoadedDisplayProperties(this: *mut core::ffi::c_void, value: AutoLoadedDisplayPropertyKind) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackItem3_Impl::SetAutoLoadedDisplayProperties(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsDisabledInPlaybackList: IsDisabledInPlaybackList::, + SetIsDisabledInPlaybackList: SetIsDisabledInPlaybackList::, + TotalDownloadProgress: TotalDownloadProgress::, + AutoLoadedDisplayProperties: AutoLoadedDisplayProperties::, + SetAutoLoadedDisplayProperties: SetAutoLoadedDisplayProperties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaPlaybackItem3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsDisabledInPlaybackList: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetIsDisabledInPlaybackList: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub TotalDownloadProgress: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, + pub AutoLoadedDisplayProperties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut AutoLoadedDisplayPropertyKind) -> windows_core::HRESULT, + pub SetAutoLoadedDisplayProperties: unsafe extern "system" fn(*mut core::ffi::c_void, AutoLoadedDisplayPropertyKind) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaPlaybackItemError, IMediaPlaybackItemError_Vtbl, 0x69fbef2b_dcd6_4df9_a450_dbf4c6f1c2c2); +impl windows_core::RuntimeType for IMediaPlaybackItemError { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaPlaybackItemError { + const NAME: &'static str = "Windows.Media.Playback.IMediaPlaybackItemError"; +} +pub trait IMediaPlaybackItemError_Impl: windows_core::IUnknownImpl { + fn ErrorCode(&self) -> windows_core::Result; + fn ExtendedError(&self) -> windows_core::Result; +} +impl IMediaPlaybackItemError_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ErrorCode(this: *mut core::ffi::c_void, result__: *mut MediaPlaybackItemErrorCode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItemError_Impl::ErrorCode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ExtendedError(this: *mut core::ffi::c_void, result__: *mut windows_core::HRESULT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItemError_Impl::ExtendedError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ErrorCode: ErrorCode::, + ExtendedError: ExtendedError::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaPlaybackItemError_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ErrorCode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut MediaPlaybackItemErrorCode) -> windows_core::HRESULT, + pub ExtendedError: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_core::HRESULT) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaPlaybackItemFactory, IMediaPlaybackItemFactory_Vtbl, 0x7133fce1_1769_4ff9_a7c1_38d2c4d42360); +impl windows_core::RuntimeType for IMediaPlaybackItemFactory { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Core")] +impl windows_core::RuntimeName for IMediaPlaybackItemFactory { + const NAME: &'static str = "Windows.Media.Playback.IMediaPlaybackItemFactory"; +} +#[cfg(feature = "Media_Core")] +pub trait IMediaPlaybackItemFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, source: windows_core::Ref<'_, super::Core::MediaSource>) -> windows_core::Result; +} +#[cfg(feature = "Media_Core")] +impl IMediaPlaybackItemFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, source: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItemFactory_Impl::Create(this, core::mem::transmute_copy(&source)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaPlaybackItemFactory_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_Core")] + pub Create: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Core"))] + Create: usize, +} +windows_core::imp::define_interface!(IMediaPlaybackItemFactory2, IMediaPlaybackItemFactory2_Vtbl, 0xd77cdf3a_b947_4972_b35d_adfb931a71e6); +impl windows_core::RuntimeType for IMediaPlaybackItemFactory2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Core")] +impl windows_core::RuntimeName for IMediaPlaybackItemFactory2 { + const NAME: &'static str = "Windows.Media.Playback.IMediaPlaybackItemFactory2"; +} +#[cfg(feature = "Media_Core")] +pub trait IMediaPlaybackItemFactory2_Impl: IMediaPlaybackItemFactory_Impl { + fn CreateWithStartTime(&self, source: windows_core::Ref<'_, super::Core::MediaSource>, startTime: &super::super::Foundation::TimeSpan) -> windows_core::Result; + fn CreateWithStartTimeAndDurationLimit(&self, source: windows_core::Ref<'_, super::Core::MediaSource>, startTime: &super::super::Foundation::TimeSpan, durationLimit: &super::super::Foundation::TimeSpan) -> windows_core::Result; +} +#[cfg(feature = "Media_Core")] +impl IMediaPlaybackItemFactory2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateWithStartTime(this: *mut core::ffi::c_void, source: *mut core::ffi::c_void, starttime: super::super::Foundation::TimeSpan, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItemFactory2_Impl::CreateWithStartTime(this, core::mem::transmute_copy(&source), core::mem::transmute(&starttime)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateWithStartTimeAndDurationLimit(this: *mut core::ffi::c_void, source: *mut core::ffi::c_void, starttime: super::super::Foundation::TimeSpan, durationlimit: super::super::Foundation::TimeSpan, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItemFactory2_Impl::CreateWithStartTimeAndDurationLimit(this, core::mem::transmute_copy(&source), core::mem::transmute(&starttime), core::mem::transmute(&durationlimit)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateWithStartTime: CreateWithStartTime::, + CreateWithStartTimeAndDurationLimit: CreateWithStartTimeAndDurationLimit::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaPlaybackItemFactory2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_Core")] + pub CreateWithStartTime: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, super::super::Foundation::TimeSpan, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Core"))] + CreateWithStartTime: usize, + #[cfg(feature = "Media_Core")] + pub CreateWithStartTimeAndDurationLimit: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, super::super::Foundation::TimeSpan, super::super::Foundation::TimeSpan, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Core"))] + CreateWithStartTimeAndDurationLimit: usize, +} +windows_core::imp::define_interface!(IMediaPlaybackItemFailedEventArgs, IMediaPlaybackItemFailedEventArgs_Vtbl, 0x7703134a_e9a7_47c3_862c_c656d30683d4); +impl windows_core::RuntimeType for IMediaPlaybackItemFailedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaPlaybackItemFailedEventArgs { + const NAME: &'static str = "Windows.Media.Playback.IMediaPlaybackItemFailedEventArgs"; +} +pub trait IMediaPlaybackItemFailedEventArgs_Impl: windows_core::IUnknownImpl { + fn Item(&self) -> windows_core::Result; + fn Error(&self) -> windows_core::Result; +} +impl IMediaPlaybackItemFailedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Item(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItemFailedEventArgs_Impl::Item(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Error(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItemFailedEventArgs_Impl::Error(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Item: Item::, + Error: Error::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaPlaybackItemFailedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Item: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Error: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaPlaybackItemOpenedEventArgs, IMediaPlaybackItemOpenedEventArgs_Vtbl, 0xcbd9bd82_3037_4fbe_ae8f_39fc39edf4ef); +impl windows_core::RuntimeType for IMediaPlaybackItemOpenedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaPlaybackItemOpenedEventArgs { + const NAME: &'static str = "Windows.Media.Playback.IMediaPlaybackItemOpenedEventArgs"; +} +pub trait IMediaPlaybackItemOpenedEventArgs_Impl: windows_core::IUnknownImpl { + fn Item(&self) -> windows_core::Result; +} +impl IMediaPlaybackItemOpenedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Item(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItemOpenedEventArgs_Impl::Item(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Item: Item:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaPlaybackItemOpenedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Item: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaPlaybackItemStatics, IMediaPlaybackItemStatics_Vtbl, 0x4b1be7f4_4345_403c_8a67_f5de91df4c86); +impl windows_core::RuntimeType for IMediaPlaybackItemStatics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Core")] +impl windows_core::RuntimeName for IMediaPlaybackItemStatics { + const NAME: &'static str = "Windows.Media.Playback.IMediaPlaybackItemStatics"; +} +#[cfg(feature = "Media_Core")] +pub trait IMediaPlaybackItemStatics_Impl: windows_core::IUnknownImpl { + fn FindFromMediaSource(&self, source: windows_core::Ref<'_, super::Core::MediaSource>) -> windows_core::Result; +} +#[cfg(feature = "Media_Core")] +impl IMediaPlaybackItemStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FindFromMediaSource(this: *mut core::ffi::c_void, source: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackItemStatics_Impl::FindFromMediaSource(this, core::mem::transmute_copy(&source)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FindFromMediaSource: FindFromMediaSource::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaPlaybackItemStatics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_Core")] + pub FindFromMediaSource: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Core"))] + FindFromMediaSource: usize, +} +windows_core::imp::define_interface!(IMediaPlaybackList, IMediaPlaybackList_Vtbl, 0x7f77ee9c_dc42_4e26_a98d_7850df8ec925); +impl windows_core::RuntimeType for IMediaPlaybackList { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Foundation_Collections")] +impl windows_core::RuntimeName for IMediaPlaybackList { + const NAME: &'static str = "Windows.Media.Playback.IMediaPlaybackList"; +} +#[cfg(feature = "Foundation_Collections")] +pub trait IMediaPlaybackList_Impl: IMediaPlaybackSource_Impl { + fn ItemFailed(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveItemFailed(&self, token: i64) -> windows_core::Result<()>; + fn CurrentItemChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveCurrentItemChanged(&self, token: i64) -> windows_core::Result<()>; + fn ItemOpened(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveItemOpened(&self, token: i64) -> windows_core::Result<()>; + fn Items(&self) -> windows_core::Result>; + fn AutoRepeatEnabled(&self) -> windows_core::Result; + fn SetAutoRepeatEnabled(&self, value: bool) -> windows_core::Result<()>; + fn ShuffleEnabled(&self) -> windows_core::Result; + fn SetShuffleEnabled(&self, value: bool) -> windows_core::Result<()>; + fn CurrentItem(&self) -> windows_core::Result; + fn CurrentItemIndex(&self) -> windows_core::Result; + fn MoveNext(&self) -> windows_core::Result; + fn MovePrevious(&self) -> windows_core::Result; + fn MoveTo(&self, itemIndex: u32) -> windows_core::Result; +} +#[cfg(feature = "Foundation_Collections")] +impl IMediaPlaybackList_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ItemFailed(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackList_Impl::ItemFailed(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveItemFailed(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackList_Impl::RemoveItemFailed(this, token).into() + } + } + unsafe extern "system" fn CurrentItemChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackList_Impl::CurrentItemChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveCurrentItemChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackList_Impl::RemoveCurrentItemChanged(this, token).into() + } + } + unsafe extern "system" fn ItemOpened(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackList_Impl::ItemOpened(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveItemOpened(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackList_Impl::RemoveItemOpened(this, token).into() + } + } + unsafe extern "system" fn Items(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackList_Impl::Items(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AutoRepeatEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackList_Impl::AutoRepeatEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAutoRepeatEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackList_Impl::SetAutoRepeatEnabled(this, value).into() + } + } + unsafe extern "system" fn ShuffleEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackList_Impl::ShuffleEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetShuffleEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackList_Impl::SetShuffleEnabled(this, value).into() + } + } + unsafe extern "system" fn CurrentItem(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackList_Impl::CurrentItem(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CurrentItemIndex(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackList_Impl::CurrentItemIndex(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MoveNext(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackList_Impl::MoveNext(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MovePrevious(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackList_Impl::MovePrevious(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MoveTo(this: *mut core::ffi::c_void, itemindex: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackList_Impl::MoveTo(this, itemindex) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ItemFailed: ItemFailed::, + RemoveItemFailed: RemoveItemFailed::, + CurrentItemChanged: CurrentItemChanged::, + RemoveCurrentItemChanged: RemoveCurrentItemChanged::, + ItemOpened: ItemOpened::, + RemoveItemOpened: RemoveItemOpened::, + Items: Items::, + AutoRepeatEnabled: AutoRepeatEnabled::, + SetAutoRepeatEnabled: SetAutoRepeatEnabled::, + ShuffleEnabled: ShuffleEnabled::, + SetShuffleEnabled: SetShuffleEnabled::, + CurrentItem: CurrentItem::, + CurrentItemIndex: CurrentItemIndex::, + MoveNext: MoveNext::, + MovePrevious: MovePrevious::, + MoveTo: MoveTo::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaPlaybackList_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ItemFailed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveItemFailed: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub CurrentItemChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveCurrentItemChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub ItemOpened: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveItemOpened: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + #[cfg(feature = "Foundation_Collections")] + pub Items: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Foundation_Collections"))] + Items: usize, + pub AutoRepeatEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetAutoRepeatEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub ShuffleEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetShuffleEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub CurrentItem: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CurrentItemIndex: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub MoveNext: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub MovePrevious: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub MoveTo: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaPlaybackList2, IMediaPlaybackList2_Vtbl, 0x0e09b478_600a_4274_a14b_0b6723d0f48b); +impl windows_core::RuntimeType for IMediaPlaybackList2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Foundation_Collections")] +impl windows_core::RuntimeName for IMediaPlaybackList2 { + const NAME: &'static str = "Windows.Media.Playback.IMediaPlaybackList2"; +} +#[cfg(feature = "Foundation_Collections")] +pub trait IMediaPlaybackList2_Impl: IMediaPlaybackList_Impl + IMediaPlaybackSource_Impl { + fn MaxPrefetchTime(&self) -> windows_core::Result>; + fn SetMaxPrefetchTime(&self, value: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn StartingItem(&self) -> windows_core::Result; + fn SetStartingItem(&self, value: windows_core::Ref<'_, MediaPlaybackItem>) -> windows_core::Result<()>; + fn ShuffledItems(&self) -> windows_core::Result>; + fn SetShuffledItems(&self, value: windows_core::Ref<'_, windows_collections::IIterable>) -> windows_core::Result<()>; +} +#[cfg(feature = "Foundation_Collections")] +impl IMediaPlaybackList2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn MaxPrefetchTime(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackList2_Impl::MaxPrefetchTime(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMaxPrefetchTime(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackList2_Impl::SetMaxPrefetchTime(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn StartingItem(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackList2_Impl::StartingItem(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetStartingItem(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackList2_Impl::SetStartingItem(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn ShuffledItems(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackList2_Impl::ShuffledItems(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetShuffledItems(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackList2_Impl::SetShuffledItems(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + MaxPrefetchTime: MaxPrefetchTime::, + SetMaxPrefetchTime: SetMaxPrefetchTime::, + StartingItem: StartingItem::, + SetStartingItem: SetStartingItem::, + ShuffledItems: ShuffledItems::, + SetShuffledItems: SetShuffledItems::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaPlaybackList2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub MaxPrefetchTime: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetMaxPrefetchTime: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub StartingItem: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetStartingItem: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ShuffledItems: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetShuffledItems: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaPlaybackList3, IMediaPlaybackList3_Vtbl, 0xdd24bba9_bc47_4463_aa90_c18b7e5ffde1); +impl windows_core::RuntimeType for IMediaPlaybackList3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Foundation_Collections")] +impl windows_core::RuntimeName for IMediaPlaybackList3 { + const NAME: &'static str = "Windows.Media.Playback.IMediaPlaybackList3"; +} +#[cfg(feature = "Foundation_Collections")] +pub trait IMediaPlaybackList3_Impl: IMediaPlaybackList_Impl + IMediaPlaybackList2_Impl + IMediaPlaybackSource_Impl { + fn MaxPlayedItemsToKeepOpen(&self) -> windows_core::Result>; + fn SetMaxPlayedItemsToKeepOpen(&self, value: windows_core::Ref<'_, super::super::Foundation::IReference>) -> windows_core::Result<()>; +} +#[cfg(feature = "Foundation_Collections")] +impl IMediaPlaybackList3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn MaxPlayedItemsToKeepOpen(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackList3_Impl::MaxPlayedItemsToKeepOpen(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMaxPlayedItemsToKeepOpen(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackList3_Impl::SetMaxPlayedItemsToKeepOpen(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + MaxPlayedItemsToKeepOpen: MaxPlayedItemsToKeepOpen::, + SetMaxPlayedItemsToKeepOpen: SetMaxPlayedItemsToKeepOpen::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaPlaybackList3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub MaxPlayedItemsToKeepOpen: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetMaxPlayedItemsToKeepOpen: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaPlaybackSource, IMediaPlaybackSource_Vtbl, 0xef9dc2bc_9317_4696_b051_2bad643177b5); +impl windows_core::RuntimeType for IMediaPlaybackSource { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IMediaPlaybackSource, windows_core::IUnknown, windows_core::IInspectable); +impl windows_core::RuntimeName for IMediaPlaybackSource { + const NAME: &'static str = "Windows.Media.Playback.IMediaPlaybackSource"; +} +pub trait IMediaPlaybackSource_Impl: windows_core::IUnknownImpl {} +impl IMediaPlaybackSource_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaPlaybackSource_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, +} +windows_core::imp::define_interface!(IMediaPlaybackTimedMetadataTrackList, IMediaPlaybackTimedMetadataTrackList_Vtbl, 0x72b41319_bbfb_46a3_9372_9c9c744b9438); +impl windows_core::RuntimeType for IMediaPlaybackTimedMetadataTrackList { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Core")] +impl windows_core::RuntimeName for IMediaPlaybackTimedMetadataTrackList { + const NAME: &'static str = "Windows.Media.Playback.IMediaPlaybackTimedMetadataTrackList"; +} +#[cfg(feature = "Media_Core")] +pub trait IMediaPlaybackTimedMetadataTrackList_Impl: windows_core::IUnknownImpl { + fn PresentationModeChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemovePresentationModeChanged(&self, token: i64) -> windows_core::Result<()>; + fn GetPresentationMode(&self, index: u32) -> windows_core::Result; + fn SetPresentationMode(&self, index: u32, value: TimedMetadataTrackPresentationMode) -> windows_core::Result<()>; +} +#[cfg(feature = "Media_Core")] +impl IMediaPlaybackTimedMetadataTrackList_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn PresentationModeChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackTimedMetadataTrackList_Impl::PresentationModeChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemovePresentationModeChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackTimedMetadataTrackList_Impl::RemovePresentationModeChanged(this, token).into() + } + } + unsafe extern "system" fn GetPresentationMode(this: *mut core::ffi::c_void, index: u32, result__: *mut TimedMetadataTrackPresentationMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaPlaybackTimedMetadataTrackList_Impl::GetPresentationMode(this, index) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPresentationMode(this: *mut core::ffi::c_void, index: u32, value: TimedMetadataTrackPresentationMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaPlaybackTimedMetadataTrackList_Impl::SetPresentationMode(this, index, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + PresentationModeChanged: PresentationModeChanged::, + RemovePresentationModeChanged: RemovePresentationModeChanged::, + GetPresentationMode: GetPresentationMode::, + SetPresentationMode: SetPresentationMode::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaPlaybackTimedMetadataTrackList_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_Core")] + pub PresentationModeChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Core"))] + PresentationModeChanged: usize, + pub RemovePresentationModeChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub GetPresentationMode: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *mut TimedMetadataTrackPresentationMode) -> windows_core::HRESULT, + pub SetPresentationMode: unsafe extern "system" fn(*mut core::ffi::c_void, u32, TimedMetadataTrackPresentationMode) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ITimedMetadataPresentationModeChangedEventArgs, ITimedMetadataPresentationModeChangedEventArgs_Vtbl, 0xd1636099_65df_45ae_8cef_dc0b53fdc2bb); +impl windows_core::RuntimeType for ITimedMetadataPresentationModeChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Core")] +impl windows_core::RuntimeName for ITimedMetadataPresentationModeChangedEventArgs { + const NAME: &'static str = "Windows.Media.Playback.ITimedMetadataPresentationModeChangedEventArgs"; +} +#[cfg(feature = "Media_Core")] +pub trait ITimedMetadataPresentationModeChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn Track(&self) -> windows_core::Result; + fn OldPresentationMode(&self) -> windows_core::Result; + fn NewPresentationMode(&self) -> windows_core::Result; +} +#[cfg(feature = "Media_Core")] +impl ITimedMetadataPresentationModeChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Track(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataPresentationModeChangedEventArgs_Impl::Track(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OldPresentationMode(this: *mut core::ffi::c_void, result__: *mut TimedMetadataTrackPresentationMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataPresentationModeChangedEventArgs_Impl::OldPresentationMode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NewPresentationMode(this: *mut core::ffi::c_void, result__: *mut TimedMetadataTrackPresentationMode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ITimedMetadataPresentationModeChangedEventArgs_Impl::NewPresentationMode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Track: Track::, + OldPresentationMode: OldPresentationMode::, + NewPresentationMode: NewPresentationMode::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ITimedMetadataPresentationModeChangedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_Core")] + pub Track: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Core"))] + Track: usize, + pub OldPresentationMode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut TimedMetadataTrackPresentationMode) -> windows_core::HRESULT, + pub NewPresentationMode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut TimedMetadataTrackPresentationMode) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaBreak(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaBreak, windows_core::IUnknown, windows_core::IInspectable); +impl MediaBreak { + pub fn PlaybackList(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PlaybackList)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PresentationPosition(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PresentationPosition)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn InsertionMethod(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InsertionMethod)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Foundation_Collections")] + pub fn CustomProperties(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CustomProperties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CanStart(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanStart)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetCanStart(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetCanStart)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Create(insertionmethod: MediaBreakInsertionMethod) -> windows_core::Result { + Self::IMediaBreakFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), insertionmethod, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateWithPresentationPosition(insertionmethod: MediaBreakInsertionMethod, presentationposition: super::super::Foundation::TimeSpan) -> windows_core::Result { + Self::IMediaBreakFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWithPresentationPosition)(windows_core::Interface::as_raw(this), insertionmethod, presentationposition, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn IMediaBreakFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for MediaBreak { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaBreak { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaBreak { + const NAME: &'static str = "Windows.Media.Playback.MediaBreak"; +} +unsafe impl Send for MediaBreak {} +unsafe impl Sync for MediaBreak {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaBreakInsertionMethod(pub i32); +impl MediaBreakInsertionMethod { + pub const Interrupt: Self = Self(0i32); + pub const Replace: Self = Self(1i32); +} +impl windows_core::TypeKind for MediaBreakInsertionMethod { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaBreakInsertionMethod { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Playback.MediaBreakInsertionMethod;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaBreakSchedule(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaBreakSchedule, windows_core::IUnknown, windows_core::IInspectable); +impl MediaBreakSchedule { + pub fn ScheduleChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ScheduleChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveScheduleChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveScheduleChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn InsertMidrollBreak(&self, mediabreak: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).InsertMidrollBreak)(windows_core::Interface::as_raw(this), mediabreak.param().abi()).ok() } + } + pub fn RemoveMidrollBreak(&self, mediabreak: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveMidrollBreak)(windows_core::Interface::as_raw(this), mediabreak.param().abi()).ok() } + } + pub fn MidrollBreaks(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MidrollBreaks)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetPrerollBreak(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPrerollBreak)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn PrerollBreak(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PrerollBreak)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetPostrollBreak(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPostrollBreak)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn PostrollBreak(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PostrollBreak)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PlaybackItem(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PlaybackItem)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaBreakSchedule { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaBreakSchedule { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaBreakSchedule { + const NAME: &'static str = "Windows.Media.Playback.MediaBreakSchedule"; +} +unsafe impl Send for MediaBreakSchedule {} +unsafe impl Sync for MediaBreakSchedule {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaItemDisplayProperties(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaItemDisplayProperties, windows_core::IUnknown, windows_core::IInspectable); +impl MediaItemDisplayProperties { + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetType(&self, value: super::MediaPlaybackType) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetType)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn MusicProperties(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MusicProperties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn VideoProperties(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).VideoProperties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn Thumbnail(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Thumbnail)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn SetThumbnail(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetThumbnail)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn ClearAll(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ClearAll)(windows_core::Interface::as_raw(this)).ok() } + } +} +impl windows_core::RuntimeType for MediaItemDisplayProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaItemDisplayProperties { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaItemDisplayProperties { + const NAME: &'static str = "Windows.Media.Playback.MediaItemDisplayProperties"; +} +unsafe impl Send for MediaItemDisplayProperties {} +unsafe impl Sync for MediaItemDisplayProperties {} +#[cfg(feature = "Media_Core")] +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaPlaybackAudioTrackList(windows_core::IUnknown); +#[cfg(feature = "Media_Core")] +windows_core::imp::interface_hierarchy!(MediaPlaybackAudioTrackList, windows_core::IUnknown, windows_core::IInspectable, windows_collections::IVectorView); +#[cfg(feature = "Media_Core")] +windows_core::imp::required_hierarchy!(MediaPlaybackAudioTrackList, windows_collections::IIterable, super::Core::ISingleSelectMediaTrackList); +#[cfg(feature = "Media_Core")] +impl MediaPlaybackAudioTrackList { + pub fn First(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SelectedIndexChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SelectedIndexChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveSelectedIndexChanged(&self, token: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveSelectedIndexChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn SetSelectedIndex(&self, value: i32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetSelectedIndex)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn SelectedIndex(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SelectedIndex)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } +} +#[cfg(feature = "Media_Core")] +impl windows_core::RuntimeType for MediaPlaybackAudioTrackList { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::>(); +} +#[cfg(feature = "Media_Core")] +unsafe impl windows_core::Interface for MediaPlaybackAudioTrackList { + type Vtable = as windows_core::Interface>::Vtable; + const IID: windows_core::GUID = as windows_core::Interface>::IID; +} +#[cfg(feature = "Media_Core")] +impl windows_core::RuntimeName for MediaPlaybackAudioTrackList { + const NAME: &'static str = "Windows.Media.Playback.MediaPlaybackAudioTrackList"; +} +#[cfg(feature = "Media_Core")] +unsafe impl Send for MediaPlaybackAudioTrackList {} +#[cfg(feature = "Media_Core")] +unsafe impl Sync for MediaPlaybackAudioTrackList {} +#[cfg(feature = "Media_Core")] +impl IntoIterator for MediaPlaybackAudioTrackList { + type Item = super::Core::AudioTrack; + type IntoIter = windows_collections::IIterator; + fn into_iter(self) -> Self::IntoIter { + IntoIterator::into_iter(&self) + } +} +#[cfg(feature = "Media_Core")] +impl IntoIterator for &MediaPlaybackAudioTrackList { + type Item = super::Core::AudioTrack; + type IntoIter = windows_collections::IIterator; + fn into_iter(self) -> Self::IntoIter { + self.First().unwrap() + } +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaPlaybackItem(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaPlaybackItem, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(MediaPlaybackItem, IMediaPlaybackSource); +impl MediaPlaybackItem { + #[cfg(feature = "Foundation_Collections")] + pub fn AudioTracksChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AudioTracksChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveAudioTracksChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveAudioTracksChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Foundation_Collections")] + pub fn VideoTracksChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).VideoTracksChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveVideoTracksChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveVideoTracksChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Foundation_Collections")] + pub fn TimedMetadataTracksChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TimedMetadataTracksChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveTimedMetadataTracksChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveTimedMetadataTracksChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Media_Core")] + pub fn Source(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Source)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Media_Core")] + pub fn AudioTracks(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AudioTracks)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Media_Core")] + pub fn VideoTracks(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).VideoTracks)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Media_Core")] + pub fn TimedMetadataTracks(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TimedMetadataTracks)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn BreakSchedule(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BreakSchedule)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn StartTime(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StartTime)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DurationLimit(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DurationLimit)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CanSkip(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanSkip)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetCanSkip(&self, value: bool) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetCanSkip)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn GetDisplayProperties(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDisplayProperties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ApplyDisplayProperties(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).ApplyDisplayProperties)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn IsDisabledInPlaybackList(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsDisabledInPlaybackList)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetIsDisabledInPlaybackList(&self, value: bool) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetIsDisabledInPlaybackList)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn TotalDownloadProgress(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TotalDownloadProgress)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AutoLoadedDisplayProperties(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AutoLoadedDisplayProperties)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAutoLoadedDisplayProperties(&self, value: AutoLoadedDisplayPropertyKind) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAutoLoadedDisplayProperties)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Media_Core")] + pub fn Create(source: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaPlaybackItemFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), source.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Media_Core")] + pub fn CreateWithStartTime(source: P0, starttime: super::super::Foundation::TimeSpan) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaPlaybackItemFactory2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWithStartTime)(windows_core::Interface::as_raw(this), source.param().abi(), starttime, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Media_Core")] + pub fn CreateWithStartTimeAndDurationLimit(source: P0, starttime: super::super::Foundation::TimeSpan, durationlimit: super::super::Foundation::TimeSpan) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaPlaybackItemFactory2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWithStartTimeAndDurationLimit)(windows_core::Interface::as_raw(this), source.param().abi(), starttime, durationlimit, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Media_Core")] + pub fn FindFromMediaSource(source: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IMediaPlaybackItemStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindFromMediaSource)(windows_core::Interface::as_raw(this), source.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn IMediaPlaybackItemFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn IMediaPlaybackItemFactory2 windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn IMediaPlaybackItemStatics windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for MediaPlaybackItem { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaPlaybackItem { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaPlaybackItem { + const NAME: &'static str = "Windows.Media.Playback.MediaPlaybackItem"; +} +unsafe impl Send for MediaPlaybackItem {} +unsafe impl Sync for MediaPlaybackItem {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaPlaybackItemChangedReason(pub i32); +impl MediaPlaybackItemChangedReason { + pub const InitialItem: Self = Self(0i32); + pub const EndOfStream: Self = Self(1i32); + pub const Error: Self = Self(2i32); + pub const AppRequested: Self = Self(3i32); +} +impl windows_core::TypeKind for MediaPlaybackItemChangedReason { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaPlaybackItemChangedReason { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Playback.MediaPlaybackItemChangedReason;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaPlaybackItemError(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaPlaybackItemError, windows_core::IUnknown, windows_core::IInspectable); +impl MediaPlaybackItemError { + pub fn ErrorCode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ErrorCode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ExtendedError(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExtendedError)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for MediaPlaybackItemError { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaPlaybackItemError { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaPlaybackItemError { + const NAME: &'static str = "Windows.Media.Playback.MediaPlaybackItemError"; +} +unsafe impl Send for MediaPlaybackItemError {} +unsafe impl Sync for MediaPlaybackItemError {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct MediaPlaybackItemErrorCode(pub i32); +impl MediaPlaybackItemErrorCode { + pub const None: Self = Self(0i32); + pub const Aborted: Self = Self(1i32); + pub const NetworkError: Self = Self(2i32); + pub const DecodeError: Self = Self(3i32); + pub const SourceNotSupportedError: Self = Self(4i32); + pub const EncryptionError: Self = Self(5i32); +} +impl windows_core::TypeKind for MediaPlaybackItemErrorCode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for MediaPlaybackItemErrorCode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Playback.MediaPlaybackItemErrorCode;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaPlaybackItemFailedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaPlaybackItemFailedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl MediaPlaybackItemFailedEventArgs { + pub fn Item(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Item)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Error(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Error)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaPlaybackItemFailedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaPlaybackItemFailedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaPlaybackItemFailedEventArgs { + const NAME: &'static str = "Windows.Media.Playback.MediaPlaybackItemFailedEventArgs"; +} +unsafe impl Send for MediaPlaybackItemFailedEventArgs {} +unsafe impl Sync for MediaPlaybackItemFailedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaPlaybackItemOpenedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaPlaybackItemOpenedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl MediaPlaybackItemOpenedEventArgs { + pub fn Item(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Item)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaPlaybackItemOpenedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaPlaybackItemOpenedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaPlaybackItemOpenedEventArgs { + const NAME: &'static str = "Windows.Media.Playback.MediaPlaybackItemOpenedEventArgs"; +} +unsafe impl Send for MediaPlaybackItemOpenedEventArgs {} +unsafe impl Sync for MediaPlaybackItemOpenedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaPlaybackList(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaPlaybackList, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(MediaPlaybackList, IMediaPlaybackSource); +impl MediaPlaybackList { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn ItemFailed(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ItemFailed)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveItemFailed(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveItemFailed)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn CurrentItemChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CurrentItemChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveCurrentItemChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveCurrentItemChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn ItemOpened(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ItemOpened)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveItemOpened(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveItemOpened)(windows_core::Interface::as_raw(this), token).ok() } + } + #[cfg(feature = "Foundation_Collections")] + pub fn Items(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Items)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn AutoRepeatEnabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AutoRepeatEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAutoRepeatEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAutoRepeatEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ShuffleEnabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ShuffleEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetShuffleEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetShuffleEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn CurrentItem(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CurrentItem)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CurrentItemIndex(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CurrentItemIndex)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn MoveNext(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MoveNext)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MovePrevious(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MovePrevious)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MoveTo(&self, itemindex: u32) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MoveTo)(windows_core::Interface::as_raw(this), itemindex, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MaxPrefetchTime(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxPrefetchTime)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetMaxPrefetchTime(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetMaxPrefetchTime)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn StartingItem(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StartingItem)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetStartingItem(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetStartingItem)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn ShuffledItems(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ShuffledItems)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetShuffledItems(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetShuffledItems)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn MaxPlayedItemsToKeepOpen(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxPlayedItemsToKeepOpen)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetMaxPlayedItemsToKeepOpen(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetMaxPlayedItemsToKeepOpen)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } +} +impl windows_core::RuntimeType for MediaPlaybackList { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaPlaybackList { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaPlaybackList { + const NAME: &'static str = "Windows.Media.Playback.MediaPlaybackList"; +} +unsafe impl Send for MediaPlaybackList {} +unsafe impl Sync for MediaPlaybackList {} +#[cfg(feature = "Media_Core")] +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaPlaybackTimedMetadataTrackList(windows_core::IUnknown); +#[cfg(feature = "Media_Core")] +windows_core::imp::interface_hierarchy!(MediaPlaybackTimedMetadataTrackList, windows_core::IUnknown, windows_core::IInspectable, windows_collections::IVectorView); +#[cfg(feature = "Media_Core")] +windows_core::imp::required_hierarchy!(MediaPlaybackTimedMetadataTrackList, windows_collections::IIterable); +#[cfg(feature = "Media_Core")] +impl MediaPlaybackTimedMetadataTrackList { + pub fn First(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PresentationModeChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PresentationModeChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemovePresentationModeChanged(&self, token: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemovePresentationModeChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn GetPresentationMode(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetPresentationMode)(windows_core::Interface::as_raw(this), index, &mut result__).map(|| result__) + } + } + pub fn SetPresentationMode(&self, index: u32, value: TimedMetadataTrackPresentationMode) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetPresentationMode)(windows_core::Interface::as_raw(this), index, value).ok() } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } +} +#[cfg(feature = "Media_Core")] +impl windows_core::RuntimeType for MediaPlaybackTimedMetadataTrackList { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::>(); +} +#[cfg(feature = "Media_Core")] +unsafe impl windows_core::Interface for MediaPlaybackTimedMetadataTrackList { + type Vtable = as windows_core::Interface>::Vtable; + const IID: windows_core::GUID = as windows_core::Interface>::IID; +} +#[cfg(feature = "Media_Core")] +impl windows_core::RuntimeName for MediaPlaybackTimedMetadataTrackList { + const NAME: &'static str = "Windows.Media.Playback.MediaPlaybackTimedMetadataTrackList"; +} +#[cfg(feature = "Media_Core")] +unsafe impl Send for MediaPlaybackTimedMetadataTrackList {} +#[cfg(feature = "Media_Core")] +unsafe impl Sync for MediaPlaybackTimedMetadataTrackList {} +#[cfg(feature = "Media_Core")] +impl IntoIterator for MediaPlaybackTimedMetadataTrackList { + type Item = super::Core::TimedMetadataTrack; + type IntoIter = windows_collections::IIterator; + fn into_iter(self) -> Self::IntoIter { + IntoIterator::into_iter(&self) + } +} +#[cfg(feature = "Media_Core")] +impl IntoIterator for &MediaPlaybackTimedMetadataTrackList { + type Item = super::Core::TimedMetadataTrack; + type IntoIter = windows_collections::IIterator; + fn into_iter(self) -> Self::IntoIter { + self.First().unwrap() + } +} +#[cfg(feature = "Media_Core")] +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaPlaybackVideoTrackList(windows_core::IUnknown); +#[cfg(feature = "Media_Core")] +windows_core::imp::interface_hierarchy!(MediaPlaybackVideoTrackList, windows_core::IUnknown, windows_core::IInspectable, windows_collections::IVectorView); +#[cfg(feature = "Media_Core")] +windows_core::imp::required_hierarchy!(MediaPlaybackVideoTrackList, windows_collections::IIterable, super::Core::ISingleSelectMediaTrackList); +#[cfg(feature = "Media_Core")] +impl MediaPlaybackVideoTrackList { + pub fn First(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SelectedIndexChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SelectedIndexChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveSelectedIndexChanged(&self, token: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveSelectedIndexChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn SetSelectedIndex(&self, value: i32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetSelectedIndex)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn SelectedIndex(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SelectedIndex)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } +} +#[cfg(feature = "Media_Core")] +impl windows_core::RuntimeType for MediaPlaybackVideoTrackList { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::>(); +} +#[cfg(feature = "Media_Core")] +unsafe impl windows_core::Interface for MediaPlaybackVideoTrackList { + type Vtable = as windows_core::Interface>::Vtable; + const IID: windows_core::GUID = as windows_core::Interface>::IID; +} +#[cfg(feature = "Media_Core")] +impl windows_core::RuntimeName for MediaPlaybackVideoTrackList { + const NAME: &'static str = "Windows.Media.Playback.MediaPlaybackVideoTrackList"; +} +#[cfg(feature = "Media_Core")] +unsafe impl Send for MediaPlaybackVideoTrackList {} +#[cfg(feature = "Media_Core")] +unsafe impl Sync for MediaPlaybackVideoTrackList {} +#[cfg(feature = "Media_Core")] +impl IntoIterator for MediaPlaybackVideoTrackList { + type Item = super::Core::VideoTrack; + type IntoIter = windows_collections::IIterator; + fn into_iter(self) -> Self::IntoIter { + IntoIterator::into_iter(&self) + } +} +#[cfg(feature = "Media_Core")] +impl IntoIterator for &MediaPlaybackVideoTrackList { + type Item = super::Core::VideoTrack; + type IntoIter = windows_collections::IIterator; + fn into_iter(self) -> Self::IntoIter { + self.First().unwrap() + } +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct TimedMetadataPresentationModeChangedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(TimedMetadataPresentationModeChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl TimedMetadataPresentationModeChangedEventArgs { + #[cfg(feature = "Media_Core")] + pub fn Track(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Track)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn OldPresentationMode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OldPresentationMode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn NewPresentationMode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NewPresentationMode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for TimedMetadataPresentationModeChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for TimedMetadataPresentationModeChangedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for TimedMetadataPresentationModeChangedEventArgs { + const NAME: &'static str = "Windows.Media.Playback.TimedMetadataPresentationModeChangedEventArgs"; +} +unsafe impl Send for TimedMetadataPresentationModeChangedEventArgs {} +unsafe impl Sync for TimedMetadataPresentationModeChangedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct TimedMetadataTrackPresentationMode(pub i32); +impl TimedMetadataTrackPresentationMode { + pub const Disabled: Self = Self(0i32); + pub const Hidden: Self = Self(1i32); + pub const ApplicationPresented: Self = Self(2i32); + pub const PlatformPresented: Self = Self(3i32); +} +impl windows_core::TypeKind for TimedMetadataTrackPresentationMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for TimedMetadataTrackPresentationMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Playback.TimedMetadataTrackPresentationMode;i4)"); +} +} +#[cfg(feature = "Media_Protection")] +pub mod Protection{ +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ComponentLoadFailedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(ComponentLoadFailedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl ComponentLoadFailedEventArgs { + pub fn Information(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Information)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Completion(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Completion)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for ComponentLoadFailedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for ComponentLoadFailedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for ComponentLoadFailedEventArgs { + const NAME: &'static str = "Windows.Media.Protection.ComponentLoadFailedEventArgs"; +} +unsafe impl Send for ComponentLoadFailedEventArgs {} +unsafe impl Sync for ComponentLoadFailedEventArgs {} +windows_core::imp::define_interface!(ComponentLoadFailedEventHandler, ComponentLoadFailedEventHandler_Vtbl, 0x95da643c_6db9_424b_86ca_091af432081c); +impl windows_core::RuntimeType for ComponentLoadFailedEventHandler { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl ComponentLoadFailedEventHandler { + pub fn new, windows_core::Ref<'_, ComponentLoadFailedEventArgs>) -> windows_core::Result<()> + Send + 'static>(invoke: F) -> Self { + let com = ComponentLoadFailedEventHandlerBox { vtable: &ComponentLoadFailedEventHandlerBox::::VTABLE, count: windows_core::imp::RefCount::new(1), invoke }; + unsafe { core::mem::transmute(windows_core::imp::Box::new(com)) } + } + pub fn Invoke(&self, sender: P0, e: P1) -> windows_core::Result<()> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Invoke)(windows_core::Interface::as_raw(this), sender.param().abi(), e.param().abi()).ok() } + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ComponentLoadFailedEventHandler_Vtbl { + base__: windows_core::IUnknown_Vtbl, + Invoke: unsafe extern "system" fn(this: *mut core::ffi::c_void, sender: *mut core::ffi::c_void, e: *mut core::ffi::c_void) -> windows_core::HRESULT, +} +#[repr(C)] +struct ComponentLoadFailedEventHandlerBox, windows_core::Ref<'_, ComponentLoadFailedEventArgs>) -> windows_core::Result<()> + Send + 'static> { + vtable: *const ComponentLoadFailedEventHandler_Vtbl, + invoke: F, + count: windows_core::imp::RefCount, +} +impl, windows_core::Ref<'_, ComponentLoadFailedEventArgs>) -> windows_core::Result<()> + Send + 'static> ComponentLoadFailedEventHandlerBox { + const VTABLE: ComponentLoadFailedEventHandler_Vtbl = ComponentLoadFailedEventHandler_Vtbl { base__: windows_core::IUnknown_Vtbl { QueryInterface: Self::QueryInterface, AddRef: Self::AddRef, Release: Self::Release }, Invoke: Self::Invoke }; + unsafe extern "system" fn QueryInterface(this: *mut core::ffi::c_void, iid: *const windows_core::GUID, interface: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this = this as *mut *mut core::ffi::c_void as *mut Self; + if iid.is_null() || interface.is_null() { + return windows_core::HRESULT(-2147467261); + } + *interface = if *iid == ::IID || *iid == ::IID || *iid == ::IID { + &mut (*this).vtable as *mut _ as _ + } else if *iid == ::IID { + (*this).count.add_ref(); + return windows_core::imp::marshaler(core::mem::transmute(&mut (*this).vtable as *mut _ as *mut core::ffi::c_void), interface); + } else { + core::ptr::null_mut() + }; + if (*interface).is_null() { + windows_core::HRESULT(-2147467262) + } else { + (*this).count.add_ref(); + windows_core::HRESULT(0) + } + } + } + unsafe extern "system" fn AddRef(this: *mut core::ffi::c_void) -> u32 { + unsafe { + let this = this as *mut *mut core::ffi::c_void as *mut Self; + (*this).count.add_ref() + } + } + unsafe extern "system" fn Release(this: *mut core::ffi::c_void) -> u32 { + unsafe { + let this = this as *mut *mut core::ffi::c_void as *mut Self; + let remaining = (*this).count.release(); + if remaining == 0 { + let _ = windows_core::imp::Box::from_raw(this); + } + remaining + } + } + unsafe extern "system" fn Invoke(this: *mut core::ffi::c_void, sender: *mut core::ffi::c_void, e: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this = &mut *(this as *mut *mut core::ffi::c_void as *mut Self); + (this.invoke)(core::mem::transmute_copy(&sender), core::mem::transmute_copy(&e)).into() + } + } +} +windows_core::imp::define_interface!(IComponentLoadFailedEventArgs, IComponentLoadFailedEventArgs_Vtbl, 0x95972e93_7746_417e_8495_f031bbc5862c); +impl windows_core::RuntimeType for IComponentLoadFailedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IComponentLoadFailedEventArgs { + const NAME: &'static str = "Windows.Media.Protection.IComponentLoadFailedEventArgs"; +} +pub trait IComponentLoadFailedEventArgs_Impl: windows_core::IUnknownImpl { + fn Information(&self) -> windows_core::Result; + fn Completion(&self) -> windows_core::Result; +} +impl IComponentLoadFailedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Information(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IComponentLoadFailedEventArgs_Impl::Information(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Completion(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IComponentLoadFailedEventArgs_Impl::Completion(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Information: Information::, + Completion: Completion::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IComponentLoadFailedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Information: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Completion: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaProtectionManager, IMediaProtectionManager_Vtbl, 0x45694947_c741_434b_a79e_474c12d93d2f); +impl windows_core::RuntimeType for IMediaProtectionManager { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Foundation_Collections")] +impl windows_core::RuntimeName for IMediaProtectionManager { + const NAME: &'static str = "Windows.Media.Protection.IMediaProtectionManager"; +} +#[cfg(feature = "Foundation_Collections")] +pub trait IMediaProtectionManager_Impl: windows_core::IUnknownImpl { + fn ServiceRequested(&self, handler: windows_core::Ref<'_, ServiceRequestedEventHandler>) -> windows_core::Result; + fn RemoveServiceRequested(&self, cookie: i64) -> windows_core::Result<()>; + fn RebootNeeded(&self, handler: windows_core::Ref<'_, RebootNeededEventHandler>) -> windows_core::Result; + fn RemoveRebootNeeded(&self, cookie: i64) -> windows_core::Result<()>; + fn ComponentLoadFailed(&self, handler: windows_core::Ref<'_, ComponentLoadFailedEventHandler>) -> windows_core::Result; + fn RemoveComponentLoadFailed(&self, cookie: i64) -> windows_core::Result<()>; + fn Properties(&self) -> windows_core::Result; +} +#[cfg(feature = "Foundation_Collections")] +impl IMediaProtectionManager_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ServiceRequested(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaProtectionManager_Impl::ServiceRequested(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveServiceRequested(this: *mut core::ffi::c_void, cookie: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaProtectionManager_Impl::RemoveServiceRequested(this, cookie).into() + } + } + unsafe extern "system" fn RebootNeeded(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaProtectionManager_Impl::RebootNeeded(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveRebootNeeded(this: *mut core::ffi::c_void, cookie: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaProtectionManager_Impl::RemoveRebootNeeded(this, cookie).into() + } + } + unsafe extern "system" fn ComponentLoadFailed(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaProtectionManager_Impl::ComponentLoadFailed(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveComponentLoadFailed(this: *mut core::ffi::c_void, cookie: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaProtectionManager_Impl::RemoveComponentLoadFailed(this, cookie).into() + } + } + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaProtectionManager_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ServiceRequested: ServiceRequested::, + RemoveServiceRequested: RemoveServiceRequested::, + RebootNeeded: RebootNeeded::, + RemoveRebootNeeded: RemoveRebootNeeded::, + ComponentLoadFailed: ComponentLoadFailed::, + RemoveComponentLoadFailed: RemoveComponentLoadFailed::, + Properties: Properties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaProtectionManager_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ServiceRequested: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveServiceRequested: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub RebootNeeded: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveRebootNeeded: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub ComponentLoadFailed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveComponentLoadFailed: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + #[cfg(feature = "Foundation_Collections")] + pub Properties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Foundation_Collections"))] + Properties: usize, +} +windows_core::imp::define_interface!(IMediaProtectionServiceCompletion, IMediaProtectionServiceCompletion_Vtbl, 0x8b5cca18_cfd5_44ee_a2ed_df76010c14b5); +impl windows_core::RuntimeType for IMediaProtectionServiceCompletion { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMediaProtectionServiceCompletion { + const NAME: &'static str = "Windows.Media.Protection.IMediaProtectionServiceCompletion"; +} +pub trait IMediaProtectionServiceCompletion_Impl: windows_core::IUnknownImpl { + fn Complete(&self, success: bool) -> windows_core::Result<()>; +} +impl IMediaProtectionServiceCompletion_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Complete(this: *mut core::ffi::c_void, success: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMediaProtectionServiceCompletion_Impl::Complete(this, success).into() + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Complete: Complete:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaProtectionServiceCompletion_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Complete: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMediaProtectionServiceRequest, IMediaProtectionServiceRequest_Vtbl, 0xb1de0ea6_2094_478d_87a4_8b95200f85c6); +impl windows_core::RuntimeType for IMediaProtectionServiceRequest { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IMediaProtectionServiceRequest, windows_core::IUnknown, windows_core::IInspectable); +impl IMediaProtectionServiceRequest { + pub fn ProtectionSystem(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProtectionSystem)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeName for IMediaProtectionServiceRequest { + const NAME: &'static str = "Windows.Media.Protection.IMediaProtectionServiceRequest"; +} +pub trait IMediaProtectionServiceRequest_Impl: windows_core::IUnknownImpl { + fn ProtectionSystem(&self) -> windows_core::Result; + fn Type(&self) -> windows_core::Result; +} +impl IMediaProtectionServiceRequest_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ProtectionSystem(this: *mut core::ffi::c_void, result__: *mut windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaProtectionServiceRequest_Impl::ProtectionSystem(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Type(this: *mut core::ffi::c_void, result__: *mut windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMediaProtectionServiceRequest_Impl::Type(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ProtectionSystem: ProtectionSystem::, + Type: Type::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMediaProtectionServiceRequest_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ProtectionSystem: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_core::GUID) -> windows_core::HRESULT, + pub Type: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_core::GUID) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IRevocationAndRenewalInformation, IRevocationAndRenewalInformation_Vtbl, 0xf3a1937b_2501_439e_a6e7_6fc95e175fcf); +impl windows_core::RuntimeType for IRevocationAndRenewalInformation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IRevocationAndRenewalInformation { + const NAME: &'static str = "Windows.Media.Protection.IRevocationAndRenewalInformation"; +} +pub trait IRevocationAndRenewalInformation_Impl: windows_core::IUnknownImpl { + fn Items(&self) -> windows_core::Result>; +} +impl IRevocationAndRenewalInformation_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Items(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRevocationAndRenewalInformation_Impl::Items(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Items: Items:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IRevocationAndRenewalInformation_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Items: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IRevocationAndRenewalItem, IRevocationAndRenewalItem_Vtbl, 0x3099c20c_3cf0_49ea_902d_caf32d2dde2c); +impl windows_core::RuntimeType for IRevocationAndRenewalItem { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IRevocationAndRenewalItem { + const NAME: &'static str = "Windows.Media.Protection.IRevocationAndRenewalItem"; +} +pub trait IRevocationAndRenewalItem_Impl: windows_core::IUnknownImpl { + fn Reasons(&self) -> windows_core::Result; + fn HeaderHash(&self) -> windows_core::Result; + fn PublicKeyHash(&self) -> windows_core::Result; + fn Name(&self) -> windows_core::Result; + fn RenewalId(&self) -> windows_core::Result; +} +impl IRevocationAndRenewalItem_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Reasons(this: *mut core::ffi::c_void, result__: *mut RevocationAndRenewalReasons) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRevocationAndRenewalItem_Impl::Reasons(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn HeaderHash(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRevocationAndRenewalItem_Impl::HeaderHash(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PublicKeyHash(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRevocationAndRenewalItem_Impl::PublicKeyHash(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Name(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRevocationAndRenewalItem_Impl::Name(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RenewalId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRevocationAndRenewalItem_Impl::RenewalId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Reasons: Reasons::, + HeaderHash: HeaderHash::, + PublicKeyHash: PublicKeyHash::, + Name: Name::, + RenewalId: RenewalId::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IRevocationAndRenewalItem_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Reasons: unsafe extern "system" fn(*mut core::ffi::c_void, *mut RevocationAndRenewalReasons) -> windows_core::HRESULT, + pub HeaderHash: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub PublicKeyHash: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Name: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub RenewalId: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IServiceRequestedEventArgs, IServiceRequestedEventArgs_Vtbl, 0x34283baf_abb4_4fc1_bd89_93f106573a49); +impl windows_core::RuntimeType for IServiceRequestedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IServiceRequestedEventArgs { + const NAME: &'static str = "Windows.Media.Protection.IServiceRequestedEventArgs"; +} +pub trait IServiceRequestedEventArgs_Impl: windows_core::IUnknownImpl { + fn Request(&self) -> windows_core::Result; + fn Completion(&self) -> windows_core::Result; +} +impl IServiceRequestedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Request(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IServiceRequestedEventArgs_Impl::Request(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Completion(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IServiceRequestedEventArgs_Impl::Completion(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Request: Request::, + Completion: Completion::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IServiceRequestedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Request: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Completion: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IServiceRequestedEventArgs2, IServiceRequestedEventArgs2_Vtbl, 0x553c69d6_fafe_4128_8dfa_130e398a13a7); +impl windows_core::RuntimeType for IServiceRequestedEventArgs2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Playback")] +impl windows_core::RuntimeName for IServiceRequestedEventArgs2 { + const NAME: &'static str = "Windows.Media.Protection.IServiceRequestedEventArgs2"; +} +#[cfg(feature = "Media_Playback")] +pub trait IServiceRequestedEventArgs2_Impl: windows_core::IUnknownImpl { + fn MediaPlaybackItem(&self) -> windows_core::Result; +} +#[cfg(feature = "Media_Playback")] +impl IServiceRequestedEventArgs2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn MediaPlaybackItem(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IServiceRequestedEventArgs2_Impl::MediaPlaybackItem(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + MediaPlaybackItem: MediaPlaybackItem::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IServiceRequestedEventArgs2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Media_Playback")] + pub MediaPlaybackItem: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Playback"))] + MediaPlaybackItem: usize, +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaProtectionManager(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaProtectionManager, windows_core::IUnknown, windows_core::IInspectable); +impl MediaProtectionManager { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn ServiceRequested(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ServiceRequested)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveServiceRequested(&self, cookie: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveServiceRequested)(windows_core::Interface::as_raw(this), cookie).ok() } + } + pub fn RebootNeeded(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RebootNeeded)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveRebootNeeded(&self, cookie: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveRebootNeeded)(windows_core::Interface::as_raw(this), cookie).ok() } + } + pub fn ComponentLoadFailed(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ComponentLoadFailed)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveComponentLoadFailed(&self, cookie: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveComponentLoadFailed)(windows_core::Interface::as_raw(this), cookie).ok() } + } + #[cfg(feature = "Foundation_Collections")] + pub fn Properties(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MediaProtectionManager { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaProtectionManager { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaProtectionManager { + const NAME: &'static str = "Windows.Media.Protection.MediaProtectionManager"; +} +unsafe impl Send for MediaProtectionManager {} +unsafe impl Sync for MediaProtectionManager {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MediaProtectionServiceCompletion(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MediaProtectionServiceCompletion, windows_core::IUnknown, windows_core::IInspectable); +impl MediaProtectionServiceCompletion { + pub fn Complete(&self, success: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Complete)(windows_core::Interface::as_raw(this), success).ok() } + } +} +impl windows_core::RuntimeType for MediaProtectionServiceCompletion { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MediaProtectionServiceCompletion { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MediaProtectionServiceCompletion { + const NAME: &'static str = "Windows.Media.Protection.MediaProtectionServiceCompletion"; +} +unsafe impl Send for MediaProtectionServiceCompletion {} +unsafe impl Sync for MediaProtectionServiceCompletion {} +windows_core::imp::define_interface!(RebootNeededEventHandler, RebootNeededEventHandler_Vtbl, 0x64e12a45_973b_4a3a_b260_91898a49a82c); +impl windows_core::RuntimeType for RebootNeededEventHandler { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl RebootNeededEventHandler { + pub fn new) -> windows_core::Result<()> + Send + 'static>(invoke: F) -> Self { + let com = RebootNeededEventHandlerBox { vtable: &RebootNeededEventHandlerBox::::VTABLE, count: windows_core::imp::RefCount::new(1), invoke }; + unsafe { core::mem::transmute(windows_core::imp::Box::new(com)) } + } + pub fn Invoke(&self, sender: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Invoke)(windows_core::Interface::as_raw(this), sender.param().abi()).ok() } + } +} +#[repr(C)] +#[doc(hidden)] +pub struct RebootNeededEventHandler_Vtbl { + base__: windows_core::IUnknown_Vtbl, + Invoke: unsafe extern "system" fn(this: *mut core::ffi::c_void, sender: *mut core::ffi::c_void) -> windows_core::HRESULT, +} +#[repr(C)] +struct RebootNeededEventHandlerBox) -> windows_core::Result<()> + Send + 'static> { + vtable: *const RebootNeededEventHandler_Vtbl, + invoke: F, + count: windows_core::imp::RefCount, +} +impl) -> windows_core::Result<()> + Send + 'static> RebootNeededEventHandlerBox { + const VTABLE: RebootNeededEventHandler_Vtbl = RebootNeededEventHandler_Vtbl { base__: windows_core::IUnknown_Vtbl { QueryInterface: Self::QueryInterface, AddRef: Self::AddRef, Release: Self::Release }, Invoke: Self::Invoke }; + unsafe extern "system" fn QueryInterface(this: *mut core::ffi::c_void, iid: *const windows_core::GUID, interface: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this = this as *mut *mut core::ffi::c_void as *mut Self; + if iid.is_null() || interface.is_null() { + return windows_core::HRESULT(-2147467261); + } + *interface = if *iid == ::IID || *iid == ::IID || *iid == ::IID { + &mut (*this).vtable as *mut _ as _ + } else if *iid == ::IID { + (*this).count.add_ref(); + return windows_core::imp::marshaler(core::mem::transmute(&mut (*this).vtable as *mut _ as *mut core::ffi::c_void), interface); + } else { + core::ptr::null_mut() + }; + if (*interface).is_null() { + windows_core::HRESULT(-2147467262) + } else { + (*this).count.add_ref(); + windows_core::HRESULT(0) + } + } + } + unsafe extern "system" fn AddRef(this: *mut core::ffi::c_void) -> u32 { + unsafe { + let this = this as *mut *mut core::ffi::c_void as *mut Self; + (*this).count.add_ref() + } + } + unsafe extern "system" fn Release(this: *mut core::ffi::c_void) -> u32 { + unsafe { + let this = this as *mut *mut core::ffi::c_void as *mut Self; + let remaining = (*this).count.release(); + if remaining == 0 { + let _ = windows_core::imp::Box::from_raw(this); + } + remaining + } + } + unsafe extern "system" fn Invoke(this: *mut core::ffi::c_void, sender: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this = &mut *(this as *mut *mut core::ffi::c_void as *mut Self); + (this.invoke)(core::mem::transmute_copy(&sender)).into() + } + } +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct RevocationAndRenewalInformation(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(RevocationAndRenewalInformation, windows_core::IUnknown, windows_core::IInspectable); +impl RevocationAndRenewalInformation { + pub fn Items(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Items)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for RevocationAndRenewalInformation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for RevocationAndRenewalInformation { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for RevocationAndRenewalInformation { + const NAME: &'static str = "Windows.Media.Protection.RevocationAndRenewalInformation"; +} +unsafe impl Send for RevocationAndRenewalInformation {} +unsafe impl Sync for RevocationAndRenewalInformation {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct RevocationAndRenewalItem(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(RevocationAndRenewalItem, windows_core::IUnknown, windows_core::IInspectable); +impl RevocationAndRenewalItem { + pub fn Reasons(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Reasons)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn HeaderHash(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HeaderHash)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn PublicKeyHash(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PublicKeyHash)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Name(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn RenewalId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RenewalId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} +impl windows_core::RuntimeType for RevocationAndRenewalItem { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for RevocationAndRenewalItem { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for RevocationAndRenewalItem { + const NAME: &'static str = "Windows.Media.Protection.RevocationAndRenewalItem"; +} +unsafe impl Send for RevocationAndRenewalItem {} +unsafe impl Sync for RevocationAndRenewalItem {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct RevocationAndRenewalReasons(pub u32); +impl RevocationAndRenewalReasons { + pub const UserModeComponentLoad: Self = Self(1u32); + pub const KernelModeComponentLoad: Self = Self(2u32); + pub const AppComponent: Self = Self(4u32); + pub const GlobalRevocationListLoadFailed: Self = Self(16u32); + pub const InvalidGlobalRevocationListSignature: Self = Self(32u32); + pub const GlobalRevocationListAbsent: Self = Self(4096u32); + pub const ComponentRevoked: Self = Self(8192u32); + pub const InvalidComponentCertificateExtendedKeyUse: Self = Self(16384u32); + pub const ComponentCertificateRevoked: Self = Self(32768u32); + pub const InvalidComponentCertificateRoot: Self = Self(65536u32); + pub const ComponentHighSecurityCertificateRevoked: Self = Self(131072u32); + pub const ComponentLowSecurityCertificateRevoked: Self = Self(262144u32); + pub const BootDriverVerificationFailed: Self = Self(1048576u32); + pub const ComponentSignedWithTestCertificate: Self = Self(16777216u32); + pub const EncryptionFailure: Self = Self(268435456u32); +} +impl windows_core::TypeKind for RevocationAndRenewalReasons { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for RevocationAndRenewalReasons { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Protection.RevocationAndRenewalReasons;u4)"); +} +impl RevocationAndRenewalReasons { + pub const fn contains(&self, other: Self) -> bool { + self.0 & other.0 == other.0 + } +} +impl core::ops::BitOr for RevocationAndRenewalReasons { + type Output = Self; + fn bitor(self, other: Self) -> Self { + Self(self.0 | other.0) + } +} +impl core::ops::BitAnd for RevocationAndRenewalReasons { + type Output = Self; + fn bitand(self, other: Self) -> Self { + Self(self.0 & other.0) + } +} +impl core::ops::BitOrAssign for RevocationAndRenewalReasons { + fn bitor_assign(&mut self, other: Self) { + self.0.bitor_assign(other.0) + } +} +impl core::ops::BitAndAssign for RevocationAndRenewalReasons { + fn bitand_assign(&mut self, other: Self) { + self.0.bitand_assign(other.0) + } +} +impl core::ops::Not for RevocationAndRenewalReasons { + type Output = Self; + fn not(self) -> Self { + Self(self.0.not()) + } +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ServiceRequestedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(ServiceRequestedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl ServiceRequestedEventArgs { + pub fn Request(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Request)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Completion(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Completion)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Media_Playback")] + pub fn MediaPlaybackItem(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MediaPlaybackItem)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for ServiceRequestedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for ServiceRequestedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for ServiceRequestedEventArgs { + const NAME: &'static str = "Windows.Media.Protection.ServiceRequestedEventArgs"; +} +unsafe impl Send for ServiceRequestedEventArgs {} +unsafe impl Sync for ServiceRequestedEventArgs {} +windows_core::imp::define_interface!(ServiceRequestedEventHandler, ServiceRequestedEventHandler_Vtbl, 0xd2d690ba_cac9_48e1_95c0_d38495a84055); +impl windows_core::RuntimeType for ServiceRequestedEventHandler { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl ServiceRequestedEventHandler { + pub fn new, windows_core::Ref<'_, ServiceRequestedEventArgs>) -> windows_core::Result<()> + Send + 'static>(invoke: F) -> Self { + let com = ServiceRequestedEventHandlerBox { vtable: &ServiceRequestedEventHandlerBox::::VTABLE, count: windows_core::imp::RefCount::new(1), invoke }; + unsafe { core::mem::transmute(windows_core::imp::Box::new(com)) } + } + pub fn Invoke(&self, sender: P0, e: P1) -> windows_core::Result<()> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Invoke)(windows_core::Interface::as_raw(this), sender.param().abi(), e.param().abi()).ok() } + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ServiceRequestedEventHandler_Vtbl { + base__: windows_core::IUnknown_Vtbl, + Invoke: unsafe extern "system" fn(this: *mut core::ffi::c_void, sender: *mut core::ffi::c_void, e: *mut core::ffi::c_void) -> windows_core::HRESULT, +} +#[repr(C)] +struct ServiceRequestedEventHandlerBox, windows_core::Ref<'_, ServiceRequestedEventArgs>) -> windows_core::Result<()> + Send + 'static> { + vtable: *const ServiceRequestedEventHandler_Vtbl, + invoke: F, + count: windows_core::imp::RefCount, +} +impl, windows_core::Ref<'_, ServiceRequestedEventArgs>) -> windows_core::Result<()> + Send + 'static> ServiceRequestedEventHandlerBox { + const VTABLE: ServiceRequestedEventHandler_Vtbl = ServiceRequestedEventHandler_Vtbl { base__: windows_core::IUnknown_Vtbl { QueryInterface: Self::QueryInterface, AddRef: Self::AddRef, Release: Self::Release }, Invoke: Self::Invoke }; + unsafe extern "system" fn QueryInterface(this: *mut core::ffi::c_void, iid: *const windows_core::GUID, interface: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this = this as *mut *mut core::ffi::c_void as *mut Self; + if iid.is_null() || interface.is_null() { + return windows_core::HRESULT(-2147467261); + } + *interface = if *iid == ::IID || *iid == ::IID || *iid == ::IID { + &mut (*this).vtable as *mut _ as _ + } else if *iid == ::IID { + (*this).count.add_ref(); + return windows_core::imp::marshaler(core::mem::transmute(&mut (*this).vtable as *mut _ as *mut core::ffi::c_void), interface); + } else { + core::ptr::null_mut() + }; + if (*interface).is_null() { + windows_core::HRESULT(-2147467262) + } else { + (*this).count.add_ref(); + windows_core::HRESULT(0) + } + } + } + unsafe extern "system" fn AddRef(this: *mut core::ffi::c_void) -> u32 { + unsafe { + let this = this as *mut *mut core::ffi::c_void as *mut Self; + (*this).count.add_ref() + } + } + unsafe extern "system" fn Release(this: *mut core::ffi::c_void) -> u32 { + unsafe { + let this = this as *mut *mut core::ffi::c_void as *mut Self; + let remaining = (*this).count.release(); + if remaining == 0 { + let _ = windows_core::imp::Box::from_raw(this); + } + remaining + } + } + unsafe extern "system" fn Invoke(this: *mut core::ffi::c_void, sender: *mut core::ffi::c_void, e: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this = &mut *(this as *mut *mut core::ffi::c_void as *mut Self); + (this.invoke)(core::mem::transmute_copy(&sender), core::mem::transmute_copy(&e)).into() + } + } +} +} +#[cfg(feature = "Media_SpeechRecognition")] +pub mod SpeechRecognition{ +windows_core::imp::define_interface!(ISpeechContinuousRecognitionCompletedEventArgs, ISpeechContinuousRecognitionCompletedEventArgs_Vtbl, 0xe3d069bb_e30c_5e18_424b_7fbe81f8fbd0); +impl windows_core::RuntimeType for ISpeechContinuousRecognitionCompletedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechContinuousRecognitionCompletedEventArgs { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechContinuousRecognitionCompletedEventArgs"; +} +pub trait ISpeechContinuousRecognitionCompletedEventArgs_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; +} +impl ISpeechContinuousRecognitionCompletedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut SpeechRecognitionResultStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechContinuousRecognitionCompletedEventArgs_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Status: Status::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechContinuousRecognitionCompletedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Status: unsafe extern "system" fn(*mut core::ffi::c_void, *mut SpeechRecognitionResultStatus) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechContinuousRecognitionResultGeneratedEventArgs, ISpeechContinuousRecognitionResultGeneratedEventArgs_Vtbl, 0x19091e1e_6e7e_5a46_40fb_76594f786504); +impl windows_core::RuntimeType for ISpeechContinuousRecognitionResultGeneratedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechContinuousRecognitionResultGeneratedEventArgs { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechContinuousRecognitionResultGeneratedEventArgs"; +} +pub trait ISpeechContinuousRecognitionResultGeneratedEventArgs_Impl: windows_core::IUnknownImpl { + fn Result(&self) -> windows_core::Result; +} +impl ISpeechContinuousRecognitionResultGeneratedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Result(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechContinuousRecognitionResultGeneratedEventArgs_Impl::Result(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Result: Result::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechContinuousRecognitionResultGeneratedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Result: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechContinuousRecognitionSession, ISpeechContinuousRecognitionSession_Vtbl, 0x6a213c04_6614_49f8_99a2_b5e9b3a085c8); +impl windows_core::RuntimeType for ISpeechContinuousRecognitionSession { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechContinuousRecognitionSession { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechContinuousRecognitionSession"; +} +pub trait ISpeechContinuousRecognitionSession_Impl: windows_core::IUnknownImpl { + fn AutoStopSilenceTimeout(&self) -> windows_core::Result; + fn SetAutoStopSilenceTimeout(&self, value: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; + fn StartAsync(&self) -> windows_core::Result; + fn StartWithModeAsync(&self, mode: SpeechContinuousRecognitionMode) -> windows_core::Result; + fn StopAsync(&self) -> windows_core::Result; + fn CancelAsync(&self) -> windows_core::Result; + fn PauseAsync(&self) -> windows_core::Result; + fn Resume(&self) -> windows_core::Result<()>; + fn Completed(&self, value: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveCompleted(&self, value: i64) -> windows_core::Result<()>; + fn ResultGenerated(&self, value: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveResultGenerated(&self, value: i64) -> windows_core::Result<()>; +} +impl ISpeechContinuousRecognitionSession_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AutoStopSilenceTimeout(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechContinuousRecognitionSession_Impl::AutoStopSilenceTimeout(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAutoStopSilenceTimeout(this: *mut core::ffi::c_void, value: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechContinuousRecognitionSession_Impl::SetAutoStopSilenceTimeout(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn StartAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechContinuousRecognitionSession_Impl::StartAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StartWithModeAsync(this: *mut core::ffi::c_void, mode: SpeechContinuousRecognitionMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechContinuousRecognitionSession_Impl::StartWithModeAsync(this, mode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StopAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechContinuousRecognitionSession_Impl::StopAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CancelAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechContinuousRecognitionSession_Impl::CancelAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PauseAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechContinuousRecognitionSession_Impl::PauseAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Resume(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechContinuousRecognitionSession_Impl::Resume(this).into() + } + } + unsafe extern "system" fn Completed(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechContinuousRecognitionSession_Impl::Completed(this, core::mem::transmute_copy(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveCompleted(this: *mut core::ffi::c_void, value: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechContinuousRecognitionSession_Impl::RemoveCompleted(this, value).into() + } + } + unsafe extern "system" fn ResultGenerated(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechContinuousRecognitionSession_Impl::ResultGenerated(this, core::mem::transmute_copy(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveResultGenerated(this: *mut core::ffi::c_void, value: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechContinuousRecognitionSession_Impl::RemoveResultGenerated(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AutoStopSilenceTimeout: AutoStopSilenceTimeout::, + SetAutoStopSilenceTimeout: SetAutoStopSilenceTimeout::, + StartAsync: StartAsync::, + StartWithModeAsync: StartWithModeAsync::, + StopAsync: StopAsync::, + CancelAsync: CancelAsync::, + PauseAsync: PauseAsync::, + Resume: Resume::, + Completed: Completed::, + RemoveCompleted: RemoveCompleted::, + ResultGenerated: ResultGenerated::, + RemoveResultGenerated: RemoveResultGenerated::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechContinuousRecognitionSession_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AutoStopSilenceTimeout: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub SetAutoStopSilenceTimeout: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub StartAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub StartWithModeAsync: unsafe extern "system" fn(*mut core::ffi::c_void, SpeechContinuousRecognitionMode, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub StopAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CancelAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub PauseAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Resume: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, + pub Completed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveCompleted: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub ResultGenerated: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveResultGenerated: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognitionCompilationResult, ISpeechRecognitionCompilationResult_Vtbl, 0x407e6c5d_6ac7_4da4_9cc1_2fce32cf7489); +impl windows_core::RuntimeType for ISpeechRecognitionCompilationResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognitionCompilationResult { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognitionCompilationResult"; +} +pub trait ISpeechRecognitionCompilationResult_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; +} +impl ISpeechRecognitionCompilationResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut SpeechRecognitionResultStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionCompilationResult_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Status: Status:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognitionCompilationResult_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Status: unsafe extern "system" fn(*mut core::ffi::c_void, *mut SpeechRecognitionResultStatus) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognitionConstraint, ISpeechRecognitionConstraint_Vtbl, 0x79ac1628_4d68_43c4_8911_40dc4101b55b); +impl windows_core::RuntimeType for ISpeechRecognitionConstraint { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(ISpeechRecognitionConstraint, windows_core::IUnknown, windows_core::IInspectable); +impl ISpeechRecognitionConstraint { + pub fn IsEnabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetIsEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetIsEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Tag(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Tag)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetTag(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetTag)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Probability(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Probability)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetProbability(&self, value: SpeechRecognitionConstraintProbability) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetProbability)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeName for ISpeechRecognitionConstraint { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognitionConstraint"; +} +pub trait ISpeechRecognitionConstraint_Impl: windows_core::IUnknownImpl { + fn IsEnabled(&self) -> windows_core::Result; + fn SetIsEnabled(&self, value: bool) -> windows_core::Result<()>; + fn Tag(&self) -> windows_core::Result; + fn SetTag(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Type(&self) -> windows_core::Result; + fn Probability(&self) -> windows_core::Result; + fn SetProbability(&self, value: SpeechRecognitionConstraintProbability) -> windows_core::Result<()>; +} +impl ISpeechRecognitionConstraint_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionConstraint_Impl::IsEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetIsEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechRecognitionConstraint_Impl::SetIsEnabled(this, value).into() + } + } + unsafe extern "system" fn Tag(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionConstraint_Impl::Tag(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetTag(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechRecognitionConstraint_Impl::SetTag(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Type(this: *mut core::ffi::c_void, result__: *mut SpeechRecognitionConstraintType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionConstraint_Impl::Type(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Probability(this: *mut core::ffi::c_void, result__: *mut SpeechRecognitionConstraintProbability) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionConstraint_Impl::Probability(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetProbability(this: *mut core::ffi::c_void, value: SpeechRecognitionConstraintProbability) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechRecognitionConstraint_Impl::SetProbability(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsEnabled: IsEnabled::, + SetIsEnabled: SetIsEnabled::, + Tag: Tag::, + SetTag: SetTag::, + Type: Type::, + Probability: Probability::, + SetProbability: SetProbability::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognitionConstraint_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetIsEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub Tag: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetTag: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Type: unsafe extern "system" fn(*mut core::ffi::c_void, *mut SpeechRecognitionConstraintType) -> windows_core::HRESULT, + pub Probability: unsafe extern "system" fn(*mut core::ffi::c_void, *mut SpeechRecognitionConstraintProbability) -> windows_core::HRESULT, + pub SetProbability: unsafe extern "system" fn(*mut core::ffi::c_void, SpeechRecognitionConstraintProbability) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognitionGrammarFileConstraint, ISpeechRecognitionGrammarFileConstraint_Vtbl, 0xb5031a8f_85ca_4fa4_b11a_474fc41b3835); +impl windows_core::RuntimeType for ISpeechRecognitionGrammarFileConstraint { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for ISpeechRecognitionGrammarFileConstraint { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognitionGrammarFileConstraint"; +} +#[cfg(feature = "Storage_Streams")] +pub trait ISpeechRecognitionGrammarFileConstraint_Impl: ISpeechRecognitionConstraint_Impl { + fn GrammarFile(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl ISpeechRecognitionGrammarFileConstraint_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GrammarFile(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionGrammarFileConstraint_Impl::GrammarFile(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GrammarFile: GrammarFile::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognitionGrammarFileConstraint_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Storage_Streams")] + pub GrammarFile: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + GrammarFile: usize, +} +windows_core::imp::define_interface!(ISpeechRecognitionGrammarFileConstraintFactory, ISpeechRecognitionGrammarFileConstraintFactory_Vtbl, 0x3da770eb_c479_4c27_9f19_89974ef392d1); +impl windows_core::RuntimeType for ISpeechRecognitionGrammarFileConstraintFactory { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for ISpeechRecognitionGrammarFileConstraintFactory { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognitionGrammarFileConstraintFactory"; +} +#[cfg(feature = "Storage_Streams")] +pub trait ISpeechRecognitionGrammarFileConstraintFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, file: windows_core::Ref<'_, super::super::Storage::StorageFile>) -> windows_core::Result; + fn CreateWithTag(&self, file: windows_core::Ref<'_, super::super::Storage::StorageFile>, tag: &windows_core::HSTRING) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl ISpeechRecognitionGrammarFileConstraintFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, file: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionGrammarFileConstraintFactory_Impl::Create(this, core::mem::transmute_copy(&file)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateWithTag(this: *mut core::ffi::c_void, file: *mut core::ffi::c_void, tag: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionGrammarFileConstraintFactory_Impl::CreateWithTag(this, core::mem::transmute_copy(&file), core::mem::transmute(&tag)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Create: Create::, + CreateWithTag: CreateWithTag::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognitionGrammarFileConstraintFactory_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Storage_Streams")] + pub Create: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + Create: usize, + #[cfg(feature = "Storage_Streams")] + pub CreateWithTag: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + CreateWithTag: usize, +} +windows_core::imp::define_interface!(ISpeechRecognitionHypothesis, ISpeechRecognitionHypothesis_Vtbl, 0x7a7b25b0_99c5_4f7d_bf84_10aa1302b634); +impl windows_core::RuntimeType for ISpeechRecognitionHypothesis { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognitionHypothesis { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognitionHypothesis"; +} +pub trait ISpeechRecognitionHypothesis_Impl: windows_core::IUnknownImpl { + fn Text(&self) -> windows_core::Result; +} +impl ISpeechRecognitionHypothesis_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Text(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionHypothesis_Impl::Text(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Text: Text:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognitionHypothesis_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Text: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognitionHypothesisGeneratedEventArgs, ISpeechRecognitionHypothesisGeneratedEventArgs_Vtbl, 0x55161a7a_8023_5866_411d_1213bb271476); +impl windows_core::RuntimeType for ISpeechRecognitionHypothesisGeneratedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognitionHypothesisGeneratedEventArgs { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognitionHypothesisGeneratedEventArgs"; +} +pub trait ISpeechRecognitionHypothesisGeneratedEventArgs_Impl: windows_core::IUnknownImpl { + fn Hypothesis(&self) -> windows_core::Result; +} +impl ISpeechRecognitionHypothesisGeneratedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Hypothesis(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionHypothesisGeneratedEventArgs_Impl::Hypothesis(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Hypothesis: Hypothesis::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognitionHypothesisGeneratedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Hypothesis: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognitionListConstraint, ISpeechRecognitionListConstraint_Vtbl, 0x09c487e9_e4ad_4526_81f2_4946fb481d98); +impl windows_core::RuntimeType for ISpeechRecognitionListConstraint { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognitionListConstraint { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognitionListConstraint"; +} +pub trait ISpeechRecognitionListConstraint_Impl: ISpeechRecognitionConstraint_Impl { + fn Commands(&self) -> windows_core::Result>; +} +impl ISpeechRecognitionListConstraint_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Commands(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionListConstraint_Impl::Commands(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Commands: Commands:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognitionListConstraint_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Commands: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognitionListConstraintFactory, ISpeechRecognitionListConstraintFactory_Vtbl, 0x40f3cdc7_562a_426a_9f3b_3b4e282be1d5); +impl windows_core::RuntimeType for ISpeechRecognitionListConstraintFactory { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognitionListConstraintFactory { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognitionListConstraintFactory"; +} +pub trait ISpeechRecognitionListConstraintFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, commands: windows_core::Ref<'_, windows_collections::IIterable>) -> windows_core::Result; + fn CreateWithTag(&self, commands: windows_core::Ref<'_, windows_collections::IIterable>, tag: &windows_core::HSTRING) -> windows_core::Result; +} +impl ISpeechRecognitionListConstraintFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, commands: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionListConstraintFactory_Impl::Create(this, core::mem::transmute_copy(&commands)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateWithTag(this: *mut core::ffi::c_void, commands: *mut core::ffi::c_void, tag: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionListConstraintFactory_Impl::CreateWithTag(this, core::mem::transmute_copy(&commands), core::mem::transmute(&tag)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Create: Create::, + CreateWithTag: CreateWithTag::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognitionListConstraintFactory_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Create: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateWithTag: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognitionQualityDegradingEventArgs, ISpeechRecognitionQualityDegradingEventArgs_Vtbl, 0x4fe24105_8c3a_4c7e_8d0a_5bd4f5b14ad8); +impl windows_core::RuntimeType for ISpeechRecognitionQualityDegradingEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognitionQualityDegradingEventArgs { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognitionQualityDegradingEventArgs"; +} +pub trait ISpeechRecognitionQualityDegradingEventArgs_Impl: windows_core::IUnknownImpl { + fn Problem(&self) -> windows_core::Result; +} +impl ISpeechRecognitionQualityDegradingEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Problem(this: *mut core::ffi::c_void, result__: *mut SpeechRecognitionAudioProblem) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionQualityDegradingEventArgs_Impl::Problem(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Problem: Problem::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognitionQualityDegradingEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Problem: unsafe extern "system" fn(*mut core::ffi::c_void, *mut SpeechRecognitionAudioProblem) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognitionResult, ISpeechRecognitionResult_Vtbl, 0x4e303157_034e_4652_857e_d0454cc4beec); +impl windows_core::RuntimeType for ISpeechRecognitionResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognitionResult { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognitionResult"; +} +pub trait ISpeechRecognitionResult_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; + fn Text(&self) -> windows_core::Result; + fn Confidence(&self) -> windows_core::Result; + fn SemanticInterpretation(&self) -> windows_core::Result; + fn GetAlternates(&self, maxAlternates: u32) -> windows_core::Result>; + fn Constraint(&self) -> windows_core::Result; + fn RulePath(&self) -> windows_core::Result>; + fn RawConfidence(&self) -> windows_core::Result; +} +impl ISpeechRecognitionResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut SpeechRecognitionResultStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionResult_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Text(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionResult_Impl::Text(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Confidence(this: *mut core::ffi::c_void, result__: *mut SpeechRecognitionConfidence) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionResult_Impl::Confidence(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SemanticInterpretation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionResult_Impl::SemanticInterpretation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetAlternates(this: *mut core::ffi::c_void, maxalternates: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionResult_Impl::GetAlternates(this, maxalternates) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Constraint(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionResult_Impl::Constraint(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RulePath(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionResult_Impl::RulePath(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RawConfidence(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionResult_Impl::RawConfidence(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Status: Status::, + Text: Text::, + Confidence: Confidence::, + SemanticInterpretation: SemanticInterpretation::, + GetAlternates: GetAlternates::, + Constraint: Constraint::, + RulePath: RulePath::, + RawConfidence: RawConfidence::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognitionResult_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Status: unsafe extern "system" fn(*mut core::ffi::c_void, *mut SpeechRecognitionResultStatus) -> windows_core::HRESULT, + pub Text: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Confidence: unsafe extern "system" fn(*mut core::ffi::c_void, *mut SpeechRecognitionConfidence) -> windows_core::HRESULT, + pub SemanticInterpretation: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetAlternates: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Constraint: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub RulePath: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub RawConfidence: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognitionResult2, ISpeechRecognitionResult2_Vtbl, 0xaf7ed1ba_451b_4166_a0c1_1ffe84032d03); +impl windows_core::RuntimeType for ISpeechRecognitionResult2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognitionResult2 { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognitionResult2"; +} +pub trait ISpeechRecognitionResult2_Impl: windows_core::IUnknownImpl { + fn PhraseStartTime(&self) -> windows_core::Result; + fn PhraseDuration(&self) -> windows_core::Result; +} +impl ISpeechRecognitionResult2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn PhraseStartTime(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionResult2_Impl::PhraseStartTime(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PhraseDuration(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionResult2_Impl::PhraseDuration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + PhraseStartTime: PhraseStartTime::, + PhraseDuration: PhraseDuration::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognitionResult2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub PhraseStartTime: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::DateTime) -> windows_core::HRESULT, + pub PhraseDuration: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognitionSemanticInterpretation, ISpeechRecognitionSemanticInterpretation_Vtbl, 0xaae1da9b_7e32_4c1f_89fe_0c65f486f52e); +impl windows_core::RuntimeType for ISpeechRecognitionSemanticInterpretation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognitionSemanticInterpretation { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognitionSemanticInterpretation"; +} +pub trait ISpeechRecognitionSemanticInterpretation_Impl: windows_core::IUnknownImpl { + fn Properties(&self) -> windows_core::Result>>; +} +impl ISpeechRecognitionSemanticInterpretation_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionSemanticInterpretation_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Properties: Properties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognitionSemanticInterpretation_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Properties: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognitionTopicConstraint, ISpeechRecognitionTopicConstraint_Vtbl, 0xbf6fdf19_825d_4e69_a681_36e48cf1c93e); +impl windows_core::RuntimeType for ISpeechRecognitionTopicConstraint { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognitionTopicConstraint { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognitionTopicConstraint"; +} +pub trait ISpeechRecognitionTopicConstraint_Impl: ISpeechRecognitionConstraint_Impl { + fn Scenario(&self) -> windows_core::Result; + fn TopicHint(&self) -> windows_core::Result; +} +impl ISpeechRecognitionTopicConstraint_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Scenario(this: *mut core::ffi::c_void, result__: *mut SpeechRecognitionScenario) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionTopicConstraint_Impl::Scenario(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TopicHint(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionTopicConstraint_Impl::TopicHint(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Scenario: Scenario::, + TopicHint: TopicHint::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognitionTopicConstraint_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Scenario: unsafe extern "system" fn(*mut core::ffi::c_void, *mut SpeechRecognitionScenario) -> windows_core::HRESULT, + pub TopicHint: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognitionTopicConstraintFactory, ISpeechRecognitionTopicConstraintFactory_Vtbl, 0x6e6863df_ec05_47d7_a5df_56a3431e58d2); +impl windows_core::RuntimeType for ISpeechRecognitionTopicConstraintFactory { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognitionTopicConstraintFactory { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognitionTopicConstraintFactory"; +} +pub trait ISpeechRecognitionTopicConstraintFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, scenario: SpeechRecognitionScenario, topicHint: &windows_core::HSTRING) -> windows_core::Result; + fn CreateWithTag(&self, scenario: SpeechRecognitionScenario, topicHint: &windows_core::HSTRING, tag: &windows_core::HSTRING) -> windows_core::Result; +} +impl ISpeechRecognitionTopicConstraintFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, scenario: SpeechRecognitionScenario, topichint: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionTopicConstraintFactory_Impl::Create(this, scenario, core::mem::transmute(&topichint)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateWithTag(this: *mut core::ffi::c_void, scenario: SpeechRecognitionScenario, topichint: *mut core::ffi::c_void, tag: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognitionTopicConstraintFactory_Impl::CreateWithTag(this, scenario, core::mem::transmute(&topichint), core::mem::transmute(&tag)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Create: Create::, + CreateWithTag: CreateWithTag::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognitionTopicConstraintFactory_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Create: unsafe extern "system" fn(*mut core::ffi::c_void, SpeechRecognitionScenario, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateWithTag: unsafe extern "system" fn(*mut core::ffi::c_void, SpeechRecognitionScenario, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognitionVoiceCommandDefinitionConstraint, ISpeechRecognitionVoiceCommandDefinitionConstraint_Vtbl, 0xf2791c2b_1ef4_4ae7_9d77_b6ff10b8a3c2); +impl windows_core::RuntimeType for ISpeechRecognitionVoiceCommandDefinitionConstraint { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognitionVoiceCommandDefinitionConstraint { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognitionVoiceCommandDefinitionConstraint"; +} +pub trait ISpeechRecognitionVoiceCommandDefinitionConstraint_Impl: ISpeechRecognitionConstraint_Impl {} +impl ISpeechRecognitionVoiceCommandDefinitionConstraint_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognitionVoiceCommandDefinitionConstraint_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, +} +windows_core::imp::define_interface!(ISpeechRecognizer, ISpeechRecognizer_Vtbl, 0x0bc3c9cb_c26a_40f2_aeb5_8096b2e48073); +impl windows_core::RuntimeType for ISpeechRecognizer { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Globalization")] +impl windows_core::RuntimeName for ISpeechRecognizer { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognizer"; +} +#[cfg(feature = "Globalization")] +pub trait ISpeechRecognizer_Impl: super::super::Foundation::IClosable_Impl { + fn CurrentLanguage(&self) -> windows_core::Result; + fn Constraints(&self) -> windows_core::Result>; + fn Timeouts(&self) -> windows_core::Result; + fn UIOptions(&self) -> windows_core::Result; + fn CompileConstraintsAsync(&self) -> windows_core::Result>; + fn RecognizeAsync(&self) -> windows_core::Result>; + fn RecognizeWithUIAsync(&self) -> windows_core::Result>; + fn RecognitionQualityDegrading(&self, speechRecognitionQualityDegradingHandler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveRecognitionQualityDegrading(&self, cookie: i64) -> windows_core::Result<()>; + fn StateChanged(&self, stateChangedHandler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveStateChanged(&self, cookie: i64) -> windows_core::Result<()>; +} +#[cfg(feature = "Globalization")] +impl ISpeechRecognizer_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CurrentLanguage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizer_Impl::CurrentLanguage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Constraints(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizer_Impl::Constraints(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Timeouts(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizer_Impl::Timeouts(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn UIOptions(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizer_Impl::UIOptions(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CompileConstraintsAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizer_Impl::CompileConstraintsAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RecognizeAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizer_Impl::RecognizeAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RecognizeWithUIAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizer_Impl::RecognizeWithUIAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RecognitionQualityDegrading(this: *mut core::ffi::c_void, speechrecognitionqualitydegradinghandler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizer_Impl::RecognitionQualityDegrading(this, core::mem::transmute_copy(&speechrecognitionqualitydegradinghandler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveRecognitionQualityDegrading(this: *mut core::ffi::c_void, cookie: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechRecognizer_Impl::RemoveRecognitionQualityDegrading(this, cookie).into() + } + } + unsafe extern "system" fn StateChanged(this: *mut core::ffi::c_void, statechangedhandler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizer_Impl::StateChanged(this, core::mem::transmute_copy(&statechangedhandler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveStateChanged(this: *mut core::ffi::c_void, cookie: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechRecognizer_Impl::RemoveStateChanged(this, cookie).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CurrentLanguage: CurrentLanguage::, + Constraints: Constraints::, + Timeouts: Timeouts::, + UIOptions: UIOptions::, + CompileConstraintsAsync: CompileConstraintsAsync::, + RecognizeAsync: RecognizeAsync::, + RecognizeWithUIAsync: RecognizeWithUIAsync::, + RecognitionQualityDegrading: RecognitionQualityDegrading::, + RemoveRecognitionQualityDegrading: RemoveRecognitionQualityDegrading::, + StateChanged: StateChanged::, + RemoveStateChanged: RemoveStateChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognizer_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Globalization")] + pub CurrentLanguage: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Globalization"))] + CurrentLanguage: usize, + pub Constraints: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Timeouts: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub UIOptions: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CompileConstraintsAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub RecognizeAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub RecognizeWithUIAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub RecognitionQualityDegrading: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveRecognitionQualityDegrading: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub StateChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveStateChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognizer2, ISpeechRecognizer2_Vtbl, 0x63c9baf1_91e3_4ea4_86a1_7c3867d084a6); +impl windows_core::RuntimeType for ISpeechRecognizer2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognizer2 { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognizer2"; +} +pub trait ISpeechRecognizer2_Impl: windows_core::IUnknownImpl { + fn ContinuousRecognitionSession(&self) -> windows_core::Result; + fn State(&self) -> windows_core::Result; + fn StopRecognitionAsync(&self) -> windows_core::Result; + fn HypothesisGenerated(&self, value: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveHypothesisGenerated(&self, value: i64) -> windows_core::Result<()>; +} +impl ISpeechRecognizer2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ContinuousRecognitionSession(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizer2_Impl::ContinuousRecognitionSession(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn State(this: *mut core::ffi::c_void, result__: *mut SpeechRecognizerState) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizer2_Impl::State(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StopRecognitionAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizer2_Impl::StopRecognitionAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn HypothesisGenerated(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizer2_Impl::HypothesisGenerated(this, core::mem::transmute_copy(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveHypothesisGenerated(this: *mut core::ffi::c_void, value: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechRecognizer2_Impl::RemoveHypothesisGenerated(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ContinuousRecognitionSession: ContinuousRecognitionSession::, + State: State::, + StopRecognitionAsync: StopRecognitionAsync::, + HypothesisGenerated: HypothesisGenerated::, + RemoveHypothesisGenerated: RemoveHypothesisGenerated::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognizer2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ContinuousRecognitionSession: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub State: unsafe extern "system" fn(*mut core::ffi::c_void, *mut SpeechRecognizerState) -> windows_core::HRESULT, + pub StopRecognitionAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub HypothesisGenerated: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveHypothesisGenerated: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognizerFactory, ISpeechRecognizerFactory_Vtbl, 0x60c488dd_7fb8_4033_ac70_d046f64818e1); +impl windows_core::RuntimeType for ISpeechRecognizerFactory { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Globalization")] +impl windows_core::RuntimeName for ISpeechRecognizerFactory { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognizerFactory"; +} +#[cfg(feature = "Globalization")] +pub trait ISpeechRecognizerFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, language: windows_core::Ref<'_, super::super::Globalization::Language>) -> windows_core::Result; +} +#[cfg(feature = "Globalization")] +impl ISpeechRecognizerFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, language: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizerFactory_Impl::Create(this, core::mem::transmute_copy(&language)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognizerFactory_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Globalization")] + pub Create: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Globalization"))] + Create: usize, +} +windows_core::imp::define_interface!(ISpeechRecognizerStateChangedEventArgs, ISpeechRecognizerStateChangedEventArgs_Vtbl, 0x563d4f09_ba03_4bad_ad81_ddc6c4dab0c3); +impl windows_core::RuntimeType for ISpeechRecognizerStateChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognizerStateChangedEventArgs { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognizerStateChangedEventArgs"; +} +pub trait ISpeechRecognizerStateChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn State(&self) -> windows_core::Result; +} +impl ISpeechRecognizerStateChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn State(this: *mut core::ffi::c_void, result__: *mut SpeechRecognizerState) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizerStateChangedEventArgs_Impl::State(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), State: State:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognizerStateChangedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub State: unsafe extern "system" fn(*mut core::ffi::c_void, *mut SpeechRecognizerState) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognizerStatics, ISpeechRecognizerStatics_Vtbl, 0x87a35eac_a7dc_4b0b_bcc9_24f47c0b7ebf); +impl windows_core::RuntimeType for ISpeechRecognizerStatics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Globalization")] +impl windows_core::RuntimeName for ISpeechRecognizerStatics { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognizerStatics"; +} +#[cfg(feature = "Globalization")] +pub trait ISpeechRecognizerStatics_Impl: windows_core::IUnknownImpl { + fn SystemSpeechLanguage(&self) -> windows_core::Result; + fn SupportedTopicLanguages(&self) -> windows_core::Result>; + fn SupportedGrammarLanguages(&self) -> windows_core::Result>; +} +#[cfg(feature = "Globalization")] +impl ISpeechRecognizerStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SystemSpeechLanguage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizerStatics_Impl::SystemSpeechLanguage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedTopicLanguages(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizerStatics_Impl::SupportedTopicLanguages(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SupportedGrammarLanguages(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizerStatics_Impl::SupportedGrammarLanguages(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SystemSpeechLanguage: SystemSpeechLanguage::, + SupportedTopicLanguages: SupportedTopicLanguages::, + SupportedGrammarLanguages: SupportedGrammarLanguages::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognizerStatics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Globalization")] + pub SystemSpeechLanguage: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Globalization"))] + SystemSpeechLanguage: usize, + #[cfg(feature = "Globalization")] + pub SupportedTopicLanguages: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Globalization"))] + SupportedTopicLanguages: usize, + #[cfg(feature = "Globalization")] + pub SupportedGrammarLanguages: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Globalization"))] + SupportedGrammarLanguages: usize, +} +windows_core::imp::define_interface!(ISpeechRecognizerStatics2, ISpeechRecognizerStatics2_Vtbl, 0x1d1b0d95_7565_4ef9_a2f3_ba15162a96cf); +impl windows_core::RuntimeType for ISpeechRecognizerStatics2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Globalization")] +impl windows_core::RuntimeName for ISpeechRecognizerStatics2 { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognizerStatics2"; +} +#[cfg(feature = "Globalization")] +pub trait ISpeechRecognizerStatics2_Impl: windows_core::IUnknownImpl { + fn TrySetSystemSpeechLanguageAsync(&self, speechLanguage: windows_core::Ref<'_, super::super::Globalization::Language>) -> windows_core::Result>; +} +#[cfg(feature = "Globalization")] +impl ISpeechRecognizerStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TrySetSystemSpeechLanguageAsync(this: *mut core::ffi::c_void, speechlanguage: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizerStatics2_Impl::TrySetSystemSpeechLanguageAsync(this, core::mem::transmute_copy(&speechlanguage)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + TrySetSystemSpeechLanguageAsync: TrySetSystemSpeechLanguageAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognizerStatics2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Globalization")] + pub TrySetSystemSpeechLanguageAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Globalization"))] + TrySetSystemSpeechLanguageAsync: usize, +} +windows_core::imp::define_interface!(ISpeechRecognizerTimeouts, ISpeechRecognizerTimeouts_Vtbl, 0x2ef76fca_6a3c_4dca_a153_df1bc88a79af); +impl windows_core::RuntimeType for ISpeechRecognizerTimeouts { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognizerTimeouts { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognizerTimeouts"; +} +pub trait ISpeechRecognizerTimeouts_Impl: windows_core::IUnknownImpl { + fn InitialSilenceTimeout(&self) -> windows_core::Result; + fn SetInitialSilenceTimeout(&self, value: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; + fn EndSilenceTimeout(&self) -> windows_core::Result; + fn SetEndSilenceTimeout(&self, value: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; + fn BabbleTimeout(&self) -> windows_core::Result; + fn SetBabbleTimeout(&self, value: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; +} +impl ISpeechRecognizerTimeouts_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn InitialSilenceTimeout(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizerTimeouts_Impl::InitialSilenceTimeout(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetInitialSilenceTimeout(this: *mut core::ffi::c_void, value: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechRecognizerTimeouts_Impl::SetInitialSilenceTimeout(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn EndSilenceTimeout(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizerTimeouts_Impl::EndSilenceTimeout(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetEndSilenceTimeout(this: *mut core::ffi::c_void, value: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechRecognizerTimeouts_Impl::SetEndSilenceTimeout(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn BabbleTimeout(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizerTimeouts_Impl::BabbleTimeout(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetBabbleTimeout(this: *mut core::ffi::c_void, value: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechRecognizerTimeouts_Impl::SetBabbleTimeout(this, core::mem::transmute(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + InitialSilenceTimeout: InitialSilenceTimeout::, + SetInitialSilenceTimeout: SetInitialSilenceTimeout::, + EndSilenceTimeout: EndSilenceTimeout::, + SetEndSilenceTimeout: SetEndSilenceTimeout::, + BabbleTimeout: BabbleTimeout::, + SetBabbleTimeout: SetBabbleTimeout::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognizerTimeouts_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub InitialSilenceTimeout: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub SetInitialSilenceTimeout: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub EndSilenceTimeout: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub SetEndSilenceTimeout: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub BabbleTimeout: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub SetBabbleTimeout: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::TimeSpan) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechRecognizerUIOptions, ISpeechRecognizerUIOptions_Vtbl, 0x7888d641_b92b_44ba_a25f_d1864630641f); +impl windows_core::RuntimeType for ISpeechRecognizerUIOptions { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechRecognizerUIOptions { + const NAME: &'static str = "Windows.Media.SpeechRecognition.ISpeechRecognizerUIOptions"; +} +pub trait ISpeechRecognizerUIOptions_Impl: windows_core::IUnknownImpl { + fn ExampleText(&self) -> windows_core::Result; + fn SetExampleText(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn AudiblePrompt(&self) -> windows_core::Result; + fn SetAudiblePrompt(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn IsReadBackEnabled(&self) -> windows_core::Result; + fn SetIsReadBackEnabled(&self, value: bool) -> windows_core::Result<()>; + fn ShowConfirmation(&self) -> windows_core::Result; + fn SetShowConfirmation(&self, value: bool) -> windows_core::Result<()>; +} +impl ISpeechRecognizerUIOptions_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ExampleText(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizerUIOptions_Impl::ExampleText(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetExampleText(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechRecognizerUIOptions_Impl::SetExampleText(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn AudiblePrompt(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizerUIOptions_Impl::AudiblePrompt(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAudiblePrompt(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechRecognizerUIOptions_Impl::SetAudiblePrompt(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn IsReadBackEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizerUIOptions_Impl::IsReadBackEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetIsReadBackEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechRecognizerUIOptions_Impl::SetIsReadBackEnabled(this, value).into() + } + } + unsafe extern "system" fn ShowConfirmation(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechRecognizerUIOptions_Impl::ShowConfirmation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetShowConfirmation(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechRecognizerUIOptions_Impl::SetShowConfirmation(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ExampleText: ExampleText::, + SetExampleText: SetExampleText::, + AudiblePrompt: AudiblePrompt::, + SetAudiblePrompt: SetAudiblePrompt::, + IsReadBackEnabled: IsReadBackEnabled::, + SetIsReadBackEnabled: SetIsReadBackEnabled::, + ShowConfirmation: ShowConfirmation::, + SetShowConfirmation: SetShowConfirmation::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechRecognizerUIOptions_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ExampleText: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetExampleText: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub AudiblePrompt: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetAudiblePrompt: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub IsReadBackEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetIsReadBackEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub ShowConfirmation: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetShowConfirmation: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVoiceCommandManager, IVoiceCommandManager_Vtbl, 0xaa3a8dd5_b6e7_4ee2_baa9_dd6baced0a2b); +impl windows_core::RuntimeType for IVoiceCommandManager { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IVoiceCommandManager { + const NAME: &'static str = "Windows.Media.SpeechRecognition.IVoiceCommandManager"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IVoiceCommandManager_Impl: windows_core::IUnknownImpl { + fn InstallCommandSetsFromStorageFileAsync(&self, file: windows_core::Ref<'_, super::super::Storage::StorageFile>) -> windows_core::Result; + fn InstalledCommandSets(&self) -> windows_core::Result>; +} +#[cfg(feature = "Storage_Streams")] +impl IVoiceCommandManager_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn InstallCommandSetsFromStorageFileAsync(this: *mut core::ffi::c_void, file: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVoiceCommandManager_Impl::InstallCommandSetsFromStorageFileAsync(this, core::mem::transmute_copy(&file)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn InstalledCommandSets(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVoiceCommandManager_Impl::InstalledCommandSets(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + InstallCommandSetsFromStorageFileAsync: InstallCommandSetsFromStorageFileAsync::, + InstalledCommandSets: InstalledCommandSets::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVoiceCommandManager_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Storage_Streams")] + pub InstallCommandSetsFromStorageFileAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + InstallCommandSetsFromStorageFileAsync: usize, + pub InstalledCommandSets: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVoiceCommandSet, IVoiceCommandSet_Vtbl, 0x0bedda75_46e6_4b11_a088_5c68632899b5); +impl windows_core::RuntimeType for IVoiceCommandSet { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVoiceCommandSet { + const NAME: &'static str = "Windows.Media.SpeechRecognition.IVoiceCommandSet"; +} +pub trait IVoiceCommandSet_Impl: windows_core::IUnknownImpl { + fn Language(&self) -> windows_core::Result; + fn Name(&self) -> windows_core::Result; + fn SetPhraseListAsync(&self, phraseListName: &windows_core::HSTRING, phraseList: windows_core::Ref<'_, windows_collections::IIterable>) -> windows_core::Result; +} +impl IVoiceCommandSet_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Language(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVoiceCommandSet_Impl::Language(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Name(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVoiceCommandSet_Impl::Name(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPhraseListAsync(this: *mut core::ffi::c_void, phraselistname: *mut core::ffi::c_void, phraselist: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVoiceCommandSet_Impl::SetPhraseListAsync(this, core::mem::transmute(&phraselistname), core::mem::transmute_copy(&phraselist)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Language: Language::, + Name: Name::, + SetPhraseListAsync: SetPhraseListAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVoiceCommandSet_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Language: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Name: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetPhraseListAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechContinuousRecognitionCompletedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechContinuousRecognitionCompletedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl SpeechContinuousRecognitionCompletedEventArgs { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for SpeechContinuousRecognitionCompletedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechContinuousRecognitionCompletedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechContinuousRecognitionCompletedEventArgs { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechContinuousRecognitionCompletedEventArgs"; +} +unsafe impl Send for SpeechContinuousRecognitionCompletedEventArgs {} +unsafe impl Sync for SpeechContinuousRecognitionCompletedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct SpeechContinuousRecognitionMode(pub i32); +impl SpeechContinuousRecognitionMode { + pub const Default: Self = Self(0i32); + pub const PauseOnRecognition: Self = Self(1i32); +} +impl windows_core::TypeKind for SpeechContinuousRecognitionMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for SpeechContinuousRecognitionMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.SpeechRecognition.SpeechContinuousRecognitionMode;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechContinuousRecognitionResultGeneratedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechContinuousRecognitionResultGeneratedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl SpeechContinuousRecognitionResultGeneratedEventArgs { + pub fn Result(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Result)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for SpeechContinuousRecognitionResultGeneratedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechContinuousRecognitionResultGeneratedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechContinuousRecognitionResultGeneratedEventArgs { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechContinuousRecognitionResultGeneratedEventArgs"; +} +unsafe impl Send for SpeechContinuousRecognitionResultGeneratedEventArgs {} +unsafe impl Sync for SpeechContinuousRecognitionResultGeneratedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechContinuousRecognitionSession(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechContinuousRecognitionSession, windows_core::IUnknown, windows_core::IInspectable); +impl SpeechContinuousRecognitionSession { + pub fn AutoStopSilenceTimeout(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AutoStopSilenceTimeout)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAutoStopSilenceTimeout(&self, value: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAutoStopSilenceTimeout)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn StartAsync(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StartAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn StartWithModeAsync(&self, mode: SpeechContinuousRecognitionMode) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StartWithModeAsync)(windows_core::Interface::as_raw(this), mode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn StopAsync(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StopAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CancelAsync(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CancelAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PauseAsync(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PauseAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Resume(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Resume)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn Completed(&self, value: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Completed)(windows_core::Interface::as_raw(this), value.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveCompleted(&self, value: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveCompleted)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ResultGenerated(&self, value: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResultGenerated)(windows_core::Interface::as_raw(this), value.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveResultGenerated(&self, value: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveResultGenerated)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for SpeechContinuousRecognitionSession { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechContinuousRecognitionSession { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechContinuousRecognitionSession { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechContinuousRecognitionSession"; +} +unsafe impl Send for SpeechContinuousRecognitionSession {} +unsafe impl Sync for SpeechContinuousRecognitionSession {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct SpeechRecognitionAudioProblem(pub i32); +impl SpeechRecognitionAudioProblem { + pub const None: Self = Self(0i32); + pub const TooNoisy: Self = Self(1i32); + pub const NoSignal: Self = Self(2i32); + pub const TooLoud: Self = Self(3i32); + pub const TooQuiet: Self = Self(4i32); + pub const TooFast: Self = Self(5i32); + pub const TooSlow: Self = Self(6i32); +} +impl windows_core::TypeKind for SpeechRecognitionAudioProblem { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for SpeechRecognitionAudioProblem { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.SpeechRecognition.SpeechRecognitionAudioProblem;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechRecognitionCompilationResult(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechRecognitionCompilationResult, windows_core::IUnknown, windows_core::IInspectable); +impl SpeechRecognitionCompilationResult { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for SpeechRecognitionCompilationResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechRecognitionCompilationResult { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechRecognitionCompilationResult { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechRecognitionCompilationResult"; +} +unsafe impl Send for SpeechRecognitionCompilationResult {} +unsafe impl Sync for SpeechRecognitionCompilationResult {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct SpeechRecognitionConfidence(pub i32); +impl SpeechRecognitionConfidence { + pub const High: Self = Self(0i32); + pub const Medium: Self = Self(1i32); + pub const Low: Self = Self(2i32); + pub const Rejected: Self = Self(3i32); +} +impl windows_core::TypeKind for SpeechRecognitionConfidence { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for SpeechRecognitionConfidence { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.SpeechRecognition.SpeechRecognitionConfidence;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct SpeechRecognitionConstraintProbability(pub i32); +impl SpeechRecognitionConstraintProbability { + pub const Default: Self = Self(0i32); + pub const Min: Self = Self(1i32); + pub const Max: Self = Self(2i32); +} +impl windows_core::TypeKind for SpeechRecognitionConstraintProbability { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for SpeechRecognitionConstraintProbability { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.SpeechRecognition.SpeechRecognitionConstraintProbability;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct SpeechRecognitionConstraintType(pub i32); +impl SpeechRecognitionConstraintType { + pub const Topic: Self = Self(0i32); + pub const List: Self = Self(1i32); + pub const Grammar: Self = Self(2i32); + pub const VoiceCommandDefinition: Self = Self(3i32); +} +impl windows_core::TypeKind for SpeechRecognitionConstraintType { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for SpeechRecognitionConstraintType { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.SpeechRecognition.SpeechRecognitionConstraintType;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechRecognitionGrammarFileConstraint(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechRecognitionGrammarFileConstraint, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(SpeechRecognitionGrammarFileConstraint, ISpeechRecognitionConstraint); +impl SpeechRecognitionGrammarFileConstraint { + pub fn IsEnabled(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetIsEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetIsEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Tag(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Tag)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetTag(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetTag)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Probability(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Probability)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetProbability(&self, value: SpeechRecognitionConstraintProbability) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetProbability)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn GrammarFile(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GrammarFile)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn Create(file: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::ISpeechRecognitionGrammarFileConstraintFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), file.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateWithTag(file: P0, tag: &windows_core::HSTRING) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::ISpeechRecognitionGrammarFileConstraintFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWithTag)(windows_core::Interface::as_raw(this), file.param().abi(), core::mem::transmute_copy(tag), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn ISpeechRecognitionGrammarFileConstraintFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for SpeechRecognitionGrammarFileConstraint { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechRecognitionGrammarFileConstraint { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechRecognitionGrammarFileConstraint { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechRecognitionGrammarFileConstraint"; +} +unsafe impl Send for SpeechRecognitionGrammarFileConstraint {} +unsafe impl Sync for SpeechRecognitionGrammarFileConstraint {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechRecognitionHypothesis(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechRecognitionHypothesis, windows_core::IUnknown, windows_core::IInspectable); +impl SpeechRecognitionHypothesis { + pub fn Text(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Text)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} +impl windows_core::RuntimeType for SpeechRecognitionHypothesis { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechRecognitionHypothesis { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechRecognitionHypothesis { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechRecognitionHypothesis"; +} +unsafe impl Send for SpeechRecognitionHypothesis {} +unsafe impl Sync for SpeechRecognitionHypothesis {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechRecognitionHypothesisGeneratedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechRecognitionHypothesisGeneratedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl SpeechRecognitionHypothesisGeneratedEventArgs { + pub fn Hypothesis(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Hypothesis)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for SpeechRecognitionHypothesisGeneratedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechRecognitionHypothesisGeneratedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechRecognitionHypothesisGeneratedEventArgs { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechRecognitionHypothesisGeneratedEventArgs"; +} +unsafe impl Send for SpeechRecognitionHypothesisGeneratedEventArgs {} +unsafe impl Sync for SpeechRecognitionHypothesisGeneratedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechRecognitionListConstraint(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechRecognitionListConstraint, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(SpeechRecognitionListConstraint, ISpeechRecognitionConstraint); +impl SpeechRecognitionListConstraint { + pub fn IsEnabled(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetIsEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetIsEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Tag(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Tag)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetTag(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetTag)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Probability(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Probability)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetProbability(&self, value: SpeechRecognitionConstraintProbability) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetProbability)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Commands(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Commands)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Create(commands: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + Self::ISpeechRecognitionListConstraintFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), commands.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateWithTag(commands: P0, tag: &windows_core::HSTRING) -> windows_core::Result + where + P0: windows_core::Param>, + { + Self::ISpeechRecognitionListConstraintFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWithTag)(windows_core::Interface::as_raw(this), commands.param().abi(), core::mem::transmute_copy(tag), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn ISpeechRecognitionListConstraintFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for SpeechRecognitionListConstraint { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechRecognitionListConstraint { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechRecognitionListConstraint { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechRecognitionListConstraint"; +} +unsafe impl Send for SpeechRecognitionListConstraint {} +unsafe impl Sync for SpeechRecognitionListConstraint {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechRecognitionQualityDegradingEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechRecognitionQualityDegradingEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl SpeechRecognitionQualityDegradingEventArgs { + pub fn Problem(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Problem)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for SpeechRecognitionQualityDegradingEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechRecognitionQualityDegradingEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechRecognitionQualityDegradingEventArgs { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechRecognitionQualityDegradingEventArgs"; +} +unsafe impl Send for SpeechRecognitionQualityDegradingEventArgs {} +unsafe impl Sync for SpeechRecognitionQualityDegradingEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechRecognitionResult(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechRecognitionResult, windows_core::IUnknown, windows_core::IInspectable); +impl SpeechRecognitionResult { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Text(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Text)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Confidence(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Confidence)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SemanticInterpretation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SemanticInterpretation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetAlternates(&self, maxalternates: u32) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAlternates)(windows_core::Interface::as_raw(this), maxalternates, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Constraint(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Constraint)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RulePath(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RulePath)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RawConfidence(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RawConfidence)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PhraseStartTime(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PhraseStartTime)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PhraseDuration(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PhraseDuration)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for SpeechRecognitionResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechRecognitionResult { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechRecognitionResult { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechRecognitionResult"; +} +unsafe impl Send for SpeechRecognitionResult {} +unsafe impl Sync for SpeechRecognitionResult {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct SpeechRecognitionResultStatus(pub i32); +impl SpeechRecognitionResultStatus { + pub const Success: Self = Self(0i32); + pub const TopicLanguageNotSupported: Self = Self(1i32); + pub const GrammarLanguageMismatch: Self = Self(2i32); + pub const GrammarCompilationFailure: Self = Self(3i32); + pub const AudioQualityFailure: Self = Self(4i32); + pub const UserCanceled: Self = Self(5i32); + pub const Unknown: Self = Self(6i32); + pub const TimeoutExceeded: Self = Self(7i32); + pub const PauseLimitExceeded: Self = Self(8i32); + pub const NetworkFailure: Self = Self(9i32); + pub const MicrophoneUnavailable: Self = Self(10i32); +} +impl windows_core::TypeKind for SpeechRecognitionResultStatus { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for SpeechRecognitionResultStatus { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.SpeechRecognition.SpeechRecognitionResultStatus;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct SpeechRecognitionScenario(pub i32); +impl SpeechRecognitionScenario { + pub const WebSearch: Self = Self(0i32); + pub const Dictation: Self = Self(1i32); + pub const FormFilling: Self = Self(2i32); +} +impl windows_core::TypeKind for SpeechRecognitionScenario { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for SpeechRecognitionScenario { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.SpeechRecognition.SpeechRecognitionScenario;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechRecognitionSemanticInterpretation(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechRecognitionSemanticInterpretation, windows_core::IUnknown, windows_core::IInspectable); +impl SpeechRecognitionSemanticInterpretation { + pub fn Properties(&self) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for SpeechRecognitionSemanticInterpretation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechRecognitionSemanticInterpretation { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechRecognitionSemanticInterpretation { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechRecognitionSemanticInterpretation"; +} +unsafe impl Send for SpeechRecognitionSemanticInterpretation {} +unsafe impl Sync for SpeechRecognitionSemanticInterpretation {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechRecognitionTopicConstraint(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechRecognitionTopicConstraint, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(SpeechRecognitionTopicConstraint, ISpeechRecognitionConstraint); +impl SpeechRecognitionTopicConstraint { + pub fn IsEnabled(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetIsEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetIsEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Tag(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Tag)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetTag(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetTag)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Probability(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Probability)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetProbability(&self, value: SpeechRecognitionConstraintProbability) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetProbability)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Scenario(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Scenario)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn TopicHint(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TopicHint)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Create(scenario: SpeechRecognitionScenario, topichint: &windows_core::HSTRING) -> windows_core::Result { + Self::ISpeechRecognitionTopicConstraintFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), scenario, core::mem::transmute_copy(topichint), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateWithTag(scenario: SpeechRecognitionScenario, topichint: &windows_core::HSTRING, tag: &windows_core::HSTRING) -> windows_core::Result { + Self::ISpeechRecognitionTopicConstraintFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWithTag)(windows_core::Interface::as_raw(this), scenario, core::mem::transmute_copy(topichint), core::mem::transmute_copy(tag), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn ISpeechRecognitionTopicConstraintFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for SpeechRecognitionTopicConstraint { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechRecognitionTopicConstraint { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechRecognitionTopicConstraint { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechRecognitionTopicConstraint"; +} +unsafe impl Send for SpeechRecognitionTopicConstraint {} +unsafe impl Sync for SpeechRecognitionTopicConstraint {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechRecognitionVoiceCommandDefinitionConstraint(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechRecognitionVoiceCommandDefinitionConstraint, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(SpeechRecognitionVoiceCommandDefinitionConstraint, ISpeechRecognitionConstraint); +impl SpeechRecognitionVoiceCommandDefinitionConstraint { + pub fn IsEnabled(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetIsEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetIsEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Tag(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Tag)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetTag(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetTag)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Probability(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Probability)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetProbability(&self, value: SpeechRecognitionConstraintProbability) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetProbability)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for SpeechRecognitionVoiceCommandDefinitionConstraint { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechRecognitionVoiceCommandDefinitionConstraint { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechRecognitionVoiceCommandDefinitionConstraint { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechRecognitionVoiceCommandDefinitionConstraint"; +} +unsafe impl Send for SpeechRecognitionVoiceCommandDefinitionConstraint {} +unsafe impl Sync for SpeechRecognitionVoiceCommandDefinitionConstraint {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechRecognizer(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechRecognizer, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(SpeechRecognizer, super::super::Foundation::IClosable); +impl SpeechRecognizer { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn Close(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } + } + #[cfg(feature = "Globalization")] + pub fn CurrentLanguage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CurrentLanguage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Constraints(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Constraints)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Timeouts(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Timeouts)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn UIOptions(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UIOptions)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CompileConstraintsAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CompileConstraintsAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RecognizeAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RecognizeAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RecognizeWithUIAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RecognizeWithUIAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RecognitionQualityDegrading(&self, speechrecognitionqualitydegradinghandler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RecognitionQualityDegrading)(windows_core::Interface::as_raw(this), speechrecognitionqualitydegradinghandler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveRecognitionQualityDegrading(&self, cookie: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveRecognitionQualityDegrading)(windows_core::Interface::as_raw(this), cookie).ok() } + } + pub fn StateChanged(&self, statechangedhandler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StateChanged)(windows_core::Interface::as_raw(this), statechangedhandler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveStateChanged(&self, cookie: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveStateChanged)(windows_core::Interface::as_raw(this), cookie).ok() } + } + pub fn ContinuousRecognitionSession(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContinuousRecognitionSession)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn State(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).State)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn StopRecognitionAsync(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StopRecognitionAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn HypothesisGenerated(&self, value: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HypothesisGenerated)(windows_core::Interface::as_raw(this), value.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveHypothesisGenerated(&self, value: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveHypothesisGenerated)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Globalization")] + pub fn Create(language: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::ISpeechRecognizerFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), language.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Globalization")] + pub fn SystemSpeechLanguage() -> windows_core::Result { + Self::ISpeechRecognizerStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SystemSpeechLanguage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Globalization")] + pub fn SupportedTopicLanguages() -> windows_core::Result> { + Self::ISpeechRecognizerStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedTopicLanguages)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Globalization")] + pub fn SupportedGrammarLanguages() -> windows_core::Result> { + Self::ISpeechRecognizerStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SupportedGrammarLanguages)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Globalization")] + pub fn TrySetSystemSpeechLanguageAsync(speechlanguage: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::ISpeechRecognizerStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrySetSystemSpeechLanguageAsync)(windows_core::Interface::as_raw(this), speechlanguage.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn ISpeechRecognizerFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn ISpeechRecognizerStatics windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn ISpeechRecognizerStatics2 windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for SpeechRecognizer { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechRecognizer { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechRecognizer { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechRecognizer"; +} +unsafe impl Send for SpeechRecognizer {} +unsafe impl Sync for SpeechRecognizer {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct SpeechRecognizerState(pub i32); +impl SpeechRecognizerState { + pub const Idle: Self = Self(0i32); + pub const Capturing: Self = Self(1i32); + pub const Processing: Self = Self(2i32); + pub const SoundStarted: Self = Self(3i32); + pub const SoundEnded: Self = Self(4i32); + pub const SpeechDetected: Self = Self(5i32); + pub const Paused: Self = Self(6i32); +} +impl windows_core::TypeKind for SpeechRecognizerState { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for SpeechRecognizerState { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.SpeechRecognition.SpeechRecognizerState;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechRecognizerStateChangedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechRecognizerStateChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl SpeechRecognizerStateChangedEventArgs { + pub fn State(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).State)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for SpeechRecognizerStateChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechRecognizerStateChangedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechRecognizerStateChangedEventArgs { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechRecognizerStateChangedEventArgs"; +} +unsafe impl Send for SpeechRecognizerStateChangedEventArgs {} +unsafe impl Sync for SpeechRecognizerStateChangedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechRecognizerTimeouts(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechRecognizerTimeouts, windows_core::IUnknown, windows_core::IInspectable); +impl SpeechRecognizerTimeouts { + pub fn InitialSilenceTimeout(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InitialSilenceTimeout)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetInitialSilenceTimeout(&self, value: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetInitialSilenceTimeout)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn EndSilenceTimeout(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).EndSilenceTimeout)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetEndSilenceTimeout(&self, value: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetEndSilenceTimeout)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn BabbleTimeout(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BabbleTimeout)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetBabbleTimeout(&self, value: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetBabbleTimeout)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for SpeechRecognizerTimeouts { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechRecognizerTimeouts { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechRecognizerTimeouts { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechRecognizerTimeouts"; +} +unsafe impl Send for SpeechRecognizerTimeouts {} +unsafe impl Sync for SpeechRecognizerTimeouts {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechRecognizerUIOptions(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechRecognizerUIOptions, windows_core::IUnknown, windows_core::IInspectable); +impl SpeechRecognizerUIOptions { + pub fn ExampleText(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExampleText)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetExampleText(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetExampleText)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn AudiblePrompt(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AudiblePrompt)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetAudiblePrompt(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAudiblePrompt)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn IsReadBackEnabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsReadBackEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetIsReadBackEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetIsReadBackEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ShowConfirmation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ShowConfirmation)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetShowConfirmation(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetShowConfirmation)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for SpeechRecognizerUIOptions { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechRecognizerUIOptions { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechRecognizerUIOptions { + const NAME: &'static str = "Windows.Media.SpeechRecognition.SpeechRecognizerUIOptions"; +} +unsafe impl Send for SpeechRecognizerUIOptions {} +unsafe impl Sync for SpeechRecognizerUIOptions {} +pub struct VoiceCommandManager; +impl VoiceCommandManager { + #[cfg(feature = "Storage_Streams")] + pub fn InstallCommandSetsFromStorageFileAsync(file: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IVoiceCommandManager(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InstallCommandSetsFromStorageFileAsync)(windows_core::Interface::as_raw(this), file.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn InstalledCommandSets() -> windows_core::Result> { + Self::IVoiceCommandManager(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InstalledCommandSets)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn IVoiceCommandManager windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeName for VoiceCommandManager { + const NAME: &'static str = "Windows.Media.SpeechRecognition.VoiceCommandManager"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VoiceCommandSet(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(VoiceCommandSet, windows_core::IUnknown, windows_core::IInspectable); +impl VoiceCommandSet { + pub fn Language(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Language)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Name(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetPhraseListAsync(&self, phraselistname: &windows_core::HSTRING, phraselist: P1) -> windows_core::Result + where + P1: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SetPhraseListAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(phraselistname), phraselist.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for VoiceCommandSet { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for VoiceCommandSet { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for VoiceCommandSet { + const NAME: &'static str = "Windows.Media.SpeechRecognition.VoiceCommandSet"; +} +unsafe impl Send for VoiceCommandSet {} +unsafe impl Sync for VoiceCommandSet {} +} +#[cfg(feature = "Media_SpeechSynthesis")] +pub mod SpeechSynthesis{ +windows_core::imp::define_interface!(IInstalledVoicesStatic, IInstalledVoicesStatic_Vtbl, 0x7d526ecc_7533_4c3f_85be_888c2baeebdc); +impl windows_core::RuntimeType for IInstalledVoicesStatic { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IInstalledVoicesStatic { + const NAME: &'static str = "Windows.Media.SpeechSynthesis.IInstalledVoicesStatic"; +} +pub trait IInstalledVoicesStatic_Impl: windows_core::IUnknownImpl { + fn AllVoices(&self) -> windows_core::Result>; + fn DefaultVoice(&self) -> windows_core::Result; +} +impl IInstalledVoicesStatic_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AllVoices(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInstalledVoicesStatic_Impl::AllVoices(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DefaultVoice(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInstalledVoicesStatic_Impl::DefaultVoice(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AllVoices: AllVoices::, + DefaultVoice: DefaultVoice::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IInstalledVoicesStatic_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AllVoices: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub DefaultVoice: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IInstalledVoicesStatic2, IInstalledVoicesStatic2_Vtbl, 0x64255f2e_358d_4058_be9a_fd3fcb423530); +impl windows_core::RuntimeType for IInstalledVoicesStatic2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IInstalledVoicesStatic2 { + const NAME: &'static str = "Windows.Media.SpeechSynthesis.IInstalledVoicesStatic2"; +} +pub trait IInstalledVoicesStatic2_Impl: windows_core::IUnknownImpl { + fn TrySetDefaultVoiceAsync(&self, voice: windows_core::Ref<'_, VoiceInformation>) -> windows_core::Result>; +} +impl IInstalledVoicesStatic2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TrySetDefaultVoiceAsync(this: *mut core::ffi::c_void, voice: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IInstalledVoicesStatic2_Impl::TrySetDefaultVoiceAsync(this, core::mem::transmute_copy(&voice)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + TrySetDefaultVoiceAsync: TrySetDefaultVoiceAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IInstalledVoicesStatic2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub TrySetDefaultVoiceAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +#[cfg(feature = "Storage_Streams")] +windows_core::imp::define_interface!(ISpeechSynthesisStream, ISpeechSynthesisStream_Vtbl, 0x83e46e93_244c_4622_ba0b_6229c4d0d65d); +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeType for ISpeechSynthesisStream { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for ISpeechSynthesisStream { + const NAME: &'static str = "Windows.Media.SpeechSynthesis.ISpeechSynthesisStream"; +} +#[cfg(feature = "Storage_Streams")] +pub trait ISpeechSynthesisStream_Impl: super::super::Foundation::IClosable_Impl + super::super::Storage::Streams::IContentTypeProvider_Impl + super::super::Storage::Streams::IInputStream_Impl + super::super::Storage::Streams::IOutputStream_Impl + super::super::Storage::Streams::IRandomAccessStream_Impl + super::super::Storage::Streams::IRandomAccessStreamWithContentType_Impl { + fn Markers(&self) -> windows_core::Result>; +} +#[cfg(feature = "Storage_Streams")] +impl ISpeechSynthesisStream_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Markers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechSynthesisStream_Impl::Markers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Markers: Markers:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[cfg(feature = "Storage_Streams")] +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechSynthesisStream_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Markers: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechSynthesizer, ISpeechSynthesizer_Vtbl, 0xce9f7c76_97f4_4ced_ad68_d51c458e45c6); +impl windows_core::RuntimeType for ISpeechSynthesizer { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for ISpeechSynthesizer { + const NAME: &'static str = "Windows.Media.SpeechSynthesis.ISpeechSynthesizer"; +} +#[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] +pub trait ISpeechSynthesizer_Impl: windows_core::IUnknownImpl { + fn SynthesizeTextToStreamAsync(&self, text: &windows_core::HSTRING) -> windows_core::Result>; + fn SynthesizeSsmlToStreamAsync(&self, Ssml: &windows_core::HSTRING) -> windows_core::Result>; + fn SetVoice(&self, value: windows_core::Ref<'_, VoiceInformation>) -> windows_core::Result<()>; + fn Voice(&self) -> windows_core::Result; +} +#[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] +impl ISpeechSynthesizer_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SynthesizeTextToStreamAsync(this: *mut core::ffi::c_void, text: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechSynthesizer_Impl::SynthesizeTextToStreamAsync(this, core::mem::transmute(&text)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SynthesizeSsmlToStreamAsync(this: *mut core::ffi::c_void, ssml: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechSynthesizer_Impl::SynthesizeSsmlToStreamAsync(this, core::mem::transmute(&ssml)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetVoice(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechSynthesizer_Impl::SetVoice(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Voice(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechSynthesizer_Impl::Voice(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SynthesizeTextToStreamAsync: SynthesizeTextToStreamAsync::, + SynthesizeSsmlToStreamAsync: SynthesizeSsmlToStreamAsync::, + SetVoice: SetVoice::, + Voice: Voice::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechSynthesizer_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] + pub SynthesizeTextToStreamAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Media_Core", feature = "Storage_Streams")))] + SynthesizeTextToStreamAsync: usize, + #[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] + pub SynthesizeSsmlToStreamAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Media_Core", feature = "Storage_Streams")))] + SynthesizeSsmlToStreamAsync: usize, + pub SetVoice: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Voice: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechSynthesizer2, ISpeechSynthesizer2_Vtbl, 0xa7c5ecb2_4339_4d6a_bbf8_c7a4f1544c2e); +impl windows_core::RuntimeType for ISpeechSynthesizer2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechSynthesizer2 { + const NAME: &'static str = "Windows.Media.SpeechSynthesis.ISpeechSynthesizer2"; +} +pub trait ISpeechSynthesizer2_Impl: windows_core::IUnknownImpl { + fn Options(&self) -> windows_core::Result; +} +impl ISpeechSynthesizer2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Options(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechSynthesizer2_Impl::Options(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Options: Options:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechSynthesizer2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Options: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechSynthesizerOptions, ISpeechSynthesizerOptions_Vtbl, 0xa0e23871_cc3d_43c9_91b1_ee185324d83d); +impl windows_core::RuntimeType for ISpeechSynthesizerOptions { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechSynthesizerOptions { + const NAME: &'static str = "Windows.Media.SpeechSynthesis.ISpeechSynthesizerOptions"; +} +pub trait ISpeechSynthesizerOptions_Impl: windows_core::IUnknownImpl { + fn IncludeWordBoundaryMetadata(&self) -> windows_core::Result; + fn SetIncludeWordBoundaryMetadata(&self, value: bool) -> windows_core::Result<()>; + fn IncludeSentenceBoundaryMetadata(&self) -> windows_core::Result; + fn SetIncludeSentenceBoundaryMetadata(&self, value: bool) -> windows_core::Result<()>; +} +impl ISpeechSynthesizerOptions_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IncludeWordBoundaryMetadata(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechSynthesizerOptions_Impl::IncludeWordBoundaryMetadata(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetIncludeWordBoundaryMetadata(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechSynthesizerOptions_Impl::SetIncludeWordBoundaryMetadata(this, value).into() + } + } + unsafe extern "system" fn IncludeSentenceBoundaryMetadata(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechSynthesizerOptions_Impl::IncludeSentenceBoundaryMetadata(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetIncludeSentenceBoundaryMetadata(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechSynthesizerOptions_Impl::SetIncludeSentenceBoundaryMetadata(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IncludeWordBoundaryMetadata: IncludeWordBoundaryMetadata::, + SetIncludeWordBoundaryMetadata: SetIncludeWordBoundaryMetadata::, + IncludeSentenceBoundaryMetadata: IncludeSentenceBoundaryMetadata::, + SetIncludeSentenceBoundaryMetadata: SetIncludeSentenceBoundaryMetadata::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechSynthesizerOptions_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IncludeWordBoundaryMetadata: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetIncludeWordBoundaryMetadata: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub IncludeSentenceBoundaryMetadata: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetIncludeSentenceBoundaryMetadata: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechSynthesizerOptions2, ISpeechSynthesizerOptions2_Vtbl, 0x1cbef60e_119c_4bed_b118_d250c3a25793); +impl windows_core::RuntimeType for ISpeechSynthesizerOptions2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechSynthesizerOptions2 { + const NAME: &'static str = "Windows.Media.SpeechSynthesis.ISpeechSynthesizerOptions2"; +} +pub trait ISpeechSynthesizerOptions2_Impl: windows_core::IUnknownImpl { + fn AudioVolume(&self) -> windows_core::Result; + fn SetAudioVolume(&self, value: f64) -> windows_core::Result<()>; + fn SpeakingRate(&self) -> windows_core::Result; + fn SetSpeakingRate(&self, value: f64) -> windows_core::Result<()>; + fn AudioPitch(&self) -> windows_core::Result; + fn SetAudioPitch(&self, value: f64) -> windows_core::Result<()>; +} +impl ISpeechSynthesizerOptions2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AudioVolume(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechSynthesizerOptions2_Impl::AudioVolume(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAudioVolume(this: *mut core::ffi::c_void, value: f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechSynthesizerOptions2_Impl::SetAudioVolume(this, value).into() + } + } + unsafe extern "system" fn SpeakingRate(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechSynthesizerOptions2_Impl::SpeakingRate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetSpeakingRate(this: *mut core::ffi::c_void, value: f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechSynthesizerOptions2_Impl::SetSpeakingRate(this, value).into() + } + } + unsafe extern "system" fn AudioPitch(this: *mut core::ffi::c_void, result__: *mut f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechSynthesizerOptions2_Impl::AudioPitch(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAudioPitch(this: *mut core::ffi::c_void, value: f64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechSynthesizerOptions2_Impl::SetAudioPitch(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AudioVolume: AudioVolume::, + SetAudioVolume: SetAudioVolume::, + SpeakingRate: SpeakingRate::, + SetSpeakingRate: SetSpeakingRate::, + AudioPitch: AudioPitch::, + SetAudioPitch: SetAudioPitch::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechSynthesizerOptions2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AudioVolume: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, + pub SetAudioVolume: unsafe extern "system" fn(*mut core::ffi::c_void, f64) -> windows_core::HRESULT, + pub SpeakingRate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, + pub SetSpeakingRate: unsafe extern "system" fn(*mut core::ffi::c_void, f64) -> windows_core::HRESULT, + pub AudioPitch: unsafe extern "system" fn(*mut core::ffi::c_void, *mut f64) -> windows_core::HRESULT, + pub SetAudioPitch: unsafe extern "system" fn(*mut core::ffi::c_void, f64) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(ISpeechSynthesizerOptions3, ISpeechSynthesizerOptions3_Vtbl, 0x401ed877_902c_4814_a582_a5d0c0769fa8); +impl windows_core::RuntimeType for ISpeechSynthesizerOptions3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpeechSynthesizerOptions3 { + const NAME: &'static str = "Windows.Media.SpeechSynthesis.ISpeechSynthesizerOptions3"; +} +pub trait ISpeechSynthesizerOptions3_Impl: windows_core::IUnknownImpl { + fn AppendedSilence(&self) -> windows_core::Result; + fn SetAppendedSilence(&self, value: SpeechAppendedSilence) -> windows_core::Result<()>; + fn PunctuationSilence(&self) -> windows_core::Result; + fn SetPunctuationSilence(&self, value: SpeechPunctuationSilence) -> windows_core::Result<()>; +} +impl ISpeechSynthesizerOptions3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AppendedSilence(this: *mut core::ffi::c_void, result__: *mut SpeechAppendedSilence) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechSynthesizerOptions3_Impl::AppendedSilence(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAppendedSilence(this: *mut core::ffi::c_void, value: SpeechAppendedSilence) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechSynthesizerOptions3_Impl::SetAppendedSilence(this, value).into() + } + } + unsafe extern "system" fn PunctuationSilence(this: *mut core::ffi::c_void, result__: *mut SpeechPunctuationSilence) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpeechSynthesizerOptions3_Impl::PunctuationSilence(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPunctuationSilence(this: *mut core::ffi::c_void, value: SpeechPunctuationSilence) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ISpeechSynthesizerOptions3_Impl::SetPunctuationSilence(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AppendedSilence: AppendedSilence::, + SetAppendedSilence: SetAppendedSilence::, + PunctuationSilence: PunctuationSilence::, + SetPunctuationSilence: SetPunctuationSilence::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpeechSynthesizerOptions3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AppendedSilence: unsafe extern "system" fn(*mut core::ffi::c_void, *mut SpeechAppendedSilence) -> windows_core::HRESULT, + pub SetAppendedSilence: unsafe extern "system" fn(*mut core::ffi::c_void, SpeechAppendedSilence) -> windows_core::HRESULT, + pub PunctuationSilence: unsafe extern "system" fn(*mut core::ffi::c_void, *mut SpeechPunctuationSilence) -> windows_core::HRESULT, + pub SetPunctuationSilence: unsafe extern "system" fn(*mut core::ffi::c_void, SpeechPunctuationSilence) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVoiceInformation, IVoiceInformation_Vtbl, 0xb127d6a4_1291_4604_aa9c_83134083352c); +impl windows_core::RuntimeType for IVoiceInformation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVoiceInformation { + const NAME: &'static str = "Windows.Media.SpeechSynthesis.IVoiceInformation"; +} +pub trait IVoiceInformation_Impl: windows_core::IUnknownImpl { + fn DisplayName(&self) -> windows_core::Result; + fn Id(&self) -> windows_core::Result; + fn Language(&self) -> windows_core::Result; + fn Description(&self) -> windows_core::Result; + fn Gender(&self) -> windows_core::Result; +} +impl IVoiceInformation_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DisplayName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVoiceInformation_Impl::DisplayName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Id(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVoiceInformation_Impl::Id(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Language(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVoiceInformation_Impl::Language(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Description(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVoiceInformation_Impl::Description(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Gender(this: *mut core::ffi::c_void, result__: *mut VoiceGender) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVoiceInformation_Impl::Gender(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DisplayName: DisplayName::, + Id: Id::, + Language: Language::, + Description: Description::, + Gender: Gender::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVoiceInformation_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub DisplayName: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Id: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Language: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Description: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Gender: unsafe extern "system" fn(*mut core::ffi::c_void, *mut VoiceGender) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct SpeechAppendedSilence(pub i32); +impl SpeechAppendedSilence { + pub const Default: Self = Self(0i32); + pub const Min: Self = Self(1i32); +} +impl windows_core::TypeKind for SpeechAppendedSilence { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for SpeechAppendedSilence { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.SpeechSynthesis.SpeechAppendedSilence;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct SpeechPunctuationSilence(pub i32); +impl SpeechPunctuationSilence { + pub const Default: Self = Self(0i32); + pub const Min: Self = Self(1i32); +} +impl windows_core::TypeKind for SpeechPunctuationSilence { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for SpeechPunctuationSilence { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.SpeechSynthesis.SpeechPunctuationSilence;i4)"); +} +#[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechSynthesisStream(windows_core::IUnknown); +#[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] +windows_core::imp::interface_hierarchy!(SpeechSynthesisStream, windows_core::IUnknown, windows_core::IInspectable); +#[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] +windows_core::imp::required_hierarchy!(SpeechSynthesisStream, super::super::Foundation::IClosable, super::super::Storage::Streams::IContentTypeProvider, super::super::Storage::Streams::IInputStream, super::super::Storage::Streams::IOutputStream, super::super::Storage::Streams::IRandomAccessStream, super::super::Storage::Streams::IRandomAccessStreamWithContentType, super::Core::ITimedMetadataTrackProvider); +#[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] +impl SpeechSynthesisStream { + pub fn Close(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn ContentType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn ReadAsync(&self, buffer: P0, count: u32, options: super::super::Storage::Streams::InputStreamOptions) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), count, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn WriteAsync(&self, buffer: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn FlushAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FlushAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetSize(&self, value: u64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetSize)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn GetInputStreamAt(&self, position: u64) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetOutputStreamAt(&self, position: u64) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetOutputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Position(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Position)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Seek(&self, position: u64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Seek)(windows_core::Interface::as_raw(this), position).ok() } + } + pub fn CloneStream(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CloneStream)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CanRead(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanRead)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CanWrite(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanWrite)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Markers(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Markers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TimedMetadataTracks(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TimedMetadataTracks)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +#[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] +impl windows_core::RuntimeType for SpeechSynthesisStream { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +#[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] +unsafe impl windows_core::Interface for SpeechSynthesisStream { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +#[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for SpeechSynthesisStream { + const NAME: &'static str = "Windows.Media.SpeechSynthesis.SpeechSynthesisStream"; +} +#[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] +unsafe impl Send for SpeechSynthesisStream {} +#[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] +unsafe impl Sync for SpeechSynthesisStream {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechSynthesizer(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechSynthesizer, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(SpeechSynthesizer, super::super::Foundation::IClosable); +impl SpeechSynthesizer { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn Close(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn AllVoices() -> windows_core::Result> { + Self::IInstalledVoicesStatic(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AllVoices)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn DefaultVoice() -> windows_core::Result { + Self::IInstalledVoicesStatic(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DefaultVoice)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TrySetDefaultVoiceAsync(voice: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::IInstalledVoicesStatic2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrySetDefaultVoiceAsync)(windows_core::Interface::as_raw(this), voice.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] + pub fn SynthesizeTextToStreamAsync(&self, text: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SynthesizeTextToStreamAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(text), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Media_Core", feature = "Storage_Streams"))] + pub fn SynthesizeSsmlToStreamAsync(&self, ssml: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SynthesizeSsmlToStreamAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(ssml), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetVoice(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetVoice)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn Voice(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Voice)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Options(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Options)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + fn IInstalledVoicesStatic windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn IInstalledVoicesStatic2 windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for SpeechSynthesizer { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechSynthesizer { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechSynthesizer { + const NAME: &'static str = "Windows.Media.SpeechSynthesis.SpeechSynthesizer"; +} +unsafe impl Send for SpeechSynthesizer {} +unsafe impl Sync for SpeechSynthesizer {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpeechSynthesizerOptions(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpeechSynthesizerOptions, windows_core::IUnknown, windows_core::IInspectable); +impl SpeechSynthesizerOptions { + pub fn IncludeWordBoundaryMetadata(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IncludeWordBoundaryMetadata)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetIncludeWordBoundaryMetadata(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetIncludeWordBoundaryMetadata)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn IncludeSentenceBoundaryMetadata(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IncludeSentenceBoundaryMetadata)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetIncludeSentenceBoundaryMetadata(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetIncludeSentenceBoundaryMetadata)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn AudioVolume(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AudioVolume)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAudioVolume(&self, value: f64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAudioVolume)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn SpeakingRate(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SpeakingRate)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetSpeakingRate(&self, value: f64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetSpeakingRate)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn AudioPitch(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AudioPitch)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAudioPitch(&self, value: f64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAudioPitch)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn AppendedSilence(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AppendedSilence)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAppendedSilence(&self, value: SpeechAppendedSilence) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAppendedSilence)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn PunctuationSilence(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PunctuationSilence)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetPunctuationSilence(&self, value: SpeechPunctuationSilence) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetPunctuationSilence)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeType for SpeechSynthesizerOptions { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpeechSynthesizerOptions { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpeechSynthesizerOptions { + const NAME: &'static str = "Windows.Media.SpeechSynthesis.SpeechSynthesizerOptions"; +} +unsafe impl Send for SpeechSynthesizerOptions {} +unsafe impl Sync for SpeechSynthesizerOptions {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct VoiceGender(pub i32); +impl VoiceGender { + pub const Male: Self = Self(0i32); + pub const Female: Self = Self(1i32); +} +impl windows_core::TypeKind for VoiceGender { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for VoiceGender { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.SpeechSynthesis.VoiceGender;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VoiceInformation(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(VoiceInformation, windows_core::IUnknown, windows_core::IInspectable); +impl VoiceInformation { + pub fn DisplayName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Id(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Id)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Language(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Language)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Description(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Description)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Gender(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Gender)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for VoiceInformation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for VoiceInformation { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for VoiceInformation { + const NAME: &'static str = "Windows.Media.SpeechSynthesis.VoiceInformation"; +} +unsafe impl Send for VoiceInformation {} +unsafe impl Sync for VoiceInformation {} +} +#[cfg(feature = "Media_Streaming")] +pub mod Streaming{ +#[cfg(feature = "Media_Streaming_Adaptive")] +pub mod Adaptive{ +#[cfg(feature = "Media_Core")] +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdaptiveMediaSource(windows_core::IUnknown); +#[cfg(feature = "Media_Core")] +windows_core::imp::interface_hierarchy!(AdaptiveMediaSource, windows_core::IUnknown, windows_core::IInspectable); +#[cfg(feature = "Media_Core")] +windows_core::imp::required_hierarchy!(AdaptiveMediaSource, super::super::super::Foundation::IClosable, super::super::Core::IMediaSource); +#[cfg(feature = "Media_Core")] +impl AdaptiveMediaSource { + pub fn IsLive(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsLive)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DesiredLiveOffset(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DesiredLiveOffset)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetDesiredLiveOffset(&self, value: super::super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDesiredLiveOffset)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn InitialBitrate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InitialBitrate)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetInitialBitrate(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetInitialBitrate)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn CurrentDownloadBitrate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CurrentDownloadBitrate)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CurrentPlaybackBitrate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CurrentPlaybackBitrate)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AvailableBitrates(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AvailableBitrates)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DesiredMinBitrate(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DesiredMinBitrate)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetDesiredMinBitrate(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDesiredMinBitrate)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn DesiredMaxBitrate(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DesiredMaxBitrate)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetDesiredMaxBitrate(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDesiredMaxBitrate)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn AudioOnlyPlayback(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AudioOnlyPlayback)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn InboundBitsPerSecond(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InboundBitsPerSecond)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn InboundBitsPerSecondWindow(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InboundBitsPerSecondWindow)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetInboundBitsPerSecondWindow(&self, value: super::super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetInboundBitsPerSecondWindow)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn DownloadBitrateChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DownloadBitrateChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveDownloadBitrateChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveDownloadBitrateChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn PlaybackBitrateChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PlaybackBitrateChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemovePlaybackBitrateChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemovePlaybackBitrateChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn DownloadRequested(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DownloadRequested)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveDownloadRequested(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveDownloadRequested)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn DownloadCompleted(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DownloadCompleted)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveDownloadCompleted(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveDownloadCompleted)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn DownloadFailed(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DownloadFailed)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveDownloadFailed(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveDownloadFailed)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn AdvancedSettings(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AdvancedSettings)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MinLiveOffset(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinLiveOffset)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MaxSeekableWindowSize(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxSeekableWindowSize)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DesiredSeekableWindowSize(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DesiredSeekableWindowSize)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetDesiredSeekableWindowSize(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetDesiredSeekableWindowSize)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn Diagnostics(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Diagnostics)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetCorrelatedTimes(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCorrelatedTimes)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IsContentTypeSupported(contenttype: &windows_core::HSTRING) -> windows_core::Result { + Self::IAdaptiveMediaSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsContentTypeSupported)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(contenttype), &mut result__).map(|| result__) + }) + } + pub fn CreateFromUriAsync(uri: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::IAdaptiveMediaSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromUriAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Web_Http")] + pub fn CreateFromUriWithDownloaderAsync(uri: P0, httpclient: P1) -> windows_core::Result> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + Self::IAdaptiveMediaSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromUriWithDownloaderAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), httpclient.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFromStreamAsync(stream: P0, uri: P1, contenttype: &windows_core::HSTRING) -> windows_core::Result> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + Self::IAdaptiveMediaSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromStreamAsync)(windows_core::Interface::as_raw(this), stream.param().abi(), uri.param().abi(), core::mem::transmute_copy(contenttype), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(all(feature = "Storage_Streams", feature = "Web_Http"))] + pub fn CreateFromStreamWithDownloaderAsync(stream: P0, uri: P1, contenttype: &windows_core::HSTRING, httpclient: P3) -> windows_core::Result> + where + P0: windows_core::Param, + P1: windows_core::Param, + P3: windows_core::Param, + { + Self::IAdaptiveMediaSourceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromStreamWithDownloaderAsync)(windows_core::Interface::as_raw(this), stream.param().abi(), uri.param().abi(), core::mem::transmute_copy(contenttype), httpclient.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Close(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } + } + fn IAdaptiveMediaSourceStatics windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +#[cfg(feature = "Media_Core")] +impl windows_core::RuntimeType for AdaptiveMediaSource { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +#[cfg(feature = "Media_Core")] +unsafe impl windows_core::Interface for AdaptiveMediaSource { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +#[cfg(feature = "Media_Core")] +impl windows_core::RuntimeName for AdaptiveMediaSource { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.AdaptiveMediaSource"; +} +#[cfg(feature = "Media_Core")] +unsafe impl Send for AdaptiveMediaSource {} +#[cfg(feature = "Media_Core")] +unsafe impl Sync for AdaptiveMediaSource {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdaptiveMediaSourceAdvancedSettings(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AdaptiveMediaSourceAdvancedSettings, windows_core::IUnknown, windows_core::IInspectable); +impl AdaptiveMediaSourceAdvancedSettings { + pub fn AllSegmentsIndependent(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AllSegmentsIndependent)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAllSegmentsIndependent(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAllSegmentsIndependent)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn DesiredBitrateHeadroomRatio(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DesiredBitrateHeadroomRatio)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetDesiredBitrateHeadroomRatio(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDesiredBitrateHeadroomRatio)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn BitrateDowngradeTriggerRatio(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BitrateDowngradeTriggerRatio)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetBitrateDowngradeTriggerRatio(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetBitrateDowngradeTriggerRatio)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } +} +impl windows_core::RuntimeType for AdaptiveMediaSourceAdvancedSettings { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AdaptiveMediaSourceAdvancedSettings { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AdaptiveMediaSourceAdvancedSettings { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceAdvancedSettings"; +} +unsafe impl Send for AdaptiveMediaSourceAdvancedSettings {} +unsafe impl Sync for AdaptiveMediaSourceAdvancedSettings {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdaptiveMediaSourceCorrelatedTimes(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AdaptiveMediaSourceCorrelatedTimes, windows_core::IUnknown, windows_core::IInspectable); +impl AdaptiveMediaSourceCorrelatedTimes { + pub fn Position(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Position)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PresentationTimeStamp(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PresentationTimeStamp)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ProgramDateTime(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProgramDateTime)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for AdaptiveMediaSourceCorrelatedTimes { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AdaptiveMediaSourceCorrelatedTimes { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AdaptiveMediaSourceCorrelatedTimes { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceCorrelatedTimes"; +} +unsafe impl Send for AdaptiveMediaSourceCorrelatedTimes {} +unsafe impl Sync for AdaptiveMediaSourceCorrelatedTimes {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdaptiveMediaSourceCreationResult(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AdaptiveMediaSourceCreationResult, windows_core::IUnknown, windows_core::IInspectable); +impl AdaptiveMediaSourceCreationResult { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Media_Core")] + pub fn MediaSource(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MediaSource)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Web_Http")] + pub fn HttpResponseMessage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HttpResponseMessage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ExtendedError(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExtendedError)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for AdaptiveMediaSourceCreationResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AdaptiveMediaSourceCreationResult { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AdaptiveMediaSourceCreationResult { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceCreationResult"; +} +unsafe impl Send for AdaptiveMediaSourceCreationResult {} +unsafe impl Sync for AdaptiveMediaSourceCreationResult {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct AdaptiveMediaSourceCreationStatus(pub i32); +impl AdaptiveMediaSourceCreationStatus { + pub const Success: Self = Self(0i32); + pub const ManifestDownloadFailure: Self = Self(1i32); + pub const ManifestParseFailure: Self = Self(2i32); + pub const UnsupportedManifestContentType: Self = Self(3i32); + pub const UnsupportedManifestVersion: Self = Self(4i32); + pub const UnsupportedManifestProfile: Self = Self(5i32); + pub const UnknownFailure: Self = Self(6i32); +} +impl windows_core::TypeKind for AdaptiveMediaSourceCreationStatus { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for AdaptiveMediaSourceCreationStatus { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceCreationStatus;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdaptiveMediaSourceDiagnosticAvailableEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AdaptiveMediaSourceDiagnosticAvailableEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl AdaptiveMediaSourceDiagnosticAvailableEventArgs { + pub fn DiagnosticType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DiagnosticType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn RequestId(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestId)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Position(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Position)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SegmentId(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SegmentId)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceType(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceType)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceUri(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceUri)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceByteRangeOffset(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceByteRangeOffset)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceByteRangeLength(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceByteRangeLength)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Bitrate(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Bitrate)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ExtendedError(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExtendedError)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ResourceDuration(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceDuration)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceContentType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceContentType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} +impl windows_core::RuntimeType for AdaptiveMediaSourceDiagnosticAvailableEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AdaptiveMediaSourceDiagnosticAvailableEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AdaptiveMediaSourceDiagnosticAvailableEventArgs { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceDiagnosticAvailableEventArgs"; +} +unsafe impl Send for AdaptiveMediaSourceDiagnosticAvailableEventArgs {} +unsafe impl Sync for AdaptiveMediaSourceDiagnosticAvailableEventArgs {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct AdaptiveMediaSourceDiagnosticType(pub i32); +impl AdaptiveMediaSourceDiagnosticType { + pub const ManifestUnchangedUponReload: Self = Self(0i32); + pub const ManifestMismatchUponReload: Self = Self(1i32); + pub const ManifestSignaledEndOfLiveEventUponReload: Self = Self(2i32); + pub const MediaSegmentSkipped: Self = Self(3i32); + pub const ResourceNotFound: Self = Self(4i32); + pub const ResourceTimedOut: Self = Self(5i32); + pub const ResourceParsingError: Self = Self(6i32); + pub const BitrateDisabled: Self = Self(7i32); + pub const FatalMediaSourceError: Self = Self(8i32); +} +impl windows_core::TypeKind for AdaptiveMediaSourceDiagnosticType { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for AdaptiveMediaSourceDiagnosticType { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceDiagnosticType;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdaptiveMediaSourceDiagnostics(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AdaptiveMediaSourceDiagnostics, windows_core::IUnknown, windows_core::IInspectable); +impl AdaptiveMediaSourceDiagnostics { + pub fn DiagnosticAvailable(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DiagnosticAvailable)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveDiagnosticAvailable(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveDiagnosticAvailable)(windows_core::Interface::as_raw(this), token).ok() } + } +} +impl windows_core::RuntimeType for AdaptiveMediaSourceDiagnostics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AdaptiveMediaSourceDiagnostics { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AdaptiveMediaSourceDiagnostics { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceDiagnostics"; +} +unsafe impl Send for AdaptiveMediaSourceDiagnostics {} +unsafe impl Sync for AdaptiveMediaSourceDiagnostics {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdaptiveMediaSourceDownloadBitrateChangedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AdaptiveMediaSourceDownloadBitrateChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl AdaptiveMediaSourceDownloadBitrateChangedEventArgs { + pub fn OldValue(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OldValue)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn NewValue(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NewValue)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Reason(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Reason)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for AdaptiveMediaSourceDownloadBitrateChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AdaptiveMediaSourceDownloadBitrateChangedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AdaptiveMediaSourceDownloadBitrateChangedEventArgs { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceDownloadBitrateChangedEventArgs"; +} +unsafe impl Send for AdaptiveMediaSourceDownloadBitrateChangedEventArgs {} +unsafe impl Sync for AdaptiveMediaSourceDownloadBitrateChangedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct AdaptiveMediaSourceDownloadBitrateChangedReason(pub i32); +impl AdaptiveMediaSourceDownloadBitrateChangedReason { + pub const SufficientInboundBitsPerSecond: Self = Self(0i32); + pub const InsufficientInboundBitsPerSecond: Self = Self(1i32); + pub const LowBufferLevel: Self = Self(2i32); + pub const PositionChanged: Self = Self(3i32); + pub const TrackSelectionChanged: Self = Self(4i32); + pub const DesiredBitratesChanged: Self = Self(5i32); + pub const ErrorInPreviousBitrate: Self = Self(6i32); +} +impl windows_core::TypeKind for AdaptiveMediaSourceDownloadBitrateChangedReason { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for AdaptiveMediaSourceDownloadBitrateChangedReason { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceDownloadBitrateChangedReason;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdaptiveMediaSourceDownloadCompletedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AdaptiveMediaSourceDownloadCompletedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl AdaptiveMediaSourceDownloadCompletedEventArgs { + pub fn ResourceType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ResourceUri(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceUri)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceByteRangeOffset(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceByteRangeOffset)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceByteRangeLength(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceByteRangeLength)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Web_Http")] + pub fn HttpResponseMessage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HttpResponseMessage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RequestId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestId)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Statistics(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Statistics)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Position(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Position)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceDuration(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceDuration)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceContentType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceContentType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} +impl windows_core::RuntimeType for AdaptiveMediaSourceDownloadCompletedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AdaptiveMediaSourceDownloadCompletedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AdaptiveMediaSourceDownloadCompletedEventArgs { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceDownloadCompletedEventArgs"; +} +unsafe impl Send for AdaptiveMediaSourceDownloadCompletedEventArgs {} +unsafe impl Sync for AdaptiveMediaSourceDownloadCompletedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdaptiveMediaSourceDownloadFailedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AdaptiveMediaSourceDownloadFailedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl AdaptiveMediaSourceDownloadFailedEventArgs { + pub fn ResourceType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ResourceUri(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceUri)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceByteRangeOffset(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceByteRangeOffset)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceByteRangeLength(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceByteRangeLength)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Web_Http")] + pub fn HttpResponseMessage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HttpResponseMessage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RequestId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestId)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ExtendedError(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExtendedError)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Statistics(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Statistics)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Position(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Position)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceDuration(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceDuration)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceContentType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceContentType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} +impl windows_core::RuntimeType for AdaptiveMediaSourceDownloadFailedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AdaptiveMediaSourceDownloadFailedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AdaptiveMediaSourceDownloadFailedEventArgs { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceDownloadFailedEventArgs"; +} +unsafe impl Send for AdaptiveMediaSourceDownloadFailedEventArgs {} +unsafe impl Sync for AdaptiveMediaSourceDownloadFailedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdaptiveMediaSourceDownloadRequestedDeferral(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AdaptiveMediaSourceDownloadRequestedDeferral, windows_core::IUnknown, windows_core::IInspectable); +impl AdaptiveMediaSourceDownloadRequestedDeferral { + pub fn Complete(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Complete)(windows_core::Interface::as_raw(this)).ok() } + } +} +impl windows_core::RuntimeType for AdaptiveMediaSourceDownloadRequestedDeferral { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AdaptiveMediaSourceDownloadRequestedDeferral { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AdaptiveMediaSourceDownloadRequestedDeferral { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceDownloadRequestedDeferral"; +} +unsafe impl Send for AdaptiveMediaSourceDownloadRequestedDeferral {} +unsafe impl Sync for AdaptiveMediaSourceDownloadRequestedDeferral {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdaptiveMediaSourceDownloadRequestedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AdaptiveMediaSourceDownloadRequestedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl AdaptiveMediaSourceDownloadRequestedEventArgs { + pub fn ResourceType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ResourceUri(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceUri)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceByteRangeOffset(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceByteRangeOffset)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceByteRangeLength(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceByteRangeLength)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Result(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Result)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetDeferral(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeferral)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RequestId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestId)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Position(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Position)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceDuration(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceDuration)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResourceContentType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceContentType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} +impl windows_core::RuntimeType for AdaptiveMediaSourceDownloadRequestedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AdaptiveMediaSourceDownloadRequestedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AdaptiveMediaSourceDownloadRequestedEventArgs { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceDownloadRequestedEventArgs"; +} +unsafe impl Send for AdaptiveMediaSourceDownloadRequestedEventArgs {} +unsafe impl Sync for AdaptiveMediaSourceDownloadRequestedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdaptiveMediaSourceDownloadResult(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AdaptiveMediaSourceDownloadResult, windows_core::IUnknown, windows_core::IInspectable); +impl AdaptiveMediaSourceDownloadResult { + pub fn ResourceUri(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceUri)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetResourceUri(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetResourceUri)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn InputStream(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InputStream)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn SetInputStream(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetInputStream)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn Buffer(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Buffer)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn SetBuffer(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetBuffer)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn ContentType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetContentType(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetContentType)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn ExtendedStatus(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExtendedStatus)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetExtendedStatus(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetExtendedStatus)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ResourceByteRangeOffset(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceByteRangeOffset)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetResourceByteRangeOffset(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetResourceByteRangeOffset)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn ResourceByteRangeLength(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResourceByteRangeLength)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetResourceByteRangeLength(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetResourceByteRangeLength)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } +} +impl windows_core::RuntimeType for AdaptiveMediaSourceDownloadResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AdaptiveMediaSourceDownloadResult { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AdaptiveMediaSourceDownloadResult { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceDownloadResult"; +} +unsafe impl Send for AdaptiveMediaSourceDownloadResult {} +unsafe impl Sync for AdaptiveMediaSourceDownloadResult {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdaptiveMediaSourceDownloadStatistics(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AdaptiveMediaSourceDownloadStatistics, windows_core::IUnknown, windows_core::IInspectable); +impl AdaptiveMediaSourceDownloadStatistics { + pub fn ContentBytesReceivedCount(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentBytesReceivedCount)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn TimeToHeadersReceived(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TimeToHeadersReceived)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TimeToFirstByteReceived(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TimeToFirstByteReceived)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TimeToLastByteReceived(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TimeToLastByteReceived)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for AdaptiveMediaSourceDownloadStatistics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AdaptiveMediaSourceDownloadStatistics { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AdaptiveMediaSourceDownloadStatistics { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceDownloadStatistics"; +} +unsafe impl Send for AdaptiveMediaSourceDownloadStatistics {} +unsafe impl Sync for AdaptiveMediaSourceDownloadStatistics {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AdaptiveMediaSourcePlaybackBitrateChangedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(AdaptiveMediaSourcePlaybackBitrateChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl AdaptiveMediaSourcePlaybackBitrateChangedEventArgs { + pub fn OldValue(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OldValue)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn NewValue(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NewValue)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AudioOnly(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AudioOnly)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for AdaptiveMediaSourcePlaybackBitrateChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for AdaptiveMediaSourcePlaybackBitrateChangedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for AdaptiveMediaSourcePlaybackBitrateChangedEventArgs { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.AdaptiveMediaSourcePlaybackBitrateChangedEventArgs"; +} +unsafe impl Send for AdaptiveMediaSourcePlaybackBitrateChangedEventArgs {} +unsafe impl Sync for AdaptiveMediaSourcePlaybackBitrateChangedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct AdaptiveMediaSourceResourceType(pub i32); +impl AdaptiveMediaSourceResourceType { + pub const Manifest: Self = Self(0i32); + pub const InitializationSegment: Self = Self(1i32); + pub const MediaSegment: Self = Self(2i32); + pub const Key: Self = Self(3i32); + pub const InitializationVector: Self = Self(4i32); + pub const MediaSegmentIndex: Self = Self(5i32); +} +impl windows_core::TypeKind for AdaptiveMediaSourceResourceType { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for AdaptiveMediaSourceResourceType { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Media.Streaming.Adaptive.AdaptiveMediaSourceResourceType;i4)"); +} +#[cfg(feature = "Media_Core")] +windows_core::imp::define_interface!(IAdaptiveMediaSource, IAdaptiveMediaSource_Vtbl, 0x4c7332ef_d39f_4396_b4d9_043957a7c964); +#[cfg(feature = "Media_Core")] +impl windows_core::RuntimeType for IAdaptiveMediaSource { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Media_Core")] +impl windows_core::RuntimeName for IAdaptiveMediaSource { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSource"; +} +#[cfg(feature = "Media_Core")] +pub trait IAdaptiveMediaSource_Impl: super::super::Core::IMediaSource_Impl { + fn IsLive(&self) -> windows_core::Result; + fn DesiredLiveOffset(&self) -> windows_core::Result; + fn SetDesiredLiveOffset(&self, value: &super::super::super::Foundation::TimeSpan) -> windows_core::Result<()>; + fn InitialBitrate(&self) -> windows_core::Result; + fn SetInitialBitrate(&self, value: u32) -> windows_core::Result<()>; + fn CurrentDownloadBitrate(&self) -> windows_core::Result; + fn CurrentPlaybackBitrate(&self) -> windows_core::Result; + fn AvailableBitrates(&self) -> windows_core::Result>; + fn DesiredMinBitrate(&self) -> windows_core::Result>; + fn SetDesiredMinBitrate(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn DesiredMaxBitrate(&self) -> windows_core::Result>; + fn SetDesiredMaxBitrate(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn AudioOnlyPlayback(&self) -> windows_core::Result; + fn InboundBitsPerSecond(&self) -> windows_core::Result; + fn InboundBitsPerSecondWindow(&self) -> windows_core::Result; + fn SetInboundBitsPerSecondWindow(&self, value: &super::super::super::Foundation::TimeSpan) -> windows_core::Result<()>; + fn DownloadBitrateChanged(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveDownloadBitrateChanged(&self, token: i64) -> windows_core::Result<()>; + fn PlaybackBitrateChanged(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemovePlaybackBitrateChanged(&self, token: i64) -> windows_core::Result<()>; + fn DownloadRequested(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveDownloadRequested(&self, token: i64) -> windows_core::Result<()>; + fn DownloadCompleted(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveDownloadCompleted(&self, token: i64) -> windows_core::Result<()>; + fn DownloadFailed(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveDownloadFailed(&self, token: i64) -> windows_core::Result<()>; +} +#[cfg(feature = "Media_Core")] +impl IAdaptiveMediaSource_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsLive(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::IsLive(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DesiredLiveOffset(this: *mut core::ffi::c_void, result__: *mut super::super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::DesiredLiveOffset(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDesiredLiveOffset(this: *mut core::ffi::c_void, value: super::super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSource_Impl::SetDesiredLiveOffset(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn InitialBitrate(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::InitialBitrate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetInitialBitrate(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSource_Impl::SetInitialBitrate(this, value).into() + } + } + unsafe extern "system" fn CurrentDownloadBitrate(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::CurrentDownloadBitrate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CurrentPlaybackBitrate(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::CurrentPlaybackBitrate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AvailableBitrates(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::AvailableBitrates(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DesiredMinBitrate(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::DesiredMinBitrate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDesiredMinBitrate(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSource_Impl::SetDesiredMinBitrate(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn DesiredMaxBitrate(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::DesiredMaxBitrate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDesiredMaxBitrate(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSource_Impl::SetDesiredMaxBitrate(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn AudioOnlyPlayback(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::AudioOnlyPlayback(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn InboundBitsPerSecond(this: *mut core::ffi::c_void, result__: *mut u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::InboundBitsPerSecond(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn InboundBitsPerSecondWindow(this: *mut core::ffi::c_void, result__: *mut super::super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::InboundBitsPerSecondWindow(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetInboundBitsPerSecondWindow(this: *mut core::ffi::c_void, value: super::super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSource_Impl::SetInboundBitsPerSecondWindow(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn DownloadBitrateChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::DownloadBitrateChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveDownloadBitrateChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSource_Impl::RemoveDownloadBitrateChanged(this, token).into() + } + } + unsafe extern "system" fn PlaybackBitrateChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::PlaybackBitrateChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemovePlaybackBitrateChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSource_Impl::RemovePlaybackBitrateChanged(this, token).into() + } + } + unsafe extern "system" fn DownloadRequested(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::DownloadRequested(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveDownloadRequested(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSource_Impl::RemoveDownloadRequested(this, token).into() + } + } + unsafe extern "system" fn DownloadCompleted(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::DownloadCompleted(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveDownloadCompleted(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSource_Impl::RemoveDownloadCompleted(this, token).into() + } + } + unsafe extern "system" fn DownloadFailed(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource_Impl::DownloadFailed(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveDownloadFailed(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSource_Impl::RemoveDownloadFailed(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsLive: IsLive::, + DesiredLiveOffset: DesiredLiveOffset::, + SetDesiredLiveOffset: SetDesiredLiveOffset::, + InitialBitrate: InitialBitrate::, + SetInitialBitrate: SetInitialBitrate::, + CurrentDownloadBitrate: CurrentDownloadBitrate::, + CurrentPlaybackBitrate: CurrentPlaybackBitrate::, + AvailableBitrates: AvailableBitrates::, + DesiredMinBitrate: DesiredMinBitrate::, + SetDesiredMinBitrate: SetDesiredMinBitrate::, + DesiredMaxBitrate: DesiredMaxBitrate::, + SetDesiredMaxBitrate: SetDesiredMaxBitrate::, + AudioOnlyPlayback: AudioOnlyPlayback::, + InboundBitsPerSecond: InboundBitsPerSecond::, + InboundBitsPerSecondWindow: InboundBitsPerSecondWindow::, + SetInboundBitsPerSecondWindow: SetInboundBitsPerSecondWindow::, + DownloadBitrateChanged: DownloadBitrateChanged::, + RemoveDownloadBitrateChanged: RemoveDownloadBitrateChanged::, + PlaybackBitrateChanged: PlaybackBitrateChanged::, + RemovePlaybackBitrateChanged: RemovePlaybackBitrateChanged::, + DownloadRequested: DownloadRequested::, + RemoveDownloadRequested: RemoveDownloadRequested::, + DownloadCompleted: DownloadCompleted::, + RemoveDownloadCompleted: RemoveDownloadCompleted::, + DownloadFailed: DownloadFailed::, + RemoveDownloadFailed: RemoveDownloadFailed::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[cfg(feature = "Media_Core")] +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSource_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsLive: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub DesiredLiveOffset: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub SetDesiredLiveOffset: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub InitialBitrate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetInitialBitrate: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub CurrentDownloadBitrate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub CurrentPlaybackBitrate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub AvailableBitrates: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub DesiredMinBitrate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetDesiredMinBitrate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub DesiredMaxBitrate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetDesiredMaxBitrate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub AudioOnlyPlayback: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub InboundBitsPerSecond: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u64) -> windows_core::HRESULT, + pub InboundBitsPerSecondWindow: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub SetInboundBitsPerSecondWindow: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub DownloadBitrateChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveDownloadBitrateChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub PlaybackBitrateChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemovePlaybackBitrateChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub DownloadRequested: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveDownloadRequested: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub DownloadCompleted: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveDownloadCompleted: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub DownloadFailed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveDownloadFailed: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSource2, IAdaptiveMediaSource2_Vtbl, 0x17890342_6760_4bb9_a58a_f7aa98b08c0e); +impl windows_core::RuntimeType for IAdaptiveMediaSource2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSource2 { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSource2"; +} +pub trait IAdaptiveMediaSource2_Impl: windows_core::IUnknownImpl { + fn AdvancedSettings(&self) -> windows_core::Result; +} +impl IAdaptiveMediaSource2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AdvancedSettings(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource2_Impl::AdvancedSettings(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AdvancedSettings: AdvancedSettings::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSource2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AdvancedSettings: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSource3, IAdaptiveMediaSource3_Vtbl, 0xba7023fd_c334_461b_a36e_c99f54f7174a); +impl windows_core::RuntimeType for IAdaptiveMediaSource3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSource3 { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSource3"; +} +pub trait IAdaptiveMediaSource3_Impl: windows_core::IUnknownImpl { + fn MinLiveOffset(&self) -> windows_core::Result>; + fn MaxSeekableWindowSize(&self) -> windows_core::Result>; + fn DesiredSeekableWindowSize(&self) -> windows_core::Result>; + fn SetDesiredSeekableWindowSize(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn Diagnostics(&self) -> windows_core::Result; + fn GetCorrelatedTimes(&self) -> windows_core::Result; +} +impl IAdaptiveMediaSource3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn MinLiveOffset(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource3_Impl::MinLiveOffset(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxSeekableWindowSize(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource3_Impl::MaxSeekableWindowSize(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DesiredSeekableWindowSize(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource3_Impl::DesiredSeekableWindowSize(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDesiredSeekableWindowSize(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSource3_Impl::SetDesiredSeekableWindowSize(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Diagnostics(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource3_Impl::Diagnostics(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetCorrelatedTimes(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSource3_Impl::GetCorrelatedTimes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + MinLiveOffset: MinLiveOffset::, + MaxSeekableWindowSize: MaxSeekableWindowSize::, + DesiredSeekableWindowSize: DesiredSeekableWindowSize::, + SetDesiredSeekableWindowSize: SetDesiredSeekableWindowSize::, + Diagnostics: Diagnostics::, + GetCorrelatedTimes: GetCorrelatedTimes::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSource3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub MinLiveOffset: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub MaxSeekableWindowSize: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub DesiredSeekableWindowSize: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetDesiredSeekableWindowSize: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Diagnostics: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetCorrelatedTimes: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceAdvancedSettings, IAdaptiveMediaSourceAdvancedSettings_Vtbl, 0x55db1680_1aeb_47dc_aa08_9a11610ba45a); +impl windows_core::RuntimeType for IAdaptiveMediaSourceAdvancedSettings { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceAdvancedSettings { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceAdvancedSettings"; +} +pub trait IAdaptiveMediaSourceAdvancedSettings_Impl: windows_core::IUnknownImpl { + fn AllSegmentsIndependent(&self) -> windows_core::Result; + fn SetAllSegmentsIndependent(&self, value: bool) -> windows_core::Result<()>; + fn DesiredBitrateHeadroomRatio(&self) -> windows_core::Result>; + fn SetDesiredBitrateHeadroomRatio(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn BitrateDowngradeTriggerRatio(&self) -> windows_core::Result>; + fn SetBitrateDowngradeTriggerRatio(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; +} +impl IAdaptiveMediaSourceAdvancedSettings_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AllSegmentsIndependent(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceAdvancedSettings_Impl::AllSegmentsIndependent(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAllSegmentsIndependent(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSourceAdvancedSettings_Impl::SetAllSegmentsIndependent(this, value).into() + } + } + unsafe extern "system" fn DesiredBitrateHeadroomRatio(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceAdvancedSettings_Impl::DesiredBitrateHeadroomRatio(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDesiredBitrateHeadroomRatio(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSourceAdvancedSettings_Impl::SetDesiredBitrateHeadroomRatio(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn BitrateDowngradeTriggerRatio(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceAdvancedSettings_Impl::BitrateDowngradeTriggerRatio(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetBitrateDowngradeTriggerRatio(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSourceAdvancedSettings_Impl::SetBitrateDowngradeTriggerRatio(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AllSegmentsIndependent: AllSegmentsIndependent::, + SetAllSegmentsIndependent: SetAllSegmentsIndependent::, + DesiredBitrateHeadroomRatio: DesiredBitrateHeadroomRatio::, + SetDesiredBitrateHeadroomRatio: SetDesiredBitrateHeadroomRatio::, + BitrateDowngradeTriggerRatio: BitrateDowngradeTriggerRatio::, + SetBitrateDowngradeTriggerRatio: SetBitrateDowngradeTriggerRatio::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceAdvancedSettings_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub AllSegmentsIndependent: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetAllSegmentsIndependent: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + pub DesiredBitrateHeadroomRatio: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetDesiredBitrateHeadroomRatio: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub BitrateDowngradeTriggerRatio: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetBitrateDowngradeTriggerRatio: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceCorrelatedTimes, IAdaptiveMediaSourceCorrelatedTimes_Vtbl, 0x05108787_e032_48e1_ab8d_002b0b3051df); +impl windows_core::RuntimeType for IAdaptiveMediaSourceCorrelatedTimes { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceCorrelatedTimes { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceCorrelatedTimes"; +} +pub trait IAdaptiveMediaSourceCorrelatedTimes_Impl: windows_core::IUnknownImpl { + fn Position(&self) -> windows_core::Result>; + fn PresentationTimeStamp(&self) -> windows_core::Result>; + fn ProgramDateTime(&self) -> windows_core::Result>; +} +impl IAdaptiveMediaSourceCorrelatedTimes_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Position(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceCorrelatedTimes_Impl::Position(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PresentationTimeStamp(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceCorrelatedTimes_Impl::PresentationTimeStamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ProgramDateTime(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceCorrelatedTimes_Impl::ProgramDateTime(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Position: Position::, + PresentationTimeStamp: PresentationTimeStamp::, + ProgramDateTime: ProgramDateTime::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceCorrelatedTimes_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Position: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub PresentationTimeStamp: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ProgramDateTime: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceCreationResult, IAdaptiveMediaSourceCreationResult_Vtbl, 0x4686b6b2_800f_4e31_9093_76d4782013e7); +impl windows_core::RuntimeType for IAdaptiveMediaSourceCreationResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Media_Core", feature = "Web_Http"))] +impl windows_core::RuntimeName for IAdaptiveMediaSourceCreationResult { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceCreationResult"; +} +#[cfg(all(feature = "Media_Core", feature = "Web_Http"))] +pub trait IAdaptiveMediaSourceCreationResult_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; + fn MediaSource(&self) -> windows_core::Result; + fn HttpResponseMessage(&self) -> windows_core::Result; +} +#[cfg(all(feature = "Media_Core", feature = "Web_Http"))] +impl IAdaptiveMediaSourceCreationResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut AdaptiveMediaSourceCreationStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceCreationResult_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MediaSource(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceCreationResult_Impl::MediaSource(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn HttpResponseMessage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceCreationResult_Impl::HttpResponseMessage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Status: Status::, + MediaSource: MediaSource::, + HttpResponseMessage: HttpResponseMessage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceCreationResult_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Status: unsafe extern "system" fn(*mut core::ffi::c_void, *mut AdaptiveMediaSourceCreationStatus) -> windows_core::HRESULT, + #[cfg(feature = "Media_Core")] + pub MediaSource: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Media_Core"))] + MediaSource: usize, + #[cfg(feature = "Web_Http")] + pub HttpResponseMessage: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Web_Http"))] + HttpResponseMessage: usize, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceCreationResult2, IAdaptiveMediaSourceCreationResult2_Vtbl, 0x1c3243bf_1c44_404b_a201_df45ac7898e8); +impl windows_core::RuntimeType for IAdaptiveMediaSourceCreationResult2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceCreationResult2 { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceCreationResult2"; +} +pub trait IAdaptiveMediaSourceCreationResult2_Impl: windows_core::IUnknownImpl { + fn ExtendedError(&self) -> windows_core::Result; +} +impl IAdaptiveMediaSourceCreationResult2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ExtendedError(this: *mut core::ffi::c_void, result__: *mut windows_core::HRESULT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceCreationResult2_Impl::ExtendedError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ExtendedError: ExtendedError::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceCreationResult2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ExtendedError: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_core::HRESULT) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDiagnosticAvailableEventArgs, IAdaptiveMediaSourceDiagnosticAvailableEventArgs_Vtbl, 0x3af64f06_6d9c_494a_b7a9_b3a5dee6ad68); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDiagnosticAvailableEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDiagnosticAvailableEventArgs { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDiagnosticAvailableEventArgs"; +} +pub trait IAdaptiveMediaSourceDiagnosticAvailableEventArgs_Impl: windows_core::IUnknownImpl { + fn DiagnosticType(&self) -> windows_core::Result; + fn RequestId(&self) -> windows_core::Result>; + fn Position(&self) -> windows_core::Result>; + fn SegmentId(&self) -> windows_core::Result>; + fn ResourceType(&self) -> windows_core::Result>; + fn ResourceUri(&self) -> windows_core::Result; + fn ResourceByteRangeOffset(&self) -> windows_core::Result>; + fn ResourceByteRangeLength(&self) -> windows_core::Result>; + fn Bitrate(&self) -> windows_core::Result>; +} +impl IAdaptiveMediaSourceDiagnosticAvailableEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DiagnosticType(this: *mut core::ffi::c_void, result__: *mut AdaptiveMediaSourceDiagnosticType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDiagnosticAvailableEventArgs_Impl::DiagnosticType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RequestId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDiagnosticAvailableEventArgs_Impl::RequestId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Position(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDiagnosticAvailableEventArgs_Impl::Position(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SegmentId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDiagnosticAvailableEventArgs_Impl::SegmentId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDiagnosticAvailableEventArgs_Impl::ResourceType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceUri(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDiagnosticAvailableEventArgs_Impl::ResourceUri(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceByteRangeOffset(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDiagnosticAvailableEventArgs_Impl::ResourceByteRangeOffset(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceByteRangeLength(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDiagnosticAvailableEventArgs_Impl::ResourceByteRangeLength(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Bitrate(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDiagnosticAvailableEventArgs_Impl::Bitrate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DiagnosticType: DiagnosticType::, + RequestId: RequestId::, + Position: Position::, + SegmentId: SegmentId::, + ResourceType: ResourceType::, + ResourceUri: ResourceUri::, + ResourceByteRangeOffset: ResourceByteRangeOffset::, + ResourceByteRangeLength: ResourceByteRangeLength::, + Bitrate: Bitrate::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDiagnosticAvailableEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub DiagnosticType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut AdaptiveMediaSourceDiagnosticType) -> windows_core::HRESULT, + pub RequestId: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Position: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SegmentId: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResourceType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResourceUri: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResourceByteRangeOffset: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResourceByteRangeLength: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Bitrate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDiagnosticAvailableEventArgs2, IAdaptiveMediaSourceDiagnosticAvailableEventArgs2_Vtbl, 0x8c6dd857_16a5_4d9f_810e_00bd901b3ef9); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDiagnosticAvailableEventArgs2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDiagnosticAvailableEventArgs2 { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDiagnosticAvailableEventArgs2"; +} +pub trait IAdaptiveMediaSourceDiagnosticAvailableEventArgs2_Impl: windows_core::IUnknownImpl { + fn ExtendedError(&self) -> windows_core::Result; +} +impl IAdaptiveMediaSourceDiagnosticAvailableEventArgs2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ExtendedError(this: *mut core::ffi::c_void, result__: *mut windows_core::HRESULT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDiagnosticAvailableEventArgs2_Impl::ExtendedError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ExtendedError: ExtendedError::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDiagnosticAvailableEventArgs2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ExtendedError: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_core::HRESULT) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDiagnosticAvailableEventArgs3, IAdaptiveMediaSourceDiagnosticAvailableEventArgs3_Vtbl, 0xc3650cd5_daeb_4103_84da_68769ad513ff); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDiagnosticAvailableEventArgs3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDiagnosticAvailableEventArgs3 { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDiagnosticAvailableEventArgs3"; +} +pub trait IAdaptiveMediaSourceDiagnosticAvailableEventArgs3_Impl: windows_core::IUnknownImpl { + fn ResourceDuration(&self) -> windows_core::Result>; + fn ResourceContentType(&self) -> windows_core::Result; +} +impl IAdaptiveMediaSourceDiagnosticAvailableEventArgs3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ResourceDuration(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDiagnosticAvailableEventArgs3_Impl::ResourceDuration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceContentType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDiagnosticAvailableEventArgs3_Impl::ResourceContentType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ResourceDuration: ResourceDuration::, + ResourceContentType: ResourceContentType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDiagnosticAvailableEventArgs3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ResourceDuration: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResourceContentType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDiagnostics, IAdaptiveMediaSourceDiagnostics_Vtbl, 0x9b24ee68_962e_448c_aebf_b29b56098e23); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDiagnostics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDiagnostics { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDiagnostics"; +} +pub trait IAdaptiveMediaSourceDiagnostics_Impl: windows_core::IUnknownImpl { + fn DiagnosticAvailable(&self, handler: windows_core::Ref<'_, super::super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveDiagnosticAvailable(&self, token: i64) -> windows_core::Result<()>; +} +impl IAdaptiveMediaSourceDiagnostics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DiagnosticAvailable(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDiagnostics_Impl::DiagnosticAvailable(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveDiagnosticAvailable(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSourceDiagnostics_Impl::RemoveDiagnosticAvailable(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DiagnosticAvailable: DiagnosticAvailable::, + RemoveDiagnosticAvailable: RemoveDiagnosticAvailable::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDiagnostics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub DiagnosticAvailable: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveDiagnosticAvailable: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDownloadBitrateChangedEventArgs, IAdaptiveMediaSourceDownloadBitrateChangedEventArgs_Vtbl, 0x670c0a44_e04e_4eff_816a_17399f78f4ba); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDownloadBitrateChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDownloadBitrateChangedEventArgs { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDownloadBitrateChangedEventArgs"; +} +pub trait IAdaptiveMediaSourceDownloadBitrateChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn OldValue(&self) -> windows_core::Result; + fn NewValue(&self) -> windows_core::Result; +} +impl IAdaptiveMediaSourceDownloadBitrateChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn OldValue(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadBitrateChangedEventArgs_Impl::OldValue(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NewValue(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadBitrateChangedEventArgs_Impl::NewValue(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + OldValue: OldValue::, + NewValue: NewValue::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDownloadBitrateChangedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub OldValue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub NewValue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDownloadBitrateChangedEventArgs2, IAdaptiveMediaSourceDownloadBitrateChangedEventArgs2_Vtbl, 0xf3f1f444_96ae_4de0_b540_2b3246e6968c); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDownloadBitrateChangedEventArgs2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDownloadBitrateChangedEventArgs2 { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDownloadBitrateChangedEventArgs2"; +} +pub trait IAdaptiveMediaSourceDownloadBitrateChangedEventArgs2_Impl: windows_core::IUnknownImpl { + fn Reason(&self) -> windows_core::Result; +} +impl IAdaptiveMediaSourceDownloadBitrateChangedEventArgs2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Reason(this: *mut core::ffi::c_void, result__: *mut AdaptiveMediaSourceDownloadBitrateChangedReason) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadBitrateChangedEventArgs2_Impl::Reason(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Reason: Reason::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDownloadBitrateChangedEventArgs2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Reason: unsafe extern "system" fn(*mut core::ffi::c_void, *mut AdaptiveMediaSourceDownloadBitrateChangedReason) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDownloadCompletedEventArgs, IAdaptiveMediaSourceDownloadCompletedEventArgs_Vtbl, 0x19240dc3_5b37_4a1a_8970_d621cb6ca83b); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDownloadCompletedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Web_Http")] +impl windows_core::RuntimeName for IAdaptiveMediaSourceDownloadCompletedEventArgs { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDownloadCompletedEventArgs"; +} +#[cfg(feature = "Web_Http")] +pub trait IAdaptiveMediaSourceDownloadCompletedEventArgs_Impl: windows_core::IUnknownImpl { + fn ResourceType(&self) -> windows_core::Result; + fn ResourceUri(&self) -> windows_core::Result; + fn ResourceByteRangeOffset(&self) -> windows_core::Result>; + fn ResourceByteRangeLength(&self) -> windows_core::Result>; + fn HttpResponseMessage(&self) -> windows_core::Result; +} +#[cfg(feature = "Web_Http")] +impl IAdaptiveMediaSourceDownloadCompletedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ResourceType(this: *mut core::ffi::c_void, result__: *mut AdaptiveMediaSourceResourceType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadCompletedEventArgs_Impl::ResourceType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceUri(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadCompletedEventArgs_Impl::ResourceUri(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceByteRangeOffset(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadCompletedEventArgs_Impl::ResourceByteRangeOffset(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceByteRangeLength(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadCompletedEventArgs_Impl::ResourceByteRangeLength(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn HttpResponseMessage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadCompletedEventArgs_Impl::HttpResponseMessage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ResourceType: ResourceType::, + ResourceUri: ResourceUri::, + ResourceByteRangeOffset: ResourceByteRangeOffset::, + ResourceByteRangeLength: ResourceByteRangeLength::, + HttpResponseMessage: HttpResponseMessage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDownloadCompletedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ResourceType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut AdaptiveMediaSourceResourceType) -> windows_core::HRESULT, + pub ResourceUri: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResourceByteRangeOffset: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResourceByteRangeLength: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Web_Http")] + pub HttpResponseMessage: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Web_Http"))] + HttpResponseMessage: usize, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDownloadCompletedEventArgs2, IAdaptiveMediaSourceDownloadCompletedEventArgs2_Vtbl, 0x704744c4_964a_40e4_af95_9177dd6dfa00); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDownloadCompletedEventArgs2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDownloadCompletedEventArgs2 { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDownloadCompletedEventArgs2"; +} +pub trait IAdaptiveMediaSourceDownloadCompletedEventArgs2_Impl: windows_core::IUnknownImpl { + fn RequestId(&self) -> windows_core::Result; + fn Statistics(&self) -> windows_core::Result; + fn Position(&self) -> windows_core::Result>; +} +impl IAdaptiveMediaSourceDownloadCompletedEventArgs2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn RequestId(this: *mut core::ffi::c_void, result__: *mut i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadCompletedEventArgs2_Impl::RequestId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Statistics(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadCompletedEventArgs2_Impl::Statistics(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Position(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadCompletedEventArgs2_Impl::Position(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + RequestId: RequestId::, + Statistics: Statistics::, + Position: Position::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDownloadCompletedEventArgs2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub RequestId: unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, + pub Statistics: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Position: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDownloadCompletedEventArgs3, IAdaptiveMediaSourceDownloadCompletedEventArgs3_Vtbl, 0x0f8a8bd1_93b2_47c6_badc_8be2c8f7f6e8); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDownloadCompletedEventArgs3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDownloadCompletedEventArgs3 { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDownloadCompletedEventArgs3"; +} +pub trait IAdaptiveMediaSourceDownloadCompletedEventArgs3_Impl: windows_core::IUnknownImpl { + fn ResourceDuration(&self) -> windows_core::Result>; + fn ResourceContentType(&self) -> windows_core::Result; +} +impl IAdaptiveMediaSourceDownloadCompletedEventArgs3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ResourceDuration(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadCompletedEventArgs3_Impl::ResourceDuration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceContentType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadCompletedEventArgs3_Impl::ResourceContentType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ResourceDuration: ResourceDuration::, + ResourceContentType: ResourceContentType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDownloadCompletedEventArgs3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ResourceDuration: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResourceContentType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDownloadFailedEventArgs, IAdaptiveMediaSourceDownloadFailedEventArgs_Vtbl, 0x37739048_f4ab_40a4_b135_c6dfd8bd7ff1); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDownloadFailedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Web_Http")] +impl windows_core::RuntimeName for IAdaptiveMediaSourceDownloadFailedEventArgs { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDownloadFailedEventArgs"; +} +#[cfg(feature = "Web_Http")] +pub trait IAdaptiveMediaSourceDownloadFailedEventArgs_Impl: windows_core::IUnknownImpl { + fn ResourceType(&self) -> windows_core::Result; + fn ResourceUri(&self) -> windows_core::Result; + fn ResourceByteRangeOffset(&self) -> windows_core::Result>; + fn ResourceByteRangeLength(&self) -> windows_core::Result>; + fn HttpResponseMessage(&self) -> windows_core::Result; +} +#[cfg(feature = "Web_Http")] +impl IAdaptiveMediaSourceDownloadFailedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ResourceType(this: *mut core::ffi::c_void, result__: *mut AdaptiveMediaSourceResourceType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadFailedEventArgs_Impl::ResourceType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceUri(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadFailedEventArgs_Impl::ResourceUri(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceByteRangeOffset(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadFailedEventArgs_Impl::ResourceByteRangeOffset(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceByteRangeLength(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadFailedEventArgs_Impl::ResourceByteRangeLength(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn HttpResponseMessage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadFailedEventArgs_Impl::HttpResponseMessage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ResourceType: ResourceType::, + ResourceUri: ResourceUri::, + ResourceByteRangeOffset: ResourceByteRangeOffset::, + ResourceByteRangeLength: ResourceByteRangeLength::, + HttpResponseMessage: HttpResponseMessage::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDownloadFailedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ResourceType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut AdaptiveMediaSourceResourceType) -> windows_core::HRESULT, + pub ResourceUri: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResourceByteRangeOffset: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResourceByteRangeLength: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Web_Http")] + pub HttpResponseMessage: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Web_Http"))] + HttpResponseMessage: usize, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDownloadFailedEventArgs2, IAdaptiveMediaSourceDownloadFailedEventArgs2_Vtbl, 0x70919568_967c_4986_90c5_c6fc4b31e2d8); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDownloadFailedEventArgs2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDownloadFailedEventArgs2 { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDownloadFailedEventArgs2"; +} +pub trait IAdaptiveMediaSourceDownloadFailedEventArgs2_Impl: windows_core::IUnknownImpl { + fn RequestId(&self) -> windows_core::Result; + fn ExtendedError(&self) -> windows_core::Result; + fn Statistics(&self) -> windows_core::Result; + fn Position(&self) -> windows_core::Result>; +} +impl IAdaptiveMediaSourceDownloadFailedEventArgs2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn RequestId(this: *mut core::ffi::c_void, result__: *mut i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadFailedEventArgs2_Impl::RequestId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ExtendedError(this: *mut core::ffi::c_void, result__: *mut windows_core::HRESULT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadFailedEventArgs2_Impl::ExtendedError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Statistics(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadFailedEventArgs2_Impl::Statistics(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Position(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadFailedEventArgs2_Impl::Position(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + RequestId: RequestId::, + ExtendedError: ExtendedError::, + Statistics: Statistics::, + Position: Position::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDownloadFailedEventArgs2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub RequestId: unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, + pub ExtendedError: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_core::HRESULT) -> windows_core::HRESULT, + pub Statistics: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Position: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDownloadFailedEventArgs3, IAdaptiveMediaSourceDownloadFailedEventArgs3_Vtbl, 0xd0354549_1132_4a10_915a_c2211b5b9409); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDownloadFailedEventArgs3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDownloadFailedEventArgs3 { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDownloadFailedEventArgs3"; +} +pub trait IAdaptiveMediaSourceDownloadFailedEventArgs3_Impl: windows_core::IUnknownImpl { + fn ResourceDuration(&self) -> windows_core::Result>; + fn ResourceContentType(&self) -> windows_core::Result; +} +impl IAdaptiveMediaSourceDownloadFailedEventArgs3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ResourceDuration(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadFailedEventArgs3_Impl::ResourceDuration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceContentType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadFailedEventArgs3_Impl::ResourceContentType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ResourceDuration: ResourceDuration::, + ResourceContentType: ResourceContentType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDownloadFailedEventArgs3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ResourceDuration: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResourceContentType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDownloadRequestedDeferral, IAdaptiveMediaSourceDownloadRequestedDeferral_Vtbl, 0x05c68f64_fa20_4dbd_9821_4bf4c9bf77ab); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDownloadRequestedDeferral { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDownloadRequestedDeferral { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDownloadRequestedDeferral"; +} +pub trait IAdaptiveMediaSourceDownloadRequestedDeferral_Impl: windows_core::IUnknownImpl { + fn Complete(&self) -> windows_core::Result<()>; +} +impl IAdaptiveMediaSourceDownloadRequestedDeferral_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Complete(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSourceDownloadRequestedDeferral_Impl::Complete(this).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Complete: Complete::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDownloadRequestedDeferral_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Complete: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDownloadRequestedEventArgs, IAdaptiveMediaSourceDownloadRequestedEventArgs_Vtbl, 0xc83fdffd_44a9_47a2_bf96_03398b4bfaaf); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDownloadRequestedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDownloadRequestedEventArgs { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDownloadRequestedEventArgs"; +} +pub trait IAdaptiveMediaSourceDownloadRequestedEventArgs_Impl: windows_core::IUnknownImpl { + fn ResourceType(&self) -> windows_core::Result; + fn ResourceUri(&self) -> windows_core::Result; + fn ResourceByteRangeOffset(&self) -> windows_core::Result>; + fn ResourceByteRangeLength(&self) -> windows_core::Result>; + fn Result(&self) -> windows_core::Result; + fn GetDeferral(&self) -> windows_core::Result; +} +impl IAdaptiveMediaSourceDownloadRequestedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ResourceType(this: *mut core::ffi::c_void, result__: *mut AdaptiveMediaSourceResourceType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadRequestedEventArgs_Impl::ResourceType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceUri(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadRequestedEventArgs_Impl::ResourceUri(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceByteRangeOffset(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadRequestedEventArgs_Impl::ResourceByteRangeOffset(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceByteRangeLength(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadRequestedEventArgs_Impl::ResourceByteRangeLength(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Result(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadRequestedEventArgs_Impl::Result(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeferral(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadRequestedEventArgs_Impl::GetDeferral(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ResourceType: ResourceType::, + ResourceUri: ResourceUri::, + ResourceByteRangeOffset: ResourceByteRangeOffset::, + ResourceByteRangeLength: ResourceByteRangeLength::, + Result: Result::, + GetDeferral: GetDeferral::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDownloadRequestedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ResourceType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut AdaptiveMediaSourceResourceType) -> windows_core::HRESULT, + pub ResourceUri: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResourceByteRangeOffset: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResourceByteRangeLength: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Result: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetDeferral: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDownloadRequestedEventArgs2, IAdaptiveMediaSourceDownloadRequestedEventArgs2_Vtbl, 0xb37d8bfe_aa44_4d82_825b_611de3bcfecb); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDownloadRequestedEventArgs2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDownloadRequestedEventArgs2 { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDownloadRequestedEventArgs2"; +} +pub trait IAdaptiveMediaSourceDownloadRequestedEventArgs2_Impl: windows_core::IUnknownImpl { + fn RequestId(&self) -> windows_core::Result; + fn Position(&self) -> windows_core::Result>; +} +impl IAdaptiveMediaSourceDownloadRequestedEventArgs2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn RequestId(this: *mut core::ffi::c_void, result__: *mut i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadRequestedEventArgs2_Impl::RequestId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Position(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadRequestedEventArgs2_Impl::Position(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + RequestId: RequestId::, + Position: Position::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDownloadRequestedEventArgs2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub RequestId: unsafe extern "system" fn(*mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, + pub Position: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDownloadRequestedEventArgs3, IAdaptiveMediaSourceDownloadRequestedEventArgs3_Vtbl, 0x333c50fd_4f62_4481_ab44_1e47b0574225); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDownloadRequestedEventArgs3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDownloadRequestedEventArgs3 { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDownloadRequestedEventArgs3"; +} +pub trait IAdaptiveMediaSourceDownloadRequestedEventArgs3_Impl: windows_core::IUnknownImpl { + fn ResourceDuration(&self) -> windows_core::Result>; + fn ResourceContentType(&self) -> windows_core::Result; +} +impl IAdaptiveMediaSourceDownloadRequestedEventArgs3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ResourceDuration(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadRequestedEventArgs3_Impl::ResourceDuration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResourceContentType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadRequestedEventArgs3_Impl::ResourceContentType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ResourceDuration: ResourceDuration::, + ResourceContentType: ResourceContentType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDownloadRequestedEventArgs3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ResourceDuration: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResourceContentType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDownloadResult, IAdaptiveMediaSourceDownloadResult_Vtbl, 0xf4afdc73_bcee_4a6a_9f0a_fec41e2339b0); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDownloadResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IAdaptiveMediaSourceDownloadResult { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDownloadResult"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IAdaptiveMediaSourceDownloadResult_Impl: windows_core::IUnknownImpl { + fn ResourceUri(&self) -> windows_core::Result; + fn SetResourceUri(&self, value: windows_core::Ref<'_, super::super::super::Foundation::Uri>) -> windows_core::Result<()>; + fn InputStream(&self) -> windows_core::Result; + fn SetInputStream(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IInputStream>) -> windows_core::Result<()>; + fn Buffer(&self) -> windows_core::Result; + fn SetBuffer(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result<()>; + fn ContentType(&self) -> windows_core::Result; + fn SetContentType(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn ExtendedStatus(&self) -> windows_core::Result; + fn SetExtendedStatus(&self, value: u32) -> windows_core::Result<()>; +} +#[cfg(feature = "Storage_Streams")] +impl IAdaptiveMediaSourceDownloadResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ResourceUri(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadResult_Impl::ResourceUri(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetResourceUri(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSourceDownloadResult_Impl::SetResourceUri(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn InputStream(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadResult_Impl::InputStream(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetInputStream(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSourceDownloadResult_Impl::SetInputStream(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Buffer(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadResult_Impl::Buffer(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetBuffer(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSourceDownloadResult_Impl::SetBuffer(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn ContentType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadResult_Impl::ContentType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetContentType(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSourceDownloadResult_Impl::SetContentType(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn ExtendedStatus(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadResult_Impl::ExtendedStatus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetExtendedStatus(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSourceDownloadResult_Impl::SetExtendedStatus(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ResourceUri: ResourceUri::, + SetResourceUri: SetResourceUri::, + InputStream: InputStream::, + SetInputStream: SetInputStream::, + Buffer: Buffer::, + SetBuffer: SetBuffer::, + ContentType: ContentType::, + SetContentType: SetContentType::, + ExtendedStatus: ExtendedStatus::, + SetExtendedStatus: SetExtendedStatus::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDownloadResult_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ResourceUri: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetResourceUri: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Storage_Streams")] + pub InputStream: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + InputStream: usize, + #[cfg(feature = "Storage_Streams")] + pub SetInputStream: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + SetInputStream: usize, + #[cfg(feature = "Storage_Streams")] + pub Buffer: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + Buffer: usize, + #[cfg(feature = "Storage_Streams")] + pub SetBuffer: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + SetBuffer: usize, + pub ContentType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetContentType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ExtendedStatus: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetExtendedStatus: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDownloadResult2, IAdaptiveMediaSourceDownloadResult2_Vtbl, 0x15552cb7_7b80_4ac4_8660_a4b97f7c70f0); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDownloadResult2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDownloadResult2 { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDownloadResult2"; +} +pub trait IAdaptiveMediaSourceDownloadResult2_Impl: windows_core::IUnknownImpl { + fn ResourceByteRangeOffset(&self) -> windows_core::Result>; + fn SetResourceByteRangeOffset(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn ResourceByteRangeLength(&self) -> windows_core::Result>; + fn SetResourceByteRangeLength(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; +} +impl IAdaptiveMediaSourceDownloadResult2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ResourceByteRangeOffset(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadResult2_Impl::ResourceByteRangeOffset(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetResourceByteRangeOffset(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSourceDownloadResult2_Impl::SetResourceByteRangeOffset(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn ResourceByteRangeLength(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadResult2_Impl::ResourceByteRangeLength(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetResourceByteRangeLength(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IAdaptiveMediaSourceDownloadResult2_Impl::SetResourceByteRangeLength(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ResourceByteRangeOffset: ResourceByteRangeOffset::, + SetResourceByteRangeOffset: SetResourceByteRangeOffset::, + ResourceByteRangeLength: ResourceByteRangeLength::, + SetResourceByteRangeLength: SetResourceByteRangeLength::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDownloadResult2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ResourceByteRangeOffset: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetResourceByteRangeOffset: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ResourceByteRangeLength: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetResourceByteRangeLength: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceDownloadStatistics, IAdaptiveMediaSourceDownloadStatistics_Vtbl, 0xa306cefb_e96a_4dff_a9b8_1ae08c01ae98); +impl windows_core::RuntimeType for IAdaptiveMediaSourceDownloadStatistics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourceDownloadStatistics { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceDownloadStatistics"; +} +pub trait IAdaptiveMediaSourceDownloadStatistics_Impl: windows_core::IUnknownImpl { + fn ContentBytesReceivedCount(&self) -> windows_core::Result; + fn TimeToHeadersReceived(&self) -> windows_core::Result>; + fn TimeToFirstByteReceived(&self) -> windows_core::Result>; + fn TimeToLastByteReceived(&self) -> windows_core::Result>; +} +impl IAdaptiveMediaSourceDownloadStatistics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ContentBytesReceivedCount(this: *mut core::ffi::c_void, result__: *mut u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadStatistics_Impl::ContentBytesReceivedCount(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TimeToHeadersReceived(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadStatistics_Impl::TimeToHeadersReceived(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TimeToFirstByteReceived(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadStatistics_Impl::TimeToFirstByteReceived(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TimeToLastByteReceived(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceDownloadStatistics_Impl::TimeToLastByteReceived(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ContentBytesReceivedCount: ContentBytesReceivedCount::, + TimeToHeadersReceived: TimeToHeadersReceived::, + TimeToFirstByteReceived: TimeToFirstByteReceived::, + TimeToLastByteReceived: TimeToLastByteReceived::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceDownloadStatistics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ContentBytesReceivedCount: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u64) -> windows_core::HRESULT, + pub TimeToHeadersReceived: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub TimeToFirstByteReceived: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub TimeToLastByteReceived: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourcePlaybackBitrateChangedEventArgs, IAdaptiveMediaSourcePlaybackBitrateChangedEventArgs_Vtbl, 0x23a29f6d_7dda_4a51_87a9_6fa8c5b292be); +impl windows_core::RuntimeType for IAdaptiveMediaSourcePlaybackBitrateChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IAdaptiveMediaSourcePlaybackBitrateChangedEventArgs { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourcePlaybackBitrateChangedEventArgs"; +} +pub trait IAdaptiveMediaSourcePlaybackBitrateChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn OldValue(&self) -> windows_core::Result; + fn NewValue(&self) -> windows_core::Result; + fn AudioOnly(&self) -> windows_core::Result; +} +impl IAdaptiveMediaSourcePlaybackBitrateChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn OldValue(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourcePlaybackBitrateChangedEventArgs_Impl::OldValue(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NewValue(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourcePlaybackBitrateChangedEventArgs_Impl::NewValue(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AudioOnly(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourcePlaybackBitrateChangedEventArgs_Impl::AudioOnly(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + OldValue: OldValue::, + NewValue: NewValue::, + AudioOnly: AudioOnly::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourcePlaybackBitrateChangedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub OldValue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub NewValue: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub AudioOnly: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IAdaptiveMediaSourceStatics, IAdaptiveMediaSourceStatics_Vtbl, 0x50a6bd5d_66ef_4cd3_9579_9e660507dc3f); +impl windows_core::RuntimeType for IAdaptiveMediaSourceStatics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Storage_Streams", feature = "Web_Http"))] +impl windows_core::RuntimeName for IAdaptiveMediaSourceStatics { + const NAME: &'static str = "Windows.Media.Streaming.Adaptive.IAdaptiveMediaSourceStatics"; +} +#[cfg(all(feature = "Storage_Streams", feature = "Web_Http"))] +pub trait IAdaptiveMediaSourceStatics_Impl: windows_core::IUnknownImpl { + fn IsContentTypeSupported(&self, contentType: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromUriAsync(&self, uri: windows_core::Ref<'_, super::super::super::Foundation::Uri>) -> windows_core::Result>; + fn CreateFromUriWithDownloaderAsync(&self, uri: windows_core::Ref<'_, super::super::super::Foundation::Uri>, httpClient: windows_core::Ref<'_, super::super::super::Web::Http::HttpClient>) -> windows_core::Result>; + fn CreateFromStreamAsync(&self, stream: windows_core::Ref<'_, super::super::super::Storage::Streams::IInputStream>, uri: windows_core::Ref<'_, super::super::super::Foundation::Uri>, contentType: &windows_core::HSTRING) -> windows_core::Result>; + fn CreateFromStreamWithDownloaderAsync(&self, stream: windows_core::Ref<'_, super::super::super::Storage::Streams::IInputStream>, uri: windows_core::Ref<'_, super::super::super::Foundation::Uri>, contentType: &windows_core::HSTRING, httpClient: windows_core::Ref<'_, super::super::super::Web::Http::HttpClient>) -> windows_core::Result>; +} +#[cfg(all(feature = "Storage_Streams", feature = "Web_Http"))] +impl IAdaptiveMediaSourceStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsContentTypeSupported(this: *mut core::ffi::c_void, contenttype: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceStatics_Impl::IsContentTypeSupported(this, core::mem::transmute(&contenttype)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromUriAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceStatics_Impl::CreateFromUriAsync(this, core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromUriWithDownloaderAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, httpclient: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceStatics_Impl::CreateFromUriWithDownloaderAsync(this, core::mem::transmute_copy(&uri), core::mem::transmute_copy(&httpclient)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromStreamAsync(this: *mut core::ffi::c_void, stream: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, contenttype: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceStatics_Impl::CreateFromStreamAsync(this, core::mem::transmute_copy(&stream), core::mem::transmute_copy(&uri), core::mem::transmute(&contenttype)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromStreamWithDownloaderAsync(this: *mut core::ffi::c_void, stream: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, contenttype: *mut core::ffi::c_void, httpclient: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAdaptiveMediaSourceStatics_Impl::CreateFromStreamWithDownloaderAsync(this, core::mem::transmute_copy(&stream), core::mem::transmute_copy(&uri), core::mem::transmute(&contenttype), core::mem::transmute_copy(&httpclient)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsContentTypeSupported: IsContentTypeSupported::, + CreateFromUriAsync: CreateFromUriAsync::, + CreateFromUriWithDownloaderAsync: CreateFromUriWithDownloaderAsync::, + CreateFromStreamAsync: CreateFromStreamAsync::, + CreateFromStreamWithDownloaderAsync: CreateFromStreamWithDownloaderAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IAdaptiveMediaSourceStatics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsContentTypeSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub CreateFromUriAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Web_Http")] + pub CreateFromUriWithDownloaderAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Web_Http"))] + CreateFromUriWithDownloaderAsync: usize, + #[cfg(feature = "Storage_Streams")] + pub CreateFromStreamAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + CreateFromStreamAsync: usize, + #[cfg(all(feature = "Storage_Streams", feature = "Web_Http"))] + pub CreateFromStreamWithDownloaderAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Storage_Streams", feature = "Web_Http")))] + CreateFromStreamWithDownloaderAsync: usize, +} +} +} +} +#[cfg(feature = "Networking")] pub mod Networking{ #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] pub struct EndpointPair(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(EndpointPair, windows_core::IUnknown, windows_core::IInspectable); impl EndpointPair { + pub fn LocalHostName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LocalHostName)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetLocalHostName(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetLocalHostName)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn LocalServiceName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LocalServiceName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetLocalServiceName(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetLocalServiceName)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn RemoteHostName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RemoteHostName)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetRemoteHostName(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetRemoteHostName)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn RemoteServiceName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RemoteServiceName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetRemoteServiceName(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetRemoteServiceName)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn CreateEndpointPair(localhostname: P0, localservicename: &windows_core::HSTRING, remotehostname: P2, remoteservicename: &windows_core::HSTRING) -> windows_core::Result + where + P0: windows_core::Param, + P2: windows_core::Param, + { + Self::IEndpointPairFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateEndpointPair)(windows_core::Interface::as_raw(this), localhostname.param().abi(), core::mem::transmute_copy(localservicename), remotehostname.param().abi(), core::mem::transmute_copy(remoteservicename), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IEndpointPairFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -12141,12 +70692,71 @@ pub struct HostName(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HostName, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HostName, super::Foundation::IStringable); impl HostName { + #[cfg(feature = "Networking_Connectivity")] + pub fn IPInformation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IPInformation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RawName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RawName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn DisplayName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn CanonicalName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanonicalName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsEqual(&self, hostname: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsEqual)(windows_core::Interface::as_raw(this), hostname.param().abi(), &mut result__).map(|| result__) + } + } pub fn CreateHostName(hostname: &windows_core::HSTRING) -> windows_core::Result { Self::IHostNameFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).CreateHostName)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(hostname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn Compare(value1: &windows_core::HSTRING, value2: &windows_core::HSTRING) -> windows_core::Result { + Self::IHostNameStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Compare)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value1), core::mem::transmute_copy(value2), &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHostNameFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -12233,6 +70843,113 @@ windows_core::imp::define_interface!(IEndpointPair, IEndpointPair_Vtbl, 0x33a0aa impl windows_core::RuntimeType for IEndpointPair { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IEndpointPair { + const NAME: &'static str = "Windows.Networking.IEndpointPair"; +} +pub trait IEndpointPair_Impl: windows_core::IUnknownImpl { + fn LocalHostName(&self) -> windows_core::Result; + fn SetLocalHostName(&self, value: windows_core::Ref<'_, HostName>) -> windows_core::Result<()>; + fn LocalServiceName(&self) -> windows_core::Result; + fn SetLocalServiceName(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn RemoteHostName(&self) -> windows_core::Result; + fn SetRemoteHostName(&self, value: windows_core::Ref<'_, HostName>) -> windows_core::Result<()>; + fn RemoteServiceName(&self) -> windows_core::Result; + fn SetRemoteServiceName(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; +} +impl IEndpointPair_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn LocalHostName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IEndpointPair_Impl::LocalHostName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetLocalHostName(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IEndpointPair_Impl::SetLocalHostName(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn LocalServiceName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IEndpointPair_Impl::LocalServiceName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetLocalServiceName(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IEndpointPair_Impl::SetLocalServiceName(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn RemoteHostName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IEndpointPair_Impl::RemoteHostName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRemoteHostName(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IEndpointPair_Impl::SetRemoteHostName(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn RemoteServiceName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IEndpointPair_Impl::RemoteServiceName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRemoteServiceName(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IEndpointPair_Impl::SetRemoteServiceName(this, core::mem::transmute(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + LocalHostName: LocalHostName::, + SetLocalHostName: SetLocalHostName::, + LocalServiceName: LocalServiceName::, + SetLocalServiceName: SetLocalServiceName::, + RemoteHostName: RemoteHostName::, + SetRemoteHostName: SetRemoteHostName::, + RemoteServiceName: RemoteServiceName::, + SetRemoteServiceName: SetRemoteServiceName::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IEndpointPair_Vtbl { @@ -12250,6 +70967,36 @@ windows_core::imp::define_interface!(IEndpointPairFactory, IEndpointPairFactory_ impl windows_core::RuntimeType for IEndpointPairFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IEndpointPairFactory { + const NAME: &'static str = "Windows.Networking.IEndpointPairFactory"; +} +pub trait IEndpointPairFactory_Impl: windows_core::IUnknownImpl { + fn CreateEndpointPair(&self, localHostName: windows_core::Ref<'_, HostName>, localServiceName: &windows_core::HSTRING, remoteHostName: windows_core::Ref<'_, HostName>, remoteServiceName: &windows_core::HSTRING) -> windows_core::Result; +} +impl IEndpointPairFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateEndpointPair(this: *mut core::ffi::c_void, localhostname: *mut core::ffi::c_void, localservicename: *mut core::ffi::c_void, remotehostname: *mut core::ffi::c_void, remoteservicename: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IEndpointPairFactory_Impl::CreateEndpointPair(this, core::mem::transmute_copy(&localhostname), core::mem::transmute(&localservicename), core::mem::transmute_copy(&remotehostname), core::mem::transmute(&remoteservicename)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateEndpointPair: CreateEndpointPair::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IEndpointPairFactory_Vtbl { @@ -12260,6 +71007,112 @@ windows_core::imp::define_interface!(IHostName, IHostName_Vtbl, 0xbf8ecaad_ed96_ impl windows_core::RuntimeType for IHostName { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Networking_Connectivity")] +impl windows_core::RuntimeName for IHostName { + const NAME: &'static str = "Windows.Networking.IHostName"; +} +#[cfg(feature = "Networking_Connectivity")] +pub trait IHostName_Impl: windows_core::IUnknownImpl { + fn IPInformation(&self) -> windows_core::Result; + fn RawName(&self) -> windows_core::Result; + fn DisplayName(&self) -> windows_core::Result; + fn CanonicalName(&self) -> windows_core::Result; + fn Type(&self) -> windows_core::Result; + fn IsEqual(&self, hostName: windows_core::Ref<'_, HostName>) -> windows_core::Result; +} +#[cfg(feature = "Networking_Connectivity")] +impl IHostName_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IPInformation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHostName_Impl::IPInformation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RawName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHostName_Impl::RawName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DisplayName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHostName_Impl::DisplayName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CanonicalName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHostName_Impl::CanonicalName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Type(this: *mut core::ffi::c_void, result__: *mut HostNameType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHostName_Impl::Type(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsEqual(this: *mut core::ffi::c_void, hostname: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHostName_Impl::IsEqual(this, core::mem::transmute_copy(&hostname)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IPInformation: IPInformation::, + RawName: RawName::, + DisplayName: DisplayName::, + CanonicalName: CanonicalName::, + Type: Type::, + IsEqual: IsEqual::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHostName_Vtbl { @@ -12278,6 +71131,33 @@ windows_core::imp::define_interface!(IHostNameFactory, IHostNameFactory_Vtbl, 0x impl windows_core::RuntimeType for IHostNameFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHostNameFactory { + const NAME: &'static str = "Windows.Networking.IHostNameFactory"; +} +pub trait IHostNameFactory_Impl: windows_core::IUnknownImpl { + fn CreateHostName(&self, hostName: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHostNameFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateHostName(this: *mut core::ffi::c_void, hostname: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHostNameFactory_Impl::CreateHostName(this, core::mem::transmute(&hostname)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), CreateHostName: CreateHostName:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHostNameFactory_Vtbl { @@ -12288,17 +71168,1422 @@ windows_core::imp::define_interface!(IHostNameStatics, IHostNameStatics_Vtbl, 0x impl windows_core::RuntimeType for IHostNameStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHostNameStatics { + const NAME: &'static str = "Windows.Networking.IHostNameStatics"; +} +pub trait IHostNameStatics_Impl: windows_core::IUnknownImpl { + fn Compare(&self, value1: &windows_core::HSTRING, value2: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHostNameStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Compare(this: *mut core::ffi::c_void, value1: *mut core::ffi::c_void, value2: *mut core::ffi::c_void, result__: *mut i32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHostNameStatics_Impl::Compare(this, core::mem::transmute(&value1), core::mem::transmute(&value2)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Compare: Compare:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHostNameStatics_Vtbl { pub base__: windows_core::IInspectable_Vtbl, pub Compare: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut i32) -> windows_core::HRESULT, } +#[cfg(feature = "Networking_BackgroundTransfer")] +pub mod BackgroundTransfer{ +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct BackgroundDownloadProgress { + pub BytesReceived: u64, + pub TotalBytesToReceive: u64, + pub Status: BackgroundTransferStatus, + pub HasResponseChanged: bool, + pub HasRestarted: bool, +} +impl windows_core::TypeKind for BackgroundDownloadProgress { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for BackgroundDownloadProgress { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"struct(Windows.Networking.BackgroundTransfer.BackgroundDownloadProgress;u8;u8;enum(Windows.Networking.BackgroundTransfer.BackgroundTransferStatus;i4);b1;b1)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct BackgroundTransferBehavior(pub i32); +impl BackgroundTransferBehavior { + pub const Parallel: Self = Self(0i32); + pub const Serialized: Self = Self(1i32); +} +impl windows_core::TypeKind for BackgroundTransferBehavior { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for BackgroundTransferBehavior { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Networking.BackgroundTransfer.BackgroundTransferBehavior;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct BackgroundTransferCostPolicy(pub i32); +impl BackgroundTransferCostPolicy { + pub const Default: Self = Self(0i32); + pub const UnrestrictedOnly: Self = Self(1i32); + pub const Always: Self = Self(2i32); +} +impl windows_core::TypeKind for BackgroundTransferCostPolicy { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for BackgroundTransferCostPolicy { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Networking.BackgroundTransfer.BackgroundTransferCostPolicy;i4)"); +} +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct BackgroundTransferFileRange { + pub Offset: u64, + pub Length: u64, +} +impl windows_core::TypeKind for BackgroundTransferFileRange { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for BackgroundTransferFileRange { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"struct(Windows.Networking.BackgroundTransfer.BackgroundTransferFileRange;u8;u8)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct BackgroundTransferGroup(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(BackgroundTransferGroup, windows_core::IUnknown, windows_core::IInspectable); +impl BackgroundTransferGroup { + pub fn Name(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn TransferBehavior(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TransferBehavior)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetTransferBehavior(&self, value: BackgroundTransferBehavior) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetTransferBehavior)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn CreateGroup(name: &windows_core::HSTRING) -> windows_core::Result { + Self::IBackgroundTransferGroupStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateGroup)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn IBackgroundTransferGroupStatics windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for BackgroundTransferGroup { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for BackgroundTransferGroup { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for BackgroundTransferGroup { + const NAME: &'static str = "Windows.Networking.BackgroundTransfer.BackgroundTransferGroup"; +} +unsafe impl Send for BackgroundTransferGroup {} +unsafe impl Sync for BackgroundTransferGroup {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct BackgroundTransferPriority(pub i32); +impl BackgroundTransferPriority { + pub const Default: Self = Self(0i32); + pub const High: Self = Self(1i32); + pub const Low: Self = Self(2i32); +} +impl windows_core::TypeKind for BackgroundTransferPriority { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for BackgroundTransferPriority { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Networking.BackgroundTransfer.BackgroundTransferPriority;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct BackgroundTransferRangesDownloadedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(BackgroundTransferRangesDownloadedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl BackgroundTransferRangesDownloadedEventArgs { + pub fn WasDownloadRestarted(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WasDownloadRestarted)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AddedRanges(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AddedRanges)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetDeferral(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeferral)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for BackgroundTransferRangesDownloadedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for BackgroundTransferRangesDownloadedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for BackgroundTransferRangesDownloadedEventArgs { + const NAME: &'static str = "Windows.Networking.BackgroundTransfer.BackgroundTransferRangesDownloadedEventArgs"; +} +unsafe impl Send for BackgroundTransferRangesDownloadedEventArgs {} +unsafe impl Sync for BackgroundTransferRangesDownloadedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct BackgroundTransferStatus(pub i32); +impl BackgroundTransferStatus { + pub const Idle: Self = Self(0i32); + pub const Running: Self = Self(1i32); + pub const PausedByApplication: Self = Self(2i32); + pub const PausedCostedNetwork: Self = Self(3i32); + pub const PausedNoNetwork: Self = Self(4i32); + pub const Completed: Self = Self(5i32); + pub const Canceled: Self = Self(6i32); + pub const Error: Self = Self(7i32); + pub const PausedRecoverableWebErrorStatus: Self = Self(8i32); + pub const PausedSystemPolicy: Self = Self(32i32); +} +impl windows_core::TypeKind for BackgroundTransferStatus { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for BackgroundTransferStatus { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Networking.BackgroundTransfer.BackgroundTransferStatus;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct DownloadOperation(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(DownloadOperation, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(DownloadOperation, IBackgroundTransferOperation, IBackgroundTransferOperationPriority); +impl DownloadOperation { + pub fn Guid(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Guid)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn RequestedUri(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestedUri)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Method(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Method)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(feature = "deprecated")] + pub fn Group(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Group)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn CostPolicy(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CostPolicy)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetCostPolicy(&self, value: BackgroundTransferCostPolicy) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetCostPolicy)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetResultStreamAt(&self, position: u64) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetResultStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetResponseInformation(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetResponseInformation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Priority(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Priority)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetPriority(&self, value: BackgroundTransferPriority) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetPriority)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn ResultFile(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResultFile)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Progress(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Progress)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn StartAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StartAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn AttachAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AttachAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Pause(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Pause)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn Resume(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Resume)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn TransferGroup(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TransferGroup)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IsRandomAccessRequired(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsRandomAccessRequired)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetIsRandomAccessRequired(&self, value: bool) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetIsRandomAccessRequired)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetResultRandomAccessStreamReference(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetResultRandomAccessStreamReference)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetDownloadedRanges(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDownloadedRanges)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RangesDownloaded(&self, eventhandler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RangesDownloaded)(windows_core::Interface::as_raw(this), eventhandler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveRangesDownloaded(&self, eventcookie: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveRangesDownloaded)(windows_core::Interface::as_raw(this), eventcookie).ok() } + } + pub fn SetRequestedUri(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetRequestedUri)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + #[cfg(feature = "Web")] + pub fn RecoverableWebErrorStatuses(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RecoverableWebErrorStatuses)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Web")] + pub fn CurrentWebErrorStatus(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CurrentWebErrorStatus)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MakeCurrentInTransferGroup(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).MakeCurrentInTransferGroup)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn SetRequestHeader(&self, headername: &windows_core::HSTRING, headervalue: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetRequestHeader)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(headername), core::mem::transmute_copy(headervalue)).ok() } + } + pub fn RemoveRequestHeader(&self, headername: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveRequestHeader)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(headername)).ok() } + } +} +impl windows_core::RuntimeType for DownloadOperation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for DownloadOperation { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for DownloadOperation { + const NAME: &'static str = "Windows.Networking.BackgroundTransfer.DownloadOperation"; +} +unsafe impl Send for DownloadOperation {} +unsafe impl Sync for DownloadOperation {} +windows_core::imp::define_interface!(IBackgroundTransferGroup, IBackgroundTransferGroup_Vtbl, 0xd8c3e3e4_6459_4540_85eb_aaa1c8903677); +impl windows_core::RuntimeType for IBackgroundTransferGroup { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IBackgroundTransferGroup { + const NAME: &'static str = "Windows.Networking.BackgroundTransfer.IBackgroundTransferGroup"; +} +pub trait IBackgroundTransferGroup_Impl: windows_core::IUnknownImpl { + fn Name(&self) -> windows_core::Result; + fn TransferBehavior(&self) -> windows_core::Result; + fn SetTransferBehavior(&self, value: BackgroundTransferBehavior) -> windows_core::Result<()>; +} +impl IBackgroundTransferGroup_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Name(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBackgroundTransferGroup_Impl::Name(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TransferBehavior(this: *mut core::ffi::c_void, result__: *mut BackgroundTransferBehavior) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBackgroundTransferGroup_Impl::TransferBehavior(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetTransferBehavior(this: *mut core::ffi::c_void, value: BackgroundTransferBehavior) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBackgroundTransferGroup_Impl::SetTransferBehavior(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Name: Name::, + TransferBehavior: TransferBehavior::, + SetTransferBehavior: SetTransferBehavior::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IBackgroundTransferGroup_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Name: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub TransferBehavior: unsafe extern "system" fn(*mut core::ffi::c_void, *mut BackgroundTransferBehavior) -> windows_core::HRESULT, + pub SetTransferBehavior: unsafe extern "system" fn(*mut core::ffi::c_void, BackgroundTransferBehavior) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IBackgroundTransferGroupStatics, IBackgroundTransferGroupStatics_Vtbl, 0x02ec50b2_7d18_495b_aa22_32a97d45d3e2); +impl windows_core::RuntimeType for IBackgroundTransferGroupStatics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IBackgroundTransferGroupStatics { + const NAME: &'static str = "Windows.Networking.BackgroundTransfer.IBackgroundTransferGroupStatics"; +} +pub trait IBackgroundTransferGroupStatics_Impl: windows_core::IUnknownImpl { + fn CreateGroup(&self, name: &windows_core::HSTRING) -> windows_core::Result; +} +impl IBackgroundTransferGroupStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateGroup(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBackgroundTransferGroupStatics_Impl::CreateGroup(this, core::mem::transmute(&name)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateGroup: CreateGroup::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IBackgroundTransferGroupStatics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub CreateGroup: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IBackgroundTransferOperation, IBackgroundTransferOperation_Vtbl, 0xded06846_90ca_44fb_8fb1_124154c0d539); +impl windows_core::RuntimeType for IBackgroundTransferOperation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IBackgroundTransferOperation, windows_core::IUnknown, windows_core::IInspectable); +impl IBackgroundTransferOperation { + pub fn Guid(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Guid)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn RequestedUri(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestedUri)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Method(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Method)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(feature = "deprecated")] + pub fn Group(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Group)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn CostPolicy(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CostPolicy)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetCostPolicy(&self, value: BackgroundTransferCostPolicy) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetCostPolicy)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetResultStreamAt(&self, position: u64) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetResultStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetResponseInformation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetResponseInformation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IBackgroundTransferOperation { + const NAME: &'static str = "Windows.Networking.BackgroundTransfer.IBackgroundTransferOperation"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IBackgroundTransferOperation_Impl: windows_core::IUnknownImpl { + fn Guid(&self) -> windows_core::Result; + fn RequestedUri(&self) -> windows_core::Result; + fn Method(&self) -> windows_core::Result; + fn Group(&self) -> windows_core::Result; + fn CostPolicy(&self) -> windows_core::Result; + fn SetCostPolicy(&self, value: BackgroundTransferCostPolicy) -> windows_core::Result<()>; + fn GetResultStreamAt(&self, position: u64) -> windows_core::Result; + fn GetResponseInformation(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IBackgroundTransferOperation_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Guid(this: *mut core::ffi::c_void, result__: *mut windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBackgroundTransferOperation_Impl::Guid(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RequestedUri(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBackgroundTransferOperation_Impl::RequestedUri(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Method(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBackgroundTransferOperation_Impl::Method(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Group(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBackgroundTransferOperation_Impl::Group(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CostPolicy(this: *mut core::ffi::c_void, result__: *mut BackgroundTransferCostPolicy) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBackgroundTransferOperation_Impl::CostPolicy(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetCostPolicy(this: *mut core::ffi::c_void, value: BackgroundTransferCostPolicy) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBackgroundTransferOperation_Impl::SetCostPolicy(this, value).into() + } + } + unsafe extern "system" fn GetResultStreamAt(this: *mut core::ffi::c_void, position: u64, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBackgroundTransferOperation_Impl::GetResultStreamAt(this, position) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetResponseInformation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBackgroundTransferOperation_Impl::GetResponseInformation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Guid: Guid::, + RequestedUri: RequestedUri::, + Method: Method::, + Group: Group::, + CostPolicy: CostPolicy::, + SetCostPolicy: SetCostPolicy::, + GetResultStreamAt: GetResultStreamAt::, + GetResponseInformation: GetResponseInformation::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IBackgroundTransferOperation_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Guid: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_core::GUID) -> windows_core::HRESULT, + pub RequestedUri: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Method: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "deprecated")] + pub Group: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + Group: usize, + pub CostPolicy: unsafe extern "system" fn(*mut core::ffi::c_void, *mut BackgroundTransferCostPolicy) -> windows_core::HRESULT, + pub SetCostPolicy: unsafe extern "system" fn(*mut core::ffi::c_void, BackgroundTransferCostPolicy) -> windows_core::HRESULT, + #[cfg(feature = "Storage_Streams")] + pub GetResultStreamAt: unsafe extern "system" fn(*mut core::ffi::c_void, u64, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + GetResultStreamAt: usize, + pub GetResponseInformation: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IBackgroundTransferOperationPriority, IBackgroundTransferOperationPriority_Vtbl, 0x04854327_5254_4b3a_915e_0aa49275c0f9); +impl windows_core::RuntimeType for IBackgroundTransferOperationPriority { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IBackgroundTransferOperationPriority, windows_core::IUnknown, windows_core::IInspectable); +impl IBackgroundTransferOperationPriority { + pub fn Priority(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Priority)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetPriority(&self, value: BackgroundTransferPriority) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPriority)(windows_core::Interface::as_raw(this), value).ok() } + } +} +impl windows_core::RuntimeName for IBackgroundTransferOperationPriority { + const NAME: &'static str = "Windows.Networking.BackgroundTransfer.IBackgroundTransferOperationPriority"; +} +pub trait IBackgroundTransferOperationPriority_Impl: windows_core::IUnknownImpl { + fn Priority(&self) -> windows_core::Result; + fn SetPriority(&self, value: BackgroundTransferPriority) -> windows_core::Result<()>; +} +impl IBackgroundTransferOperationPriority_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Priority(this: *mut core::ffi::c_void, result__: *mut BackgroundTransferPriority) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBackgroundTransferOperationPriority_Impl::Priority(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPriority(this: *mut core::ffi::c_void, value: BackgroundTransferPriority) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IBackgroundTransferOperationPriority_Impl::SetPriority(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Priority: Priority::, + SetPriority: SetPriority::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IBackgroundTransferOperationPriority_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Priority: unsafe extern "system" fn(*mut core::ffi::c_void, *mut BackgroundTransferPriority) -> windows_core::HRESULT, + pub SetPriority: unsafe extern "system" fn(*mut core::ffi::c_void, BackgroundTransferPriority) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IBackgroundTransferRangesDownloadedEventArgs, IBackgroundTransferRangesDownloadedEventArgs_Vtbl, 0x3ebc7453_bf48_4a88_9248_b0c165184f5c); +impl windows_core::RuntimeType for IBackgroundTransferRangesDownloadedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IBackgroundTransferRangesDownloadedEventArgs { + const NAME: &'static str = "Windows.Networking.BackgroundTransfer.IBackgroundTransferRangesDownloadedEventArgs"; +} +pub trait IBackgroundTransferRangesDownloadedEventArgs_Impl: windows_core::IUnknownImpl { + fn WasDownloadRestarted(&self) -> windows_core::Result; + fn AddedRanges(&self) -> windows_core::Result>; + fn GetDeferral(&self) -> windows_core::Result; +} +impl IBackgroundTransferRangesDownloadedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn WasDownloadRestarted(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBackgroundTransferRangesDownloadedEventArgs_Impl::WasDownloadRestarted(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AddedRanges(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBackgroundTransferRangesDownloadedEventArgs_Impl::AddedRanges(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDeferral(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBackgroundTransferRangesDownloadedEventArgs_Impl::GetDeferral(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + WasDownloadRestarted: WasDownloadRestarted::, + AddedRanges: AddedRanges::, + GetDeferral: GetDeferral::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IBackgroundTransferRangesDownloadedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub WasDownloadRestarted: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub AddedRanges: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetDeferral: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IDownloadOperation, IDownloadOperation_Vtbl, 0xbd87ebb0_5714_4e09_ba68_bef73903b0d7); +impl windows_core::RuntimeType for IDownloadOperation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IDownloadOperation { + const NAME: &'static str = "Windows.Networking.BackgroundTransfer.IDownloadOperation"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IDownloadOperation_Impl: IBackgroundTransferOperation_Impl { + fn ResultFile(&self) -> windows_core::Result; + fn Progress(&self) -> windows_core::Result; + fn StartAsync(&self) -> windows_core::Result>; + fn AttachAsync(&self) -> windows_core::Result>; + fn Pause(&self) -> windows_core::Result<()>; + fn Resume(&self) -> windows_core::Result<()>; +} +#[cfg(feature = "Storage_Streams")] +impl IDownloadOperation_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ResultFile(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDownloadOperation_Impl::ResultFile(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Progress(this: *mut core::ffi::c_void, result__: *mut BackgroundDownloadProgress) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDownloadOperation_Impl::Progress(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StartAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDownloadOperation_Impl::StartAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AttachAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDownloadOperation_Impl::AttachAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Pause(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDownloadOperation_Impl::Pause(this).into() + } + } + unsafe extern "system" fn Resume(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDownloadOperation_Impl::Resume(this).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ResultFile: ResultFile::, + Progress: Progress::, + StartAsync: StartAsync::, + AttachAsync: AttachAsync::, + Pause: Pause::, + Resume: Resume::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IDownloadOperation_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Storage_Streams")] + pub ResultFile: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + ResultFile: usize, + pub Progress: unsafe extern "system" fn(*mut core::ffi::c_void, *mut BackgroundDownloadProgress) -> windows_core::HRESULT, + pub StartAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub AttachAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Pause: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, + pub Resume: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IDownloadOperation2, IDownloadOperation2_Vtbl, 0xa3cced40_8f9c_4353_9cd4_290dee387c38); +impl windows_core::RuntimeType for IDownloadOperation2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IDownloadOperation2 { + const NAME: &'static str = "Windows.Networking.BackgroundTransfer.IDownloadOperation2"; +} +pub trait IDownloadOperation2_Impl: windows_core::IUnknownImpl { + fn TransferGroup(&self) -> windows_core::Result; +} +impl IDownloadOperation2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TransferGroup(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDownloadOperation2_Impl::TransferGroup(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), TransferGroup: TransferGroup:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IDownloadOperation2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub TransferGroup: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IDownloadOperation3, IDownloadOperation3_Vtbl, 0x5027351c_7d5e_4adc_b8d3_df5c6031b9cc); +impl windows_core::RuntimeType for IDownloadOperation3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Storage_Streams", feature = "Web"))] +impl windows_core::RuntimeName for IDownloadOperation3 { + const NAME: &'static str = "Windows.Networking.BackgroundTransfer.IDownloadOperation3"; +} +#[cfg(all(feature = "Storage_Streams", feature = "Web"))] +pub trait IDownloadOperation3_Impl: windows_core::IUnknownImpl { + fn IsRandomAccessRequired(&self) -> windows_core::Result; + fn SetIsRandomAccessRequired(&self, value: bool) -> windows_core::Result<()>; + fn GetResultRandomAccessStreamReference(&self) -> windows_core::Result; + fn GetDownloadedRanges(&self) -> windows_core::Result>; + fn RangesDownloaded(&self, eventHandler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveRangesDownloaded(&self, eventCookie: i64) -> windows_core::Result<()>; + fn SetRequestedUri(&self, value: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result<()>; + fn RecoverableWebErrorStatuses(&self) -> windows_core::Result>; + fn CurrentWebErrorStatus(&self) -> windows_core::Result>; +} +#[cfg(all(feature = "Storage_Streams", feature = "Web"))] +impl IDownloadOperation3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsRandomAccessRequired(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDownloadOperation3_Impl::IsRandomAccessRequired(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetIsRandomAccessRequired(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDownloadOperation3_Impl::SetIsRandomAccessRequired(this, value).into() + } + } + unsafe extern "system" fn GetResultRandomAccessStreamReference(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDownloadOperation3_Impl::GetResultRandomAccessStreamReference(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDownloadedRanges(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDownloadOperation3_Impl::GetDownloadedRanges(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RangesDownloaded(this: *mut core::ffi::c_void, eventhandler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDownloadOperation3_Impl::RangesDownloaded(this, core::mem::transmute_copy(&eventhandler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveRangesDownloaded(this: *mut core::ffi::c_void, eventcookie: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDownloadOperation3_Impl::RemoveRangesDownloaded(this, eventcookie).into() + } + } + unsafe extern "system" fn SetRequestedUri(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDownloadOperation3_Impl::SetRequestedUri(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn RecoverableWebErrorStatuses(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDownloadOperation3_Impl::RecoverableWebErrorStatuses(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CurrentWebErrorStatus(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDownloadOperation3_Impl::CurrentWebErrorStatus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsRandomAccessRequired: IsRandomAccessRequired::, + SetIsRandomAccessRequired: SetIsRandomAccessRequired::, + GetResultRandomAccessStreamReference: GetResultRandomAccessStreamReference::, + GetDownloadedRanges: GetDownloadedRanges::, + RangesDownloaded: RangesDownloaded::, + RemoveRangesDownloaded: RemoveRangesDownloaded::, + SetRequestedUri: SetRequestedUri::, + RecoverableWebErrorStatuses: RecoverableWebErrorStatuses::, + CurrentWebErrorStatus: CurrentWebErrorStatus::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IDownloadOperation3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsRandomAccessRequired: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub SetIsRandomAccessRequired: unsafe extern "system" fn(*mut core::ffi::c_void, bool) -> windows_core::HRESULT, + #[cfg(feature = "Storage_Streams")] + pub GetResultRandomAccessStreamReference: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + GetResultRandomAccessStreamReference: usize, + pub GetDownloadedRanges: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub RangesDownloaded: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveRangesDownloaded: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub SetRequestedUri: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Web")] + pub RecoverableWebErrorStatuses: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Web"))] + RecoverableWebErrorStatuses: usize, + #[cfg(feature = "Web")] + pub CurrentWebErrorStatus: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Web"))] + CurrentWebErrorStatus: usize, +} +windows_core::imp::define_interface!(IDownloadOperation4, IDownloadOperation4_Vtbl, 0x0cdaaef4_8cef_404a_966d_f058400bed80); +impl windows_core::RuntimeType for IDownloadOperation4 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IDownloadOperation4 { + const NAME: &'static str = "Windows.Networking.BackgroundTransfer.IDownloadOperation4"; +} +pub trait IDownloadOperation4_Impl: windows_core::IUnknownImpl { + fn MakeCurrentInTransferGroup(&self) -> windows_core::Result<()>; +} +impl IDownloadOperation4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn MakeCurrentInTransferGroup(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDownloadOperation4_Impl::MakeCurrentInTransferGroup(this).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + MakeCurrentInTransferGroup: MakeCurrentInTransferGroup::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IDownloadOperation4_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub MakeCurrentInTransferGroup: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IDownloadOperation5, IDownloadOperation5_Vtbl, 0xa699a86f_5590_463a_b8d6_1e491a2760a5); +impl windows_core::RuntimeType for IDownloadOperation5 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IDownloadOperation5 { + const NAME: &'static str = "Windows.Networking.BackgroundTransfer.IDownloadOperation5"; +} +pub trait IDownloadOperation5_Impl: windows_core::IUnknownImpl { + fn SetRequestHeader(&self, headerName: &windows_core::HSTRING, headerValue: &windows_core::HSTRING) -> windows_core::Result<()>; + fn RemoveRequestHeader(&self, headerName: &windows_core::HSTRING) -> windows_core::Result<()>; +} +impl IDownloadOperation5_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SetRequestHeader(this: *mut core::ffi::c_void, headername: *mut core::ffi::c_void, headervalue: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDownloadOperation5_Impl::SetRequestHeader(this, core::mem::transmute(&headername), core::mem::transmute(&headervalue)).into() + } + } + unsafe extern "system" fn RemoveRequestHeader(this: *mut core::ffi::c_void, headername: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDownloadOperation5_Impl::RemoveRequestHeader(this, core::mem::transmute(&headername)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SetRequestHeader: SetRequestHeader::, + RemoveRequestHeader: RemoveRequestHeader::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IDownloadOperation5_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SetRequestHeader: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub RemoveRequestHeader: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IResponseInformation, IResponseInformation_Vtbl, 0xf8bb9a12_f713_4792_8b68_d9d297f91d2e); +impl windows_core::RuntimeType for IResponseInformation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IResponseInformation { + const NAME: &'static str = "Windows.Networking.BackgroundTransfer.IResponseInformation"; +} +pub trait IResponseInformation_Impl: windows_core::IUnknownImpl { + fn IsResumable(&self) -> windows_core::Result; + fn ActualUri(&self) -> windows_core::Result; + fn StatusCode(&self) -> windows_core::Result; + fn Headers(&self) -> windows_core::Result>; +} +impl IResponseInformation_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsResumable(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IResponseInformation_Impl::IsResumable(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ActualUri(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IResponseInformation_Impl::ActualUri(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StatusCode(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IResponseInformation_Impl::StatusCode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Headers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IResponseInformation_Impl::Headers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsResumable: IsResumable::, + ActualUri: ActualUri::, + StatusCode: StatusCode::, + Headers: Headers::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IResponseInformation_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsResumable: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub ActualUri: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub StatusCode: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Headers: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ResponseInformation(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(ResponseInformation, windows_core::IUnknown, windows_core::IInspectable); +impl ResponseInformation { + pub fn IsResumable(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsResumable)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ActualUri(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ActualUri)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn StatusCode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StatusCode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Headers(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Headers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for ResponseInformation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for ResponseInformation { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for ResponseInformation { + const NAME: &'static str = "Windows.Networking.BackgroundTransfer.ResponseInformation"; +} +unsafe impl Send for ResponseInformation {} +unsafe impl Sync for ResponseInformation {} +} +#[cfg(feature = "Networking_Connectivity")] pub mod Connectivity{ #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] pub struct AttributedNetworkUsage(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(AttributedNetworkUsage, windows_core::IUnknown, windows_core::IInspectable); +impl AttributedNetworkUsage { + pub fn BytesSent(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BytesSent)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn BytesReceived(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BytesReceived)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AttributionId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AttributionId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn AttributionName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AttributionName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn AttributionThumbnail(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AttributionThumbnail)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for AttributedNetworkUsage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -12315,6 +72600,43 @@ unsafe impl Sync for AttributedNetworkUsage {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct ConnectionCost(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(ConnectionCost, windows_core::IUnknown, windows_core::IInspectable); +impl ConnectionCost { + pub fn NetworkCostType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NetworkCostType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Roaming(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Roaming)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn OverDataLimit(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OverDataLimit)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ApproachingDataLimit(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ApproachingDataLimit)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn BackgroundDataUsageRestricted(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BackgroundDataUsageRestricted)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for ConnectionCost { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -12331,6 +72653,171 @@ unsafe impl Sync for ConnectionCost {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct ConnectionProfile(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(ConnectionProfile, windows_core::IUnknown, windows_core::IInspectable); +impl ConnectionProfile { + pub fn ProfileName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProfileName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetNetworkConnectivityLevel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetNetworkConnectivityLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetNetworkNames(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetNetworkNames)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetConnectionCost(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetConnectionCost)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetDataPlanStatus(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDataPlanStatus)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn NetworkAdapter(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NetworkAdapter)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "deprecated")] + pub fn GetLocalUsage(&self, starttime: super::super::Foundation::DateTime, endtime: super::super::Foundation::DateTime) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetLocalUsage)(windows_core::Interface::as_raw(this), starttime, endtime, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "deprecated")] + pub fn GetLocalUsagePerRoamingStates(&self, starttime: super::super::Foundation::DateTime, endtime: super::super::Foundation::DateTime, states: RoamingStates) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetLocalUsagePerRoamingStates)(windows_core::Interface::as_raw(this), starttime, endtime, states, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn NetworkSecuritySettings(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NetworkSecuritySettings)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IsWwanConnectionProfile(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsWwanConnectionProfile)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsWlanConnectionProfile(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsWlanConnectionProfile)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn WwanConnectionProfileDetails(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WwanConnectionProfileDetails)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn WlanConnectionProfileDetails(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WlanConnectionProfileDetails)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ServiceProviderGuid(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ServiceProviderGuid)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetSignalBars(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetSignalBars)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetDomainConnectivityLevel(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDomainConnectivityLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetNetworkUsageAsync(&self, starttime: super::super::Foundation::DateTime, endtime: super::super::Foundation::DateTime, granularity: DataUsageGranularity, states: NetworkUsageStates) -> windows_core::Result>> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetNetworkUsageAsync)(windows_core::Interface::as_raw(this), starttime, endtime, granularity, states, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetConnectivityIntervalsAsync(&self, starttime: super::super::Foundation::DateTime, endtime: super::super::Foundation::DateTime, states: NetworkUsageStates) -> windows_core::Result>> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetConnectivityIntervalsAsync)(windows_core::Interface::as_raw(this), starttime, endtime, states, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetAttributedNetworkUsageAsync(&self, starttime: super::super::Foundation::DateTime, endtime: super::super::Foundation::DateTime, states: NetworkUsageStates) -> windows_core::Result>> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAttributedNetworkUsageAsync)(windows_core::Interface::as_raw(this), starttime, endtime, states, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetProviderNetworkUsageAsync(&self, starttime: super::super::Foundation::DateTime, endtime: super::super::Foundation::DateTime, states: NetworkUsageStates) -> windows_core::Result>> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetProviderNetworkUsageAsync)(windows_core::Interface::as_raw(this), starttime, endtime, states, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CanDelete(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanDelete)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn TryDeleteAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryDeleteAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IsDomainAuthenticatedBy(&self, kind: DomainAuthenticationKind) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsDomainAuthenticatedBy)(windows_core::Interface::as_raw(this), kind, &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for ConnectionProfile { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -12362,6 +72849,22 @@ impl windows_core::RuntimeType for ConnectionProfileDeleteStatus { #[derive(Clone, Debug, Eq, PartialEq)] pub struct ConnectivityInterval(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(ConnectivityInterval, windows_core::IUnknown, windows_core::IInspectable); +impl ConnectivityInterval { + pub fn StartTime(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StartTime)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ConnectionDuration(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ConnectionDuration)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for ConnectivityInterval { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -12378,6 +72881,50 @@ unsafe impl Sync for ConnectivityInterval {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct DataPlanStatus(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(DataPlanStatus, windows_core::IUnknown, windows_core::IInspectable); +impl DataPlanStatus { + pub fn DataPlanUsage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DataPlanUsage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DataLimitInMegabytes(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DataLimitInMegabytes)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn InboundBitsPerSecond(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InboundBitsPerSecond)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn OutboundBitsPerSecond(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OutboundBitsPerSecond)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn NextBillingCycle(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NextBillingCycle)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MaxTransferSizeInMegabytes(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxTransferSizeInMegabytes)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for DataPlanStatus { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -12394,6 +72941,22 @@ unsafe impl Sync for DataPlanStatus {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct DataPlanUsage(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(DataPlanUsage, windows_core::IUnknown, windows_core::IInspectable); +impl DataPlanUsage { + pub fn MegabytesUsed(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MegabytesUsed)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn LastSyncTime(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LastSyncTime)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for DataPlanUsage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -12406,21 +72969,45 @@ impl windows_core::RuntimeName for DataPlanUsage { } unsafe impl Send for DataPlanUsage {} unsafe impl Sync for DataPlanUsage {} +#[cfg(feature = "deprecated")] #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] pub struct DataUsage(windows_core::IUnknown); +#[cfg(feature = "deprecated")] windows_core::imp::interface_hierarchy!(DataUsage, windows_core::IUnknown, windows_core::IInspectable); +#[cfg(feature = "deprecated")] +impl DataUsage { + pub fn BytesSent(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BytesSent)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn BytesReceived(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BytesReceived)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +#[cfg(feature = "deprecated")] impl windows_core::RuntimeType for DataUsage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } +#[cfg(feature = "deprecated")] unsafe impl windows_core::Interface for DataUsage { type Vtable = ::Vtable; const IID: windows_core::GUID = ::IID; } +#[cfg(feature = "deprecated")] impl windows_core::RuntimeName for DataUsage { const NAME: &'static str = "Windows.Networking.Connectivity.DataUsage"; } +#[cfg(feature = "deprecated")] unsafe impl Send for DataUsage {} +#[cfg(feature = "deprecated")] unsafe impl Sync for DataUsage {} #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -12469,6 +73056,97 @@ windows_core::imp::define_interface!(IAttributedNetworkUsage, IAttributedNetwork impl windows_core::RuntimeType for IAttributedNetworkUsage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IAttributedNetworkUsage { + const NAME: &'static str = "Windows.Networking.Connectivity.IAttributedNetworkUsage"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IAttributedNetworkUsage_Impl: windows_core::IUnknownImpl { + fn BytesSent(&self) -> windows_core::Result; + fn BytesReceived(&self) -> windows_core::Result; + fn AttributionId(&self) -> windows_core::Result; + fn AttributionName(&self) -> windows_core::Result; + fn AttributionThumbnail(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IAttributedNetworkUsage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn BytesSent(this: *mut core::ffi::c_void, result__: *mut u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAttributedNetworkUsage_Impl::BytesSent(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn BytesReceived(this: *mut core::ffi::c_void, result__: *mut u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAttributedNetworkUsage_Impl::BytesReceived(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AttributionId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAttributedNetworkUsage_Impl::AttributionId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AttributionName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAttributedNetworkUsage_Impl::AttributionName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AttributionThumbnail(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IAttributedNetworkUsage_Impl::AttributionThumbnail(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + BytesSent: BytesSent::, + BytesReceived: BytesReceived::, + AttributionId: AttributionId::, + AttributionName: AttributionName::, + AttributionThumbnail: AttributionThumbnail::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IAttributedNetworkUsage_Vtbl { @@ -12486,6 +73164,77 @@ windows_core::imp::define_interface!(IConnectionCost, IConnectionCost_Vtbl, 0xba impl windows_core::RuntimeType for IConnectionCost { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IConnectionCost { + const NAME: &'static str = "Windows.Networking.Connectivity.IConnectionCost"; +} +pub trait IConnectionCost_Impl: windows_core::IUnknownImpl { + fn NetworkCostType(&self) -> windows_core::Result; + fn Roaming(&self) -> windows_core::Result; + fn OverDataLimit(&self) -> windows_core::Result; + fn ApproachingDataLimit(&self) -> windows_core::Result; +} +impl IConnectionCost_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn NetworkCostType(this: *mut core::ffi::c_void, result__: *mut NetworkCostType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionCost_Impl::NetworkCostType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Roaming(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionCost_Impl::Roaming(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OverDataLimit(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionCost_Impl::OverDataLimit(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ApproachingDataLimit(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionCost_Impl::ApproachingDataLimit(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + NetworkCostType: NetworkCostType::, + Roaming: Roaming::, + OverDataLimit: OverDataLimit::, + ApproachingDataLimit: ApproachingDataLimit::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IConnectionCost_Vtbl { @@ -12499,6 +73248,35 @@ windows_core::imp::define_interface!(IConnectionCost2, IConnectionCost2_Vtbl, 0x impl windows_core::RuntimeType for IConnectionCost2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IConnectionCost2 { + const NAME: &'static str = "Windows.Networking.Connectivity.IConnectionCost2"; +} +pub trait IConnectionCost2_Impl: windows_core::IUnknownImpl { + fn BackgroundDataUsageRestricted(&self) -> windows_core::Result; +} +impl IConnectionCost2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn BackgroundDataUsageRestricted(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionCost2_Impl::BackgroundDataUsageRestricted(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + BackgroundDataUsageRestricted: BackgroundDataUsageRestricted::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IConnectionCost2_Vtbl { @@ -12509,6 +73287,155 @@ windows_core::imp::define_interface!(IConnectionProfile, IConnectionProfile_Vtbl impl windows_core::RuntimeType for IConnectionProfile { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IConnectionProfile { + const NAME: &'static str = "Windows.Networking.Connectivity.IConnectionProfile"; +} +pub trait IConnectionProfile_Impl: windows_core::IUnknownImpl { + fn ProfileName(&self) -> windows_core::Result; + fn GetNetworkConnectivityLevel(&self) -> windows_core::Result; + fn GetNetworkNames(&self) -> windows_core::Result>; + fn GetConnectionCost(&self) -> windows_core::Result; + fn GetDataPlanStatus(&self) -> windows_core::Result; + fn NetworkAdapter(&self) -> windows_core::Result; + fn GetLocalUsage(&self, StartTime: &super::super::Foundation::DateTime, EndTime: &super::super::Foundation::DateTime) -> windows_core::Result; + fn GetLocalUsagePerRoamingStates(&self, StartTime: &super::super::Foundation::DateTime, EndTime: &super::super::Foundation::DateTime, States: RoamingStates) -> windows_core::Result; + fn NetworkSecuritySettings(&self) -> windows_core::Result; +} +impl IConnectionProfile_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ProfileName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile_Impl::ProfileName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetNetworkConnectivityLevel(this: *mut core::ffi::c_void, result__: *mut NetworkConnectivityLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile_Impl::GetNetworkConnectivityLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetNetworkNames(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile_Impl::GetNetworkNames(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetConnectionCost(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile_Impl::GetConnectionCost(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDataPlanStatus(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile_Impl::GetDataPlanStatus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NetworkAdapter(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile_Impl::NetworkAdapter(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetLocalUsage(this: *mut core::ffi::c_void, starttime: super::super::Foundation::DateTime, endtime: super::super::Foundation::DateTime, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile_Impl::GetLocalUsage(this, core::mem::transmute(&starttime), core::mem::transmute(&endtime)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetLocalUsagePerRoamingStates(this: *mut core::ffi::c_void, starttime: super::super::Foundation::DateTime, endtime: super::super::Foundation::DateTime, states: RoamingStates, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile_Impl::GetLocalUsagePerRoamingStates(this, core::mem::transmute(&starttime), core::mem::transmute(&endtime), states) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NetworkSecuritySettings(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile_Impl::NetworkSecuritySettings(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ProfileName: ProfileName::, + GetNetworkConnectivityLevel: GetNetworkConnectivityLevel::, + GetNetworkNames: GetNetworkNames::, + GetConnectionCost: GetConnectionCost::, + GetDataPlanStatus: GetDataPlanStatus::, + NetworkAdapter: NetworkAdapter::, + GetLocalUsage: GetLocalUsage::, + GetLocalUsagePerRoamingStates: GetLocalUsagePerRoamingStates::, + NetworkSecuritySettings: NetworkSecuritySettings::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IConnectionProfile_Vtbl { @@ -12519,14 +73446,167 @@ pub struct IConnectionProfile_Vtbl { pub GetConnectionCost: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, pub GetDataPlanStatus: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, pub NetworkAdapter: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "deprecated")] pub GetLocalUsage: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::DateTime, super::super::Foundation::DateTime, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + GetLocalUsage: usize, + #[cfg(feature = "deprecated")] pub GetLocalUsagePerRoamingStates: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::DateTime, super::super::Foundation::DateTime, RoamingStates, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + GetLocalUsagePerRoamingStates: usize, pub NetworkSecuritySettings: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, } windows_core::imp::define_interface!(IConnectionProfile2, IConnectionProfile2_Vtbl, 0xe2045145_4c9f_400c_9150_7ec7d6e2888a); impl windows_core::RuntimeType for IConnectionProfile2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IConnectionProfile2 { + const NAME: &'static str = "Windows.Networking.Connectivity.IConnectionProfile2"; +} +pub trait IConnectionProfile2_Impl: windows_core::IUnknownImpl { + fn IsWwanConnectionProfile(&self) -> windows_core::Result; + fn IsWlanConnectionProfile(&self) -> windows_core::Result; + fn WwanConnectionProfileDetails(&self) -> windows_core::Result; + fn WlanConnectionProfileDetails(&self) -> windows_core::Result; + fn ServiceProviderGuid(&self) -> windows_core::Result>; + fn GetSignalBars(&self) -> windows_core::Result>; + fn GetDomainConnectivityLevel(&self) -> windows_core::Result; + fn GetNetworkUsageAsync(&self, startTime: &super::super::Foundation::DateTime, endTime: &super::super::Foundation::DateTime, granularity: DataUsageGranularity, states: &NetworkUsageStates) -> windows_core::Result>>; + fn GetConnectivityIntervalsAsync(&self, startTime: &super::super::Foundation::DateTime, endTime: &super::super::Foundation::DateTime, states: &NetworkUsageStates) -> windows_core::Result>>; +} +impl IConnectionProfile2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsWwanConnectionProfile(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile2_Impl::IsWwanConnectionProfile(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsWlanConnectionProfile(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile2_Impl::IsWlanConnectionProfile(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WwanConnectionProfileDetails(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile2_Impl::WwanConnectionProfileDetails(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WlanConnectionProfileDetails(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile2_Impl::WlanConnectionProfileDetails(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ServiceProviderGuid(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile2_Impl::ServiceProviderGuid(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetSignalBars(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile2_Impl::GetSignalBars(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDomainConnectivityLevel(this: *mut core::ffi::c_void, result__: *mut DomainConnectivityLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile2_Impl::GetDomainConnectivityLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetNetworkUsageAsync(this: *mut core::ffi::c_void, starttime: super::super::Foundation::DateTime, endtime: super::super::Foundation::DateTime, granularity: DataUsageGranularity, states: NetworkUsageStates, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile2_Impl::GetNetworkUsageAsync(this, core::mem::transmute(&starttime), core::mem::transmute(&endtime), granularity, core::mem::transmute(&states)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetConnectivityIntervalsAsync(this: *mut core::ffi::c_void, starttime: super::super::Foundation::DateTime, endtime: super::super::Foundation::DateTime, states: NetworkUsageStates, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile2_Impl::GetConnectivityIntervalsAsync(this, core::mem::transmute(&starttime), core::mem::transmute(&endtime), core::mem::transmute(&states)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsWwanConnectionProfile: IsWwanConnectionProfile::, + IsWlanConnectionProfile: IsWlanConnectionProfile::, + WwanConnectionProfileDetails: WwanConnectionProfileDetails::, + WlanConnectionProfileDetails: WlanConnectionProfileDetails::, + ServiceProviderGuid: ServiceProviderGuid::, + GetSignalBars: GetSignalBars::, + GetDomainConnectivityLevel: GetDomainConnectivityLevel::, + GetNetworkUsageAsync: GetNetworkUsageAsync::, + GetConnectivityIntervalsAsync: GetConnectivityIntervalsAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IConnectionProfile2_Vtbl { @@ -12545,6 +73625,36 @@ windows_core::imp::define_interface!(IConnectionProfile3, IConnectionProfile3_Vt impl windows_core::RuntimeType for IConnectionProfile3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IConnectionProfile3 { + const NAME: &'static str = "Windows.Networking.Connectivity.IConnectionProfile3"; +} +pub trait IConnectionProfile3_Impl: windows_core::IUnknownImpl { + fn GetAttributedNetworkUsageAsync(&self, startTime: &super::super::Foundation::DateTime, endTime: &super::super::Foundation::DateTime, states: &NetworkUsageStates) -> windows_core::Result>>; +} +impl IConnectionProfile3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetAttributedNetworkUsageAsync(this: *mut core::ffi::c_void, starttime: super::super::Foundation::DateTime, endtime: super::super::Foundation::DateTime, states: NetworkUsageStates, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile3_Impl::GetAttributedNetworkUsageAsync(this, core::mem::transmute(&starttime), core::mem::transmute(&endtime), core::mem::transmute(&states)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetAttributedNetworkUsageAsync: GetAttributedNetworkUsageAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IConnectionProfile3_Vtbl { @@ -12555,6 +73665,36 @@ windows_core::imp::define_interface!(IConnectionProfile4, IConnectionProfile4_Vt impl windows_core::RuntimeType for IConnectionProfile4 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IConnectionProfile4 { + const NAME: &'static str = "Windows.Networking.Connectivity.IConnectionProfile4"; +} +pub trait IConnectionProfile4_Impl: windows_core::IUnknownImpl { + fn GetProviderNetworkUsageAsync(&self, startTime: &super::super::Foundation::DateTime, endTime: &super::super::Foundation::DateTime, states: &NetworkUsageStates) -> windows_core::Result>>; +} +impl IConnectionProfile4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetProviderNetworkUsageAsync(this: *mut core::ffi::c_void, starttime: super::super::Foundation::DateTime, endtime: super::super::Foundation::DateTime, states: NetworkUsageStates, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile4_Impl::GetProviderNetworkUsageAsync(this, core::mem::transmute(&starttime), core::mem::transmute(&endtime), core::mem::transmute(&states)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetProviderNetworkUsageAsync: GetProviderNetworkUsageAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IConnectionProfile4_Vtbl { @@ -12565,6 +73705,50 @@ windows_core::imp::define_interface!(IConnectionProfile5, IConnectionProfile5_Vt impl windows_core::RuntimeType for IConnectionProfile5 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IConnectionProfile5 { + const NAME: &'static str = "Windows.Networking.Connectivity.IConnectionProfile5"; +} +pub trait IConnectionProfile5_Impl: windows_core::IUnknownImpl { + fn CanDelete(&self) -> windows_core::Result; + fn TryDeleteAsync(&self) -> windows_core::Result>; +} +impl IConnectionProfile5_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CanDelete(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile5_Impl::CanDelete(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryDeleteAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile5_Impl::TryDeleteAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CanDelete: CanDelete::, + TryDeleteAsync: TryDeleteAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IConnectionProfile5_Vtbl { @@ -12576,6 +73760,35 @@ windows_core::imp::define_interface!(IConnectionProfile6, IConnectionProfile6_Vt impl windows_core::RuntimeType for IConnectionProfile6 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IConnectionProfile6 { + const NAME: &'static str = "Windows.Networking.Connectivity.IConnectionProfile6"; +} +pub trait IConnectionProfile6_Impl: windows_core::IUnknownImpl { + fn IsDomainAuthenticatedBy(&self, kind: DomainAuthenticationKind) -> windows_core::Result; +} +impl IConnectionProfile6_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsDomainAuthenticatedBy(this: *mut core::ffi::c_void, kind: DomainAuthenticationKind, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectionProfile6_Impl::IsDomainAuthenticatedBy(this, kind) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsDomainAuthenticatedBy: IsDomainAuthenticatedBy::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IConnectionProfile6_Vtbl { @@ -12586,6 +73799,49 @@ windows_core::imp::define_interface!(IConnectivityInterval, IConnectivityInterva impl windows_core::RuntimeType for IConnectivityInterval { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IConnectivityInterval { + const NAME: &'static str = "Windows.Networking.Connectivity.IConnectivityInterval"; +} +pub trait IConnectivityInterval_Impl: windows_core::IUnknownImpl { + fn StartTime(&self) -> windows_core::Result; + fn ConnectionDuration(&self) -> windows_core::Result; +} +impl IConnectivityInterval_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn StartTime(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectivityInterval_Impl::StartTime(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ConnectionDuration(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IConnectivityInterval_Impl::ConnectionDuration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + StartTime: StartTime::, + ConnectionDuration: ConnectionDuration::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IConnectivityInterval_Vtbl { @@ -12597,6 +73853,111 @@ windows_core::imp::define_interface!(IDataPlanStatus, IDataPlanStatus_Vtbl, 0x97 impl windows_core::RuntimeType for IDataPlanStatus { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDataPlanStatus { + const NAME: &'static str = "Windows.Networking.Connectivity.IDataPlanStatus"; +} +pub trait IDataPlanStatus_Impl: windows_core::IUnknownImpl { + fn DataPlanUsage(&self) -> windows_core::Result; + fn DataLimitInMegabytes(&self) -> windows_core::Result>; + fn InboundBitsPerSecond(&self) -> windows_core::Result>; + fn OutboundBitsPerSecond(&self) -> windows_core::Result>; + fn NextBillingCycle(&self) -> windows_core::Result>; + fn MaxTransferSizeInMegabytes(&self) -> windows_core::Result>; +} +impl IDataPlanStatus_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DataPlanUsage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDataPlanStatus_Impl::DataPlanUsage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DataLimitInMegabytes(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDataPlanStatus_Impl::DataLimitInMegabytes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn InboundBitsPerSecond(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDataPlanStatus_Impl::InboundBitsPerSecond(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OutboundBitsPerSecond(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDataPlanStatus_Impl::OutboundBitsPerSecond(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NextBillingCycle(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDataPlanStatus_Impl::NextBillingCycle(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MaxTransferSizeInMegabytes(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDataPlanStatus_Impl::MaxTransferSizeInMegabytes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DataPlanUsage: DataPlanUsage::, + DataLimitInMegabytes: DataLimitInMegabytes::, + InboundBitsPerSecond: InboundBitsPerSecond::, + OutboundBitsPerSecond: OutboundBitsPerSecond::, + NextBillingCycle: NextBillingCycle::, + MaxTransferSizeInMegabytes: MaxTransferSizeInMegabytes::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDataPlanStatus_Vtbl { @@ -12612,6 +73973,49 @@ windows_core::imp::define_interface!(IDataPlanUsage, IDataPlanUsage_Vtbl, 0xb921 impl windows_core::RuntimeType for IDataPlanUsage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDataPlanUsage { + const NAME: &'static str = "Windows.Networking.Connectivity.IDataPlanUsage"; +} +pub trait IDataPlanUsage_Impl: windows_core::IUnknownImpl { + fn MegabytesUsed(&self) -> windows_core::Result; + fn LastSyncTime(&self) -> windows_core::Result; +} +impl IDataPlanUsage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn MegabytesUsed(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDataPlanUsage_Impl::MegabytesUsed(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn LastSyncTime(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDataPlanUsage_Impl::LastSyncTime(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + MegabytesUsed: MegabytesUsed::, + LastSyncTime: LastSyncTime::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDataPlanUsage_Vtbl { @@ -12619,10 +74023,59 @@ pub struct IDataPlanUsage_Vtbl { pub MegabytesUsed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, pub LastSyncTime: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::DateTime) -> windows_core::HRESULT, } +#[cfg(feature = "deprecated")] windows_core::imp::define_interface!(IDataUsage, IDataUsage_Vtbl, 0xc1431dd3_b146_4d39_b959_0c69b096c512); +#[cfg(feature = "deprecated")] impl windows_core::RuntimeType for IDataUsage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "deprecated")] +impl windows_core::RuntimeName for IDataUsage { + const NAME: &'static str = "Windows.Networking.Connectivity.IDataUsage"; +} +#[cfg(feature = "deprecated")] +pub trait IDataUsage_Impl: windows_core::IUnknownImpl { + fn BytesSent(&self) -> windows_core::Result; + fn BytesReceived(&self) -> windows_core::Result; +} +#[cfg(feature = "deprecated")] +impl IDataUsage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn BytesSent(this: *mut core::ffi::c_void, result__: *mut u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDataUsage_Impl::BytesSent(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn BytesReceived(this: *mut core::ffi::c_void, result__: *mut u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDataUsage_Impl::BytesReceived(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + BytesSent: BytesSent::, + BytesReceived: BytesReceived::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[cfg(feature = "deprecated")] #[repr(C)] #[doc(hidden)] pub struct IDataUsage_Vtbl { @@ -12630,10 +74083,167 @@ pub struct IDataUsage_Vtbl { pub BytesSent: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u64) -> windows_core::HRESULT, pub BytesReceived: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u64) -> windows_core::HRESULT, } +windows_core::imp::define_interface!(IIPInformation, IIPInformation_Vtbl, 0xd85145e0_138f_47d7_9b3a_36bb488cef33); +impl windows_core::RuntimeType for IIPInformation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IIPInformation { + const NAME: &'static str = "Windows.Networking.Connectivity.IIPInformation"; +} +pub trait IIPInformation_Impl: windows_core::IUnknownImpl { + fn NetworkAdapter(&self) -> windows_core::Result; + fn PrefixLength(&self) -> windows_core::Result>; +} +impl IIPInformation_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn NetworkAdapter(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIPInformation_Impl::NetworkAdapter(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PrefixLength(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IIPInformation_Impl::PrefixLength(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + NetworkAdapter: NetworkAdapter::, + PrefixLength: PrefixLength::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IIPInformation_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub NetworkAdapter: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub PrefixLength: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} windows_core::imp::define_interface!(INetworkAdapter, INetworkAdapter_Vtbl, 0x3b542e03_5388_496c_a8a3_affd39aec2e6); impl windows_core::RuntimeType for INetworkAdapter { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for INetworkAdapter { + const NAME: &'static str = "Windows.Networking.Connectivity.INetworkAdapter"; +} +pub trait INetworkAdapter_Impl: windows_core::IUnknownImpl { + fn OutboundMaxBitsPerSecond(&self) -> windows_core::Result; + fn InboundMaxBitsPerSecond(&self) -> windows_core::Result; + fn IanaInterfaceType(&self) -> windows_core::Result; + fn NetworkItem(&self) -> windows_core::Result; + fn NetworkAdapterId(&self) -> windows_core::Result; + fn GetConnectedProfileAsync(&self) -> windows_core::Result>; +} +impl INetworkAdapter_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn OutboundMaxBitsPerSecond(this: *mut core::ffi::c_void, result__: *mut u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match INetworkAdapter_Impl::OutboundMaxBitsPerSecond(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn InboundMaxBitsPerSecond(this: *mut core::ffi::c_void, result__: *mut u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match INetworkAdapter_Impl::InboundMaxBitsPerSecond(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IanaInterfaceType(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match INetworkAdapter_Impl::IanaInterfaceType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NetworkItem(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match INetworkAdapter_Impl::NetworkItem(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NetworkAdapterId(this: *mut core::ffi::c_void, result__: *mut windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match INetworkAdapter_Impl::NetworkAdapterId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetConnectedProfileAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match INetworkAdapter_Impl::GetConnectedProfileAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + OutboundMaxBitsPerSecond: OutboundMaxBitsPerSecond::, + InboundMaxBitsPerSecond: InboundMaxBitsPerSecond::, + IanaInterfaceType: IanaInterfaceType::, + NetworkItem: NetworkItem::, + NetworkAdapterId: NetworkAdapterId::, + GetConnectedProfileAsync: GetConnectedProfileAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct INetworkAdapter_Vtbl { @@ -12649,6 +74259,49 @@ windows_core::imp::define_interface!(INetworkItem, INetworkItem_Vtbl, 0x01bc4d39 impl windows_core::RuntimeType for INetworkItem { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for INetworkItem { + const NAME: &'static str = "Windows.Networking.Connectivity.INetworkItem"; +} +pub trait INetworkItem_Impl: windows_core::IUnknownImpl { + fn NetworkId(&self) -> windows_core::Result; + fn GetNetworkTypes(&self) -> windows_core::Result; +} +impl INetworkItem_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn NetworkId(this: *mut core::ffi::c_void, result__: *mut windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match INetworkItem_Impl::NetworkId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetNetworkTypes(this: *mut core::ffi::c_void, result__: *mut NetworkTypes) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match INetworkItem_Impl::GetNetworkTypes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + NetworkId: NetworkId::, + GetNetworkTypes: GetNetworkTypes::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct INetworkItem_Vtbl { @@ -12660,6 +74313,49 @@ windows_core::imp::define_interface!(INetworkSecuritySettings, INetworkSecurityS impl windows_core::RuntimeType for INetworkSecuritySettings { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for INetworkSecuritySettings { + const NAME: &'static str = "Windows.Networking.Connectivity.INetworkSecuritySettings"; +} +pub trait INetworkSecuritySettings_Impl: windows_core::IUnknownImpl { + fn NetworkAuthenticationType(&self) -> windows_core::Result; + fn NetworkEncryptionType(&self) -> windows_core::Result; +} +impl INetworkSecuritySettings_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn NetworkAuthenticationType(this: *mut core::ffi::c_void, result__: *mut NetworkAuthenticationType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match INetworkSecuritySettings_Impl::NetworkAuthenticationType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NetworkEncryptionType(this: *mut core::ffi::c_void, result__: *mut NetworkEncryptionType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match INetworkSecuritySettings_Impl::NetworkEncryptionType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + NetworkAuthenticationType: NetworkAuthenticationType::, + NetworkEncryptionType: NetworkEncryptionType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct INetworkSecuritySettings_Vtbl { @@ -12671,6 +74367,63 @@ windows_core::imp::define_interface!(INetworkUsage, INetworkUsage_Vtbl, 0x49da8f impl windows_core::RuntimeType for INetworkUsage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for INetworkUsage { + const NAME: &'static str = "Windows.Networking.Connectivity.INetworkUsage"; +} +pub trait INetworkUsage_Impl: windows_core::IUnknownImpl { + fn BytesSent(&self) -> windows_core::Result; + fn BytesReceived(&self) -> windows_core::Result; + fn ConnectionDuration(&self) -> windows_core::Result; +} +impl INetworkUsage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn BytesSent(this: *mut core::ffi::c_void, result__: *mut u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match INetworkUsage_Impl::BytesSent(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn BytesReceived(this: *mut core::ffi::c_void, result__: *mut u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match INetworkUsage_Impl::BytesReceived(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ConnectionDuration(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match INetworkUsage_Impl::ConnectionDuration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + BytesSent: BytesSent::, + BytesReceived: BytesReceived::, + ConnectionDuration: ConnectionDuration::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct INetworkUsage_Vtbl { @@ -12679,10 +74432,100 @@ pub struct INetworkUsage_Vtbl { pub BytesReceived: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u64) -> windows_core::HRESULT, pub ConnectionDuration: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, } +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct IPInformation(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(IPInformation, windows_core::IUnknown, windows_core::IInspectable); +impl IPInformation { + pub fn NetworkAdapter(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NetworkAdapter)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PrefixLength(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PrefixLength)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for IPInformation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for IPInformation { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for IPInformation { + const NAME: &'static str = "Windows.Networking.Connectivity.IPInformation"; +} +unsafe impl Send for IPInformation {} +unsafe impl Sync for IPInformation {} windows_core::imp::define_interface!(IProviderNetworkUsage, IProviderNetworkUsage_Vtbl, 0x5ec69e04_7931_48c8_b8f3_46300fa42728); impl windows_core::RuntimeType for IProviderNetworkUsage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IProviderNetworkUsage { + const NAME: &'static str = "Windows.Networking.Connectivity.IProviderNetworkUsage"; +} +pub trait IProviderNetworkUsage_Impl: windows_core::IUnknownImpl { + fn BytesSent(&self) -> windows_core::Result; + fn BytesReceived(&self) -> windows_core::Result; + fn ProviderId(&self) -> windows_core::Result; +} +impl IProviderNetworkUsage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn BytesSent(this: *mut core::ffi::c_void, result__: *mut u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProviderNetworkUsage_Impl::BytesSent(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn BytesReceived(this: *mut core::ffi::c_void, result__: *mut u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProviderNetworkUsage_Impl::BytesReceived(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ProviderId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IProviderNetworkUsage_Impl::ProviderId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + BytesSent: BytesSent::, + BytesReceived: BytesReceived::, + ProviderId: ProviderId::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IProviderNetworkUsage_Vtbl { @@ -12695,6 +74538,36 @@ windows_core::imp::define_interface!(IWlanConnectionProfileDetails, IWlanConnect impl windows_core::RuntimeType for IWlanConnectionProfileDetails { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IWlanConnectionProfileDetails { + const NAME: &'static str = "Windows.Networking.Connectivity.IWlanConnectionProfileDetails"; +} +pub trait IWlanConnectionProfileDetails_Impl: windows_core::IUnknownImpl { + fn GetConnectedSsid(&self) -> windows_core::Result; +} +impl IWlanConnectionProfileDetails_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetConnectedSsid(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWlanConnectionProfileDetails_Impl::GetConnectedSsid(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetConnectedSsid: GetConnectedSsid::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IWlanConnectionProfileDetails_Vtbl { @@ -12705,6 +74578,79 @@ windows_core::imp::define_interface!(IWwanConnectionProfileDetails, IWwanConnect impl windows_core::RuntimeType for IWwanConnectionProfileDetails { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IWwanConnectionProfileDetails { + const NAME: &'static str = "Windows.Networking.Connectivity.IWwanConnectionProfileDetails"; +} +pub trait IWwanConnectionProfileDetails_Impl: windows_core::IUnknownImpl { + fn HomeProviderId(&self) -> windows_core::Result; + fn AccessPointName(&self) -> windows_core::Result; + fn GetNetworkRegistrationState(&self) -> windows_core::Result; + fn GetCurrentDataClass(&self) -> windows_core::Result; +} +impl IWwanConnectionProfileDetails_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn HomeProviderId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWwanConnectionProfileDetails_Impl::HomeProviderId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AccessPointName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWwanConnectionProfileDetails_Impl::AccessPointName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetNetworkRegistrationState(this: *mut core::ffi::c_void, result__: *mut WwanNetworkRegistrationState) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWwanConnectionProfileDetails_Impl::GetNetworkRegistrationState(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetCurrentDataClass(this: *mut core::ffi::c_void, result__: *mut WwanDataClass) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWwanConnectionProfileDetails_Impl::GetCurrentDataClass(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + HomeProviderId: HomeProviderId::, + AccessPointName: AccessPointName::, + GetNetworkRegistrationState: GetNetworkRegistrationState::, + GetCurrentDataClass: GetCurrentDataClass::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IWwanConnectionProfileDetails_Vtbl { @@ -12718,6 +74664,50 @@ windows_core::imp::define_interface!(IWwanConnectionProfileDetails2, IWwanConnec impl windows_core::RuntimeType for IWwanConnectionProfileDetails2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IWwanConnectionProfileDetails2 { + const NAME: &'static str = "Windows.Networking.Connectivity.IWwanConnectionProfileDetails2"; +} +pub trait IWwanConnectionProfileDetails2_Impl: windows_core::IUnknownImpl { + fn IPKind(&self) -> windows_core::Result; + fn PurposeGuids(&self) -> windows_core::Result>; +} +impl IWwanConnectionProfileDetails2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IPKind(this: *mut core::ffi::c_void, result__: *mut WwanNetworkIPKind) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWwanConnectionProfileDetails2_Impl::IPKind(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PurposeGuids(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWwanConnectionProfileDetails2_Impl::PurposeGuids(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IPKind: IPKind::, + PurposeGuids: PurposeGuids::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IWwanConnectionProfileDetails2_Vtbl { @@ -12729,6 +74719,50 @@ pub struct IWwanConnectionProfileDetails2_Vtbl { #[derive(Clone, Debug, Eq, PartialEq)] pub struct NetworkAdapter(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(NetworkAdapter, windows_core::IUnknown, windows_core::IInspectable); +impl NetworkAdapter { + pub fn OutboundMaxBitsPerSecond(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OutboundMaxBitsPerSecond)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn InboundMaxBitsPerSecond(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InboundMaxBitsPerSecond)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IanaInterfaceType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IanaInterfaceType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn NetworkItem(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NetworkItem)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn NetworkAdapterId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NetworkAdapterId)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetConnectedProfileAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetConnectedProfileAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for NetworkAdapter { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -12824,6 +74858,22 @@ impl windows_core::RuntimeType for NetworkEncryptionType { #[derive(Clone, Debug, Eq, PartialEq)] pub struct NetworkItem(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(NetworkItem, windows_core::IUnknown, windows_core::IInspectable); +impl NetworkItem { + pub fn NetworkId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NetworkId)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetNetworkTypes(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetNetworkTypes)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for NetworkItem { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -12840,6 +74890,22 @@ unsafe impl Sync for NetworkItem {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct NetworkSecuritySettings(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(NetworkSecuritySettings, windows_core::IUnknown, windows_core::IInspectable); +impl NetworkSecuritySettings { + pub fn NetworkAuthenticationType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NetworkAuthenticationType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn NetworkEncryptionType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NetworkEncryptionType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for NetworkSecuritySettings { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -12903,6 +74969,29 @@ impl core::ops::Not for NetworkTypes { #[derive(Clone, Debug, Eq, PartialEq)] pub struct NetworkUsage(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(NetworkUsage, windows_core::IUnknown, windows_core::IInspectable); +impl NetworkUsage { + pub fn BytesSent(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BytesSent)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn BytesReceived(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BytesReceived)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ConnectionDuration(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ConnectionDuration)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for NetworkUsage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -12931,6 +75020,29 @@ impl windows_core::RuntimeType for NetworkUsageStates { #[derive(Clone, Debug, Eq, PartialEq)] pub struct ProviderNetworkUsage(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(ProviderNetworkUsage, windows_core::IUnknown, windows_core::IInspectable); +impl ProviderNetworkUsage { + pub fn BytesSent(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BytesSent)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn BytesReceived(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BytesReceived)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ProviderId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProviderId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} impl windows_core::RuntimeType for ProviderNetworkUsage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -13008,6 +75120,15 @@ impl windows_core::RuntimeType for TriStates { #[derive(Clone, Debug, Eq, PartialEq)] pub struct WlanConnectionProfileDetails(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(WlanConnectionProfileDetails, windows_core::IUnknown, windows_core::IInspectable); +impl WlanConnectionProfileDetails { + pub fn GetConnectedSsid(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetConnectedSsid)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} impl windows_core::RuntimeType for WlanConnectionProfileDetails { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -13024,6 +75145,50 @@ unsafe impl Sync for WlanConnectionProfileDetails {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct WwanConnectionProfileDetails(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(WwanConnectionProfileDetails, windows_core::IUnknown, windows_core::IInspectable); +impl WwanConnectionProfileDetails { + pub fn HomeProviderId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HomeProviderId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn AccessPointName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AccessPointName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetNetworkRegistrationState(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetNetworkRegistrationState)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetCurrentDataClass(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentDataClass)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IPKind(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IPKind)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PurposeGuids(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PurposeGuids)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for WwanConnectionProfileDetails { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -13132,6 +75297,7 @@ impl windows_core::RuntimeType for WwanNetworkRegistrationState { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Networking.Connectivity.WwanNetworkRegistrationState;i4)"); } } +#[cfg(feature = "Networking_Sockets")] pub mod Sockets{ #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq)] @@ -13153,6 +75319,36 @@ windows_core::imp::define_interface!(ISocketActivityContext, ISocketActivityCont impl windows_core::RuntimeType for ISocketActivityContext { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for ISocketActivityContext { + const NAME: &'static str = "Windows.Networking.Sockets.ISocketActivityContext"; +} +#[cfg(feature = "Storage_Streams")] +pub trait ISocketActivityContext_Impl: windows_core::IUnknownImpl { + fn Data(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl ISocketActivityContext_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Data(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISocketActivityContext_Impl::Data(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Data: Data:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISocketActivityContext_Vtbl { @@ -13166,6 +75362,36 @@ windows_core::imp::define_interface!(ISocketActivityContextFactory, ISocketActiv impl windows_core::RuntimeType for ISocketActivityContextFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for ISocketActivityContextFactory { + const NAME: &'static str = "Windows.Networking.Sockets.ISocketActivityContextFactory"; +} +#[cfg(feature = "Storage_Streams")] +pub trait ISocketActivityContextFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, data: windows_core::Ref<'_, super::super::Storage::Streams::IBuffer>) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl ISocketActivityContextFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, data: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISocketActivityContextFactory_Impl::Create(this, core::mem::transmute_copy(&data)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISocketActivityContextFactory_Vtbl { @@ -13179,6 +75405,159 @@ windows_core::imp::define_interface!(IStreamSocket, IStreamSocket_Vtbl, 0x69a22c impl windows_core::RuntimeType for IStreamSocket { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IStreamSocket { + const NAME: &'static str = "Windows.Networking.Sockets.IStreamSocket"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IStreamSocket_Impl: super::super::Foundation::IClosable_Impl { + fn Control(&self) -> windows_core::Result; + fn Information(&self) -> windows_core::Result; + fn InputStream(&self) -> windows_core::Result; + fn OutputStream(&self) -> windows_core::Result; + fn ConnectWithEndpointPairAsync(&self, endpointPair: windows_core::Ref<'_, super::EndpointPair>) -> windows_core::Result; + fn ConnectAsync(&self, remoteHostName: windows_core::Ref<'_, super::HostName>, remoteServiceName: &windows_core::HSTRING) -> windows_core::Result; + fn ConnectWithEndpointPairAndProtectionLevelAsync(&self, endpointPair: windows_core::Ref<'_, super::EndpointPair>, protectionLevel: SocketProtectionLevel) -> windows_core::Result; + fn ConnectWithProtectionLevelAsync(&self, remoteHostName: windows_core::Ref<'_, super::HostName>, remoteServiceName: &windows_core::HSTRING, protectionLevel: SocketProtectionLevel) -> windows_core::Result; + fn UpgradeToSslAsync(&self, protectionLevel: SocketProtectionLevel, validationHostName: windows_core::Ref<'_, super::HostName>) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IStreamSocket_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Control(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocket_Impl::Control(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Information(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocket_Impl::Information(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn InputStream(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocket_Impl::InputStream(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OutputStream(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocket_Impl::OutputStream(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ConnectWithEndpointPairAsync(this: *mut core::ffi::c_void, endpointpair: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocket_Impl::ConnectWithEndpointPairAsync(this, core::mem::transmute_copy(&endpointpair)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ConnectAsync(this: *mut core::ffi::c_void, remotehostname: *mut core::ffi::c_void, remoteservicename: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocket_Impl::ConnectAsync(this, core::mem::transmute_copy(&remotehostname), core::mem::transmute(&remoteservicename)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ConnectWithEndpointPairAndProtectionLevelAsync(this: *mut core::ffi::c_void, endpointpair: *mut core::ffi::c_void, protectionlevel: SocketProtectionLevel, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocket_Impl::ConnectWithEndpointPairAndProtectionLevelAsync(this, core::mem::transmute_copy(&endpointpair), protectionlevel) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ConnectWithProtectionLevelAsync(this: *mut core::ffi::c_void, remotehostname: *mut core::ffi::c_void, remoteservicename: *mut core::ffi::c_void, protectionlevel: SocketProtectionLevel, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocket_Impl::ConnectWithProtectionLevelAsync(this, core::mem::transmute_copy(&remotehostname), core::mem::transmute(&remoteservicename), protectionlevel) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn UpgradeToSslAsync(this: *mut core::ffi::c_void, protectionlevel: SocketProtectionLevel, validationhostname: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocket_Impl::UpgradeToSslAsync(this, protectionlevel, core::mem::transmute_copy(&validationhostname)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Control: Control::, + Information: Information::, + InputStream: InputStream::, + OutputStream: OutputStream::, + ConnectWithEndpointPairAsync: ConnectWithEndpointPairAsync::, + ConnectAsync: ConnectAsync::, + ConnectWithEndpointPairAndProtectionLevelAsync: ConnectWithEndpointPairAndProtectionLevelAsync::, + ConnectWithProtectionLevelAsync: ConnectWithProtectionLevelAsync::, + UpgradeToSslAsync: UpgradeToSslAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStreamSocket_Vtbl { @@ -13203,6 +75582,39 @@ windows_core::imp::define_interface!(IStreamSocket2, IStreamSocket2_Vtbl, 0x29d0 impl windows_core::RuntimeType for IStreamSocket2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Networking_Connectivity")] +impl windows_core::RuntimeName for IStreamSocket2 { + const NAME: &'static str = "Windows.Networking.Sockets.IStreamSocket2"; +} +#[cfg(feature = "Networking_Connectivity")] +pub trait IStreamSocket2_Impl: super::super::Foundation::IClosable_Impl { + fn ConnectWithProtectionLevelAndAdapterAsync(&self, remoteHostName: windows_core::Ref<'_, super::HostName>, remoteServiceName: &windows_core::HSTRING, protectionLevel: SocketProtectionLevel, adapter: windows_core::Ref<'_, super::Connectivity::NetworkAdapter>) -> windows_core::Result; +} +#[cfg(feature = "Networking_Connectivity")] +impl IStreamSocket2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ConnectWithProtectionLevelAndAdapterAsync(this: *mut core::ffi::c_void, remotehostname: *mut core::ffi::c_void, remoteservicename: *mut core::ffi::c_void, protectionlevel: SocketProtectionLevel, adapter: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocket2_Impl::ConnectWithProtectionLevelAndAdapterAsync(this, core::mem::transmute_copy(&remotehostname), core::mem::transmute(&remoteservicename), protectionlevel, core::mem::transmute_copy(&adapter)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ConnectWithProtectionLevelAndAdapterAsync: ConnectWithProtectionLevelAndAdapterAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStreamSocket2_Vtbl { @@ -13216,6 +75628,76 @@ windows_core::imp::define_interface!(IStreamSocket3, IStreamSocket3_Vtbl, 0x3f43 impl windows_core::RuntimeType for IStreamSocket3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStreamSocket3 { + const NAME: &'static str = "Windows.Networking.Sockets.IStreamSocket3"; +} +pub trait IStreamSocket3_Impl: windows_core::IUnknownImpl { + fn CancelIOAsync(&self) -> windows_core::Result; + fn EnableTransferOwnership(&self, taskId: &windows_core::GUID) -> windows_core::Result<()>; + fn EnableTransferOwnershipWithConnectedStandbyAction(&self, taskId: &windows_core::GUID, connectedStandbyAction: SocketActivityConnectedStandbyAction) -> windows_core::Result<()>; + fn TransferOwnership(&self, socketId: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TransferOwnershipWithContext(&self, socketId: &windows_core::HSTRING, data: windows_core::Ref<'_, SocketActivityContext>) -> windows_core::Result<()>; + fn TransferOwnershipWithContextAndKeepAliveTime(&self, socketId: &windows_core::HSTRING, data: windows_core::Ref<'_, SocketActivityContext>, keepAliveTime: &super::super::Foundation::TimeSpan) -> windows_core::Result<()>; +} +impl IStreamSocket3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CancelIOAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocket3_Impl::CancelIOAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn EnableTransferOwnership(this: *mut core::ffi::c_void, taskid: windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStreamSocket3_Impl::EnableTransferOwnership(this, core::mem::transmute(&taskid)).into() + } + } + unsafe extern "system" fn EnableTransferOwnershipWithConnectedStandbyAction(this: *mut core::ffi::c_void, taskid: windows_core::GUID, connectedstandbyaction: SocketActivityConnectedStandbyAction) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStreamSocket3_Impl::EnableTransferOwnershipWithConnectedStandbyAction(this, core::mem::transmute(&taskid), connectedstandbyaction).into() + } + } + unsafe extern "system" fn TransferOwnership(this: *mut core::ffi::c_void, socketid: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStreamSocket3_Impl::TransferOwnership(this, core::mem::transmute(&socketid)).into() + } + } + unsafe extern "system" fn TransferOwnershipWithContext(this: *mut core::ffi::c_void, socketid: *mut core::ffi::c_void, data: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStreamSocket3_Impl::TransferOwnershipWithContext(this, core::mem::transmute(&socketid), core::mem::transmute_copy(&data)).into() + } + } + unsafe extern "system" fn TransferOwnershipWithContextAndKeepAliveTime(this: *mut core::ffi::c_void, socketid: *mut core::ffi::c_void, data: *mut core::ffi::c_void, keepalivetime: super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStreamSocket3_Impl::TransferOwnershipWithContextAndKeepAliveTime(this, core::mem::transmute(&socketid), core::mem::transmute_copy(&data), core::mem::transmute(&keepalivetime)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CancelIOAsync: CancelIOAsync::, + EnableTransferOwnership: EnableTransferOwnership::, + EnableTransferOwnershipWithConnectedStandbyAction: EnableTransferOwnershipWithConnectedStandbyAction::, + TransferOwnership: TransferOwnership::, + TransferOwnershipWithContext: TransferOwnershipWithContext::, + TransferOwnershipWithContextAndKeepAliveTime: TransferOwnershipWithContextAndKeepAliveTime::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStreamSocket3_Vtbl { @@ -13231,6 +75713,131 @@ windows_core::imp::define_interface!(IStreamSocketControl, IStreamSocketControl_ impl windows_core::RuntimeType for IStreamSocketControl { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStreamSocketControl { + const NAME: &'static str = "Windows.Networking.Sockets.IStreamSocketControl"; +} +pub trait IStreamSocketControl_Impl: windows_core::IUnknownImpl { + fn NoDelay(&self) -> windows_core::Result; + fn SetNoDelay(&self, value: bool) -> windows_core::Result<()>; + fn KeepAlive(&self) -> windows_core::Result; + fn SetKeepAlive(&self, value: bool) -> windows_core::Result<()>; + fn OutboundBufferSizeInBytes(&self) -> windows_core::Result; + fn SetOutboundBufferSizeInBytes(&self, value: u32) -> windows_core::Result<()>; + fn QualityOfService(&self) -> windows_core::Result; + fn SetQualityOfService(&self, value: SocketQualityOfService) -> windows_core::Result<()>; + fn OutboundUnicastHopLimit(&self) -> windows_core::Result; + fn SetOutboundUnicastHopLimit(&self, value: u8) -> windows_core::Result<()>; +} +impl IStreamSocketControl_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn NoDelay(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketControl_Impl::NoDelay(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetNoDelay(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStreamSocketControl_Impl::SetNoDelay(this, value).into() + } + } + unsafe extern "system" fn KeepAlive(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketControl_Impl::KeepAlive(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetKeepAlive(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStreamSocketControl_Impl::SetKeepAlive(this, value).into() + } + } + unsafe extern "system" fn OutboundBufferSizeInBytes(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketControl_Impl::OutboundBufferSizeInBytes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetOutboundBufferSizeInBytes(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStreamSocketControl_Impl::SetOutboundBufferSizeInBytes(this, value).into() + } + } + unsafe extern "system" fn QualityOfService(this: *mut core::ffi::c_void, result__: *mut SocketQualityOfService) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketControl_Impl::QualityOfService(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetQualityOfService(this: *mut core::ffi::c_void, value: SocketQualityOfService) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStreamSocketControl_Impl::SetQualityOfService(this, value).into() + } + } + unsafe extern "system" fn OutboundUnicastHopLimit(this: *mut core::ffi::c_void, result__: *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketControl_Impl::OutboundUnicastHopLimit(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetOutboundUnicastHopLimit(this: *mut core::ffi::c_void, value: u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStreamSocketControl_Impl::SetOutboundUnicastHopLimit(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + NoDelay: NoDelay::, + SetNoDelay: SetNoDelay::, + KeepAlive: KeepAlive::, + SetKeepAlive: SetKeepAlive::, + OutboundBufferSizeInBytes: OutboundBufferSizeInBytes::, + SetOutboundBufferSizeInBytes: SetOutboundBufferSizeInBytes::, + QualityOfService: QualityOfService::, + SetQualityOfService: SetQualityOfService::, + OutboundUnicastHopLimit: OutboundUnicastHopLimit::, + SetOutboundUnicastHopLimit: SetOutboundUnicastHopLimit::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStreamSocketControl_Vtbl { @@ -13250,6 +75857,39 @@ windows_core::imp::define_interface!(IStreamSocketControl2, IStreamSocketControl impl windows_core::RuntimeType for IStreamSocketControl2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Security_Cryptography_Certificates")] +impl windows_core::RuntimeName for IStreamSocketControl2 { + const NAME: &'static str = "Windows.Networking.Sockets.IStreamSocketControl2"; +} +#[cfg(feature = "Security_Cryptography_Certificates")] +pub trait IStreamSocketControl2_Impl: windows_core::IUnknownImpl { + fn IgnorableServerCertificateErrors(&self) -> windows_core::Result>; +} +#[cfg(feature = "Security_Cryptography_Certificates")] +impl IStreamSocketControl2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IgnorableServerCertificateErrors(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketControl2_Impl::IgnorableServerCertificateErrors(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IgnorableServerCertificateErrors: IgnorableServerCertificateErrors::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStreamSocketControl2_Vtbl { @@ -13263,6 +75903,69 @@ windows_core::imp::define_interface!(IStreamSocketControl3, IStreamSocketControl impl windows_core::RuntimeType for IStreamSocketControl3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Security_Cryptography_Certificates")] +impl windows_core::RuntimeName for IStreamSocketControl3 { + const NAME: &'static str = "Windows.Networking.Sockets.IStreamSocketControl3"; +} +#[cfg(feature = "Security_Cryptography_Certificates")] +pub trait IStreamSocketControl3_Impl: windows_core::IUnknownImpl { + fn SerializeConnectionAttempts(&self) -> windows_core::Result; + fn SetSerializeConnectionAttempts(&self, value: bool) -> windows_core::Result<()>; + fn ClientCertificate(&self) -> windows_core::Result; + fn SetClientCertificate(&self, value: windows_core::Ref<'_, super::super::Security::Cryptography::Certificates::Certificate>) -> windows_core::Result<()>; +} +#[cfg(feature = "Security_Cryptography_Certificates")] +impl IStreamSocketControl3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SerializeConnectionAttempts(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketControl3_Impl::SerializeConnectionAttempts(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetSerializeConnectionAttempts(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStreamSocketControl3_Impl::SetSerializeConnectionAttempts(this, value).into() + } + } + unsafe extern "system" fn ClientCertificate(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketControl3_Impl::ClientCertificate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetClientCertificate(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStreamSocketControl3_Impl::SetClientCertificate(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + SerializeConnectionAttempts: SerializeConnectionAttempts::, + SetSerializeConnectionAttempts: SetSerializeConnectionAttempts::, + ClientCertificate: ClientCertificate::, + SetClientCertificate: SetClientCertificate::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStreamSocketControl3_Vtbl { @@ -13282,6 +75985,43 @@ windows_core::imp::define_interface!(IStreamSocketControl4, IStreamSocketControl impl windows_core::RuntimeType for IStreamSocketControl4 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStreamSocketControl4 { + const NAME: &'static str = "Windows.Networking.Sockets.IStreamSocketControl4"; +} +pub trait IStreamSocketControl4_Impl: windows_core::IUnknownImpl { + fn MinProtectionLevel(&self) -> windows_core::Result; + fn SetMinProtectionLevel(&self, value: SocketProtectionLevel) -> windows_core::Result<()>; +} +impl IStreamSocketControl4_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn MinProtectionLevel(this: *mut core::ffi::c_void, result__: *mut SocketProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketControl4_Impl::MinProtectionLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMinProtectionLevel(this: *mut core::ffi::c_void, value: SocketProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStreamSocketControl4_Impl::SetMinProtectionLevel(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + MinProtectionLevel: MinProtectionLevel::, + SetMinProtectionLevel: SetMinProtectionLevel::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStreamSocketControl4_Vtbl { @@ -13293,6 +76033,171 @@ windows_core::imp::define_interface!(IStreamSocketInformation, IStreamSocketInfo impl windows_core::RuntimeType for IStreamSocketInformation { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IStreamSocketInformation { + const NAME: &'static str = "Windows.Networking.Sockets.IStreamSocketInformation"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IStreamSocketInformation_Impl: windows_core::IUnknownImpl { + fn LocalAddress(&self) -> windows_core::Result; + fn LocalPort(&self) -> windows_core::Result; + fn RemoteHostName(&self) -> windows_core::Result; + fn RemoteAddress(&self) -> windows_core::Result; + fn RemoteServiceName(&self) -> windows_core::Result; + fn RemotePort(&self) -> windows_core::Result; + fn RoundTripTimeStatistics(&self) -> windows_core::Result; + fn BandwidthStatistics(&self) -> windows_core::Result; + fn ProtectionLevel(&self) -> windows_core::Result; + fn SessionKey(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IStreamSocketInformation_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn LocalAddress(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketInformation_Impl::LocalAddress(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn LocalPort(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketInformation_Impl::LocalPort(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoteHostName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketInformation_Impl::RemoteHostName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoteAddress(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketInformation_Impl::RemoteAddress(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoteServiceName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketInformation_Impl::RemoteServiceName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemotePort(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketInformation_Impl::RemotePort(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RoundTripTimeStatistics(this: *mut core::ffi::c_void, result__: *mut RoundTripTimeStatistics) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketInformation_Impl::RoundTripTimeStatistics(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn BandwidthStatistics(this: *mut core::ffi::c_void, result__: *mut BandwidthStatistics) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketInformation_Impl::BandwidthStatistics(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ProtectionLevel(this: *mut core::ffi::c_void, result__: *mut SocketProtectionLevel) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketInformation_Impl::ProtectionLevel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SessionKey(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketInformation_Impl::SessionKey(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + LocalAddress: LocalAddress::, + LocalPort: LocalPort::, + RemoteHostName: RemoteHostName::, + RemoteAddress: RemoteAddress::, + RemoteServiceName: RemoteServiceName::, + RemotePort: RemotePort::, + RoundTripTimeStatistics: RoundTripTimeStatistics::, + BandwidthStatistics: BandwidthStatistics::, + ProtectionLevel: ProtectionLevel::, + SessionKey: SessionKey::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStreamSocketInformation_Vtbl { @@ -13315,6 +76220,83 @@ windows_core::imp::define_interface!(IStreamSocketInformation2, IStreamSocketInf impl windows_core::RuntimeType for IStreamSocketInformation2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Security_Cryptography_Certificates")] +impl windows_core::RuntimeName for IStreamSocketInformation2 { + const NAME: &'static str = "Windows.Networking.Sockets.IStreamSocketInformation2"; +} +#[cfg(feature = "Security_Cryptography_Certificates")] +pub trait IStreamSocketInformation2_Impl: windows_core::IUnknownImpl { + fn ServerCertificateErrorSeverity(&self) -> windows_core::Result; + fn ServerCertificateErrors(&self) -> windows_core::Result>; + fn ServerCertificate(&self) -> windows_core::Result; + fn ServerIntermediateCertificates(&self) -> windows_core::Result>; +} +#[cfg(feature = "Security_Cryptography_Certificates")] +impl IStreamSocketInformation2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ServerCertificateErrorSeverity(this: *mut core::ffi::c_void, result__: *mut SocketSslErrorSeverity) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketInformation2_Impl::ServerCertificateErrorSeverity(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ServerCertificateErrors(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketInformation2_Impl::ServerCertificateErrors(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ServerCertificate(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketInformation2_Impl::ServerCertificate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ServerIntermediateCertificates(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketInformation2_Impl::ServerIntermediateCertificates(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ServerCertificateErrorSeverity: ServerCertificateErrorSeverity::, + ServerCertificateErrors: ServerCertificateErrors::, + ServerCertificate: ServerCertificate::, + ServerIntermediateCertificates: ServerIntermediateCertificates::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStreamSocketInformation2_Vtbl { @@ -13337,6 +76319,51 @@ windows_core::imp::define_interface!(IStreamSocketStatics, IStreamSocketStatics_ impl windows_core::RuntimeType for IStreamSocketStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStreamSocketStatics { + const NAME: &'static str = "Windows.Networking.Sockets.IStreamSocketStatics"; +} +pub trait IStreamSocketStatics_Impl: windows_core::IUnknownImpl { + fn GetEndpointPairsAsync(&self, remoteHostName: windows_core::Ref<'_, super::HostName>, remoteServiceName: &windows_core::HSTRING) -> windows_core::Result>>; + fn GetEndpointPairsWithSortOptionsAsync(&self, remoteHostName: windows_core::Ref<'_, super::HostName>, remoteServiceName: &windows_core::HSTRING, sortOptions: super::HostNameSortOptions) -> windows_core::Result>>; +} +impl IStreamSocketStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetEndpointPairsAsync(this: *mut core::ffi::c_void, remotehostname: *mut core::ffi::c_void, remoteservicename: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketStatics_Impl::GetEndpointPairsAsync(this, core::mem::transmute_copy(&remotehostname), core::mem::transmute(&remoteservicename)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetEndpointPairsWithSortOptionsAsync(this: *mut core::ffi::c_void, remotehostname: *mut core::ffi::c_void, remoteservicename: *mut core::ffi::c_void, sortoptions: super::HostNameSortOptions, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStreamSocketStatics_Impl::GetEndpointPairsWithSortOptionsAsync(this, core::mem::transmute_copy(&remotehostname), core::mem::transmute(&remoteservicename), sortoptions) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetEndpointPairsAsync: GetEndpointPairsAsync::, + GetEndpointPairsWithSortOptionsAsync: GetEndpointPairsWithSortOptionsAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStreamSocketStatics_Vtbl { @@ -13376,6 +76403,14 @@ impl windows_core::RuntimeType for SocketActivityConnectedStandbyAction { pub struct SocketActivityContext(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(SocketActivityContext, windows_core::IUnknown, windows_core::IInspectable); impl SocketActivityContext { + #[cfg(feature = "Storage_Streams")] + pub fn Data(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Data)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } #[cfg(feature = "Storage_Streams")] pub fn Create(data: P0) -> windows_core::Result where @@ -13476,6 +76511,13 @@ impl StreamSocket { (windows_core::Interface::vtable(this).Control)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Information(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Information)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } #[cfg(feature = "Storage_Streams")] pub fn InputStream(&self) -> windows_core::Result { let this = self; @@ -13492,6 +76534,16 @@ impl StreamSocket { (windows_core::Interface::vtable(this).OutputStream)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ConnectWithEndpointPairAsync(&self, endpointpair: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ConnectWithEndpointPairAsync)(windows_core::Interface::as_raw(this), endpointpair.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn ConnectAsync(&self, remotehostname: P0, remoteservicename: &windows_core::HSTRING) -> windows_core::Result where P0: windows_core::Param, @@ -13502,6 +76554,16 @@ impl StreamSocket { (windows_core::Interface::vtable(this).ConnectAsync)(windows_core::Interface::as_raw(this), remotehostname.param().abi(), core::mem::transmute_copy(remoteservicename), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ConnectWithEndpointPairAndProtectionLevelAsync(&self, endpointpair: P0, protectionlevel: SocketProtectionLevel) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ConnectWithEndpointPairAndProtectionLevelAsync)(windows_core::Interface::as_raw(this), endpointpair.param().abi(), protectionlevel, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn ConnectWithProtectionLevelAsync(&self, remotehostname: P0, remoteservicename: &windows_core::HSTRING, protectionlevel: SocketProtectionLevel) -> windows_core::Result where P0: windows_core::Param, @@ -13512,6 +76574,79 @@ impl StreamSocket { (windows_core::Interface::vtable(this).ConnectWithProtectionLevelAsync)(windows_core::Interface::as_raw(this), remotehostname.param().abi(), core::mem::transmute_copy(remoteservicename), protectionlevel, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn UpgradeToSslAsync(&self, protectionlevel: SocketProtectionLevel, validationhostname: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UpgradeToSslAsync)(windows_core::Interface::as_raw(this), protectionlevel, validationhostname.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Networking_Connectivity")] + pub fn ConnectWithProtectionLevelAndAdapterAsync(&self, remotehostname: P0, remoteservicename: &windows_core::HSTRING, protectionlevel: SocketProtectionLevel, adapter: P3) -> windows_core::Result + where + P0: windows_core::Param, + P3: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ConnectWithProtectionLevelAndAdapterAsync)(windows_core::Interface::as_raw(this), remotehostname.param().abi(), core::mem::transmute_copy(remoteservicename), protectionlevel, adapter.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CancelIOAsync(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CancelIOAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn EnableTransferOwnership(&self, taskid: windows_core::GUID) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).EnableTransferOwnership)(windows_core::Interface::as_raw(this), taskid).ok() } + } + pub fn EnableTransferOwnershipWithConnectedStandbyAction(&self, taskid: windows_core::GUID, connectedstandbyaction: SocketActivityConnectedStandbyAction) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).EnableTransferOwnershipWithConnectedStandbyAction)(windows_core::Interface::as_raw(this), taskid, connectedstandbyaction).ok() } + } + pub fn TransferOwnership(&self, socketid: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).TransferOwnership)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(socketid)).ok() } + } + pub fn TransferOwnershipWithContext(&self, socketid: &windows_core::HSTRING, data: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).TransferOwnershipWithContext)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(socketid), data.param().abi()).ok() } + } + pub fn TransferOwnershipWithContextAndKeepAliveTime(&self, socketid: &windows_core::HSTRING, data: P1, keepalivetime: super::super::Foundation::TimeSpan) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).TransferOwnershipWithContextAndKeepAliveTime)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(socketid), data.param().abi(), keepalivetime).ok() } + } + pub fn GetEndpointPairsAsync(remotehostname: P0, remoteservicename: &windows_core::HSTRING) -> windows_core::Result>> + where + P0: windows_core::Param, + { + Self::IStreamSocketStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetEndpointPairsAsync)(windows_core::Interface::as_raw(this), remotehostname.param().abi(), core::mem::transmute_copy(remoteservicename), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetEndpointPairsWithSortOptionsAsync(remotehostname: P0, remoteservicename: &windows_core::HSTRING, sortoptions: super::HostNameSortOptions) -> windows_core::Result>> + where + P0: windows_core::Param, + { + Self::IStreamSocketStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetEndpointPairsWithSortOptionsAsync)(windows_core::Interface::as_raw(this), remotehostname.param().abi(), core::mem::transmute_copy(remoteservicename), sortoptions, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IStreamSocketStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -13534,10 +76669,61 @@ unsafe impl Sync for StreamSocket {} pub struct StreamSocketControl(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(StreamSocketControl, windows_core::IUnknown, windows_core::IInspectable); impl StreamSocketControl { + pub fn NoDelay(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NoDelay)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn SetNoDelay(&self, value: bool) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).SetNoDelay)(windows_core::Interface::as_raw(this), value).ok() } } + pub fn KeepAlive(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).KeepAlive)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetKeepAlive(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetKeepAlive)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn OutboundBufferSizeInBytes(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OutboundBufferSizeInBytes)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetOutboundBufferSizeInBytes(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetOutboundBufferSizeInBytes)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn QualityOfService(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).QualityOfService)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetQualityOfService(&self, value: SocketQualityOfService) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetQualityOfService)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn OutboundUnicastHopLimit(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OutboundUnicastHopLimit)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetOutboundUnicastHopLimit(&self, value: u8) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetOutboundUnicastHopLimit)(windows_core::Interface::as_raw(this), value).ok() } + } #[cfg(feature = "Security_Cryptography_Certificates")] pub fn IgnorableServerCertificateErrors(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::(self)?; @@ -13546,7 +76732,45 @@ impl StreamSocketControl { (windows_core::Interface::vtable(this).IgnorableServerCertificateErrors)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn SerializeConnectionAttempts(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SerializeConnectionAttempts)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } + pub fn SetSerializeConnectionAttempts(&self, value: bool) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetSerializeConnectionAttempts)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Security_Cryptography_Certificates")] + pub fn ClientCertificate(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ClientCertificate)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Security_Cryptography_Certificates")] + pub fn SetClientCertificate(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetClientCertificate)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn MinProtectionLevel(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinProtectionLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetMinProtectionLevel(&self, value: SocketProtectionLevel) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetMinProtectionLevel)(windows_core::Interface::as_raw(this), value).ok() } + } +} impl windows_core::RuntimeType for StreamSocketControl { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -13563,6 +76787,110 @@ unsafe impl Sync for StreamSocketControl {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct StreamSocketInformation(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(StreamSocketInformation, windows_core::IUnknown, windows_core::IInspectable); +impl StreamSocketInformation { + pub fn LocalAddress(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LocalAddress)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn LocalPort(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LocalPort)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn RemoteHostName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RemoteHostName)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RemoteAddress(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RemoteAddress)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RemoteServiceName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RemoteServiceName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn RemotePort(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RemotePort)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn RoundTripTimeStatistics(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RoundTripTimeStatistics)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn BandwidthStatistics(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BandwidthStatistics)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ProtectionLevel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProtectionLevel)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn SessionKey(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SessionKey)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ServerCertificateErrorSeverity(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ServerCertificateErrorSeverity)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Security_Cryptography_Certificates")] + pub fn ServerCertificateErrors(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ServerCertificateErrors)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Security_Cryptography_Certificates")] + pub fn ServerCertificate(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ServerCertificate)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Security_Cryptography_Certificates")] + pub fn ServerIntermediateCertificates(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ServerIntermediateCertificates)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for StreamSocketInformation { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -13577,12 +76905,118 @@ unsafe impl Send for StreamSocketInformation {} unsafe impl Sync for StreamSocketInformation {} } } +#[cfg(feature = "Perception")] +pub mod Perception{ +#[cfg(feature = "Perception_Spatial")] +pub mod Spatial{ +windows_core::imp::define_interface!(ISpatialCoordinateSystem, ISpatialCoordinateSystem_Vtbl, 0x69ebca4b_60a3_3586_a653_59a7bd676d07); +impl windows_core::RuntimeType for ISpatialCoordinateSystem { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for ISpatialCoordinateSystem { + const NAME: &'static str = "Windows.Perception.Spatial.ISpatialCoordinateSystem"; +} +pub trait ISpatialCoordinateSystem_Impl: windows_core::IUnknownImpl { + fn TryGetTransformTo(&self, target: windows_core::Ref<'_, SpatialCoordinateSystem>) -> windows_core::Result>; +} +impl ISpatialCoordinateSystem_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TryGetTransformTo(this: *mut core::ffi::c_void, target: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISpatialCoordinateSystem_Impl::TryGetTransformTo(this, core::mem::transmute_copy(&target)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + TryGetTransformTo: TryGetTransformTo::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ISpatialCoordinateSystem_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub TryGetTransformTo: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SpatialCoordinateSystem(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(SpatialCoordinateSystem, windows_core::IUnknown, windows_core::IInspectable); +impl SpatialCoordinateSystem { + pub fn TryGetTransformTo(&self, target: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryGetTransformTo)(windows_core::Interface::as_raw(this), target.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for SpatialCoordinateSystem { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for SpatialCoordinateSystem { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for SpatialCoordinateSystem { + const NAME: &'static str = "Windows.Perception.Spatial.SpatialCoordinateSystem"; +} +unsafe impl Send for SpatialCoordinateSystem {} +unsafe impl Sync for SpatialCoordinateSystem {} +} +} +#[cfg(feature = "Security")] pub mod Security{ +#[cfg(feature = "Security_Credentials")] pub mod Credentials{ windows_core::imp::define_interface!(ICredentialFactory, ICredentialFactory_Vtbl, 0x54ef13a1_bf26_47b5_97dd_de779b7cad58); impl windows_core::RuntimeType for ICredentialFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICredentialFactory { + const NAME: &'static str = "Windows.Security.Credentials.ICredentialFactory"; +} +pub trait ICredentialFactory_Impl: windows_core::IUnknownImpl { + fn CreatePasswordCredential(&self, resource: &windows_core::HSTRING, userName: &windows_core::HSTRING, password: &windows_core::HSTRING) -> windows_core::Result; +} +impl ICredentialFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreatePasswordCredential(this: *mut core::ffi::c_void, resource: *mut core::ffi::c_void, username: *mut core::ffi::c_void, password: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICredentialFactory_Impl::CreatePasswordCredential(this, core::mem::transmute(&resource), core::mem::transmute(&username), core::mem::transmute(&password)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreatePasswordCredential: CreatePasswordCredential::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICredentialFactory_Vtbl { @@ -13593,6 +77027,116 @@ windows_core::imp::define_interface!(IPasswordCredential, IPasswordCredential_Vt impl windows_core::RuntimeType for IPasswordCredential { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Foundation_Collections")] +impl windows_core::RuntimeName for IPasswordCredential { + const NAME: &'static str = "Windows.Security.Credentials.IPasswordCredential"; +} +#[cfg(feature = "Foundation_Collections")] +pub trait IPasswordCredential_Impl: windows_core::IUnknownImpl { + fn Resource(&self) -> windows_core::Result; + fn SetResource(&self, resource: &windows_core::HSTRING) -> windows_core::Result<()>; + fn UserName(&self) -> windows_core::Result; + fn SetUserName(&self, userName: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Password(&self) -> windows_core::Result; + fn SetPassword(&self, password: &windows_core::HSTRING) -> windows_core::Result<()>; + fn RetrievePassword(&self) -> windows_core::Result<()>; + fn Properties(&self) -> windows_core::Result; +} +#[cfg(feature = "Foundation_Collections")] +impl IPasswordCredential_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Resource(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPasswordCredential_Impl::Resource(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetResource(this: *mut core::ffi::c_void, resource: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IPasswordCredential_Impl::SetResource(this, core::mem::transmute(&resource)).into() + } + } + unsafe extern "system" fn UserName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPasswordCredential_Impl::UserName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetUserName(this: *mut core::ffi::c_void, username: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IPasswordCredential_Impl::SetUserName(this, core::mem::transmute(&username)).into() + } + } + unsafe extern "system" fn Password(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPasswordCredential_Impl::Password(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPassword(this: *mut core::ffi::c_void, password: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IPasswordCredential_Impl::SetPassword(this, core::mem::transmute(&password)).into() + } + } + unsafe extern "system" fn RetrievePassword(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IPasswordCredential_Impl::RetrievePassword(this).into() + } + } + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IPasswordCredential_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Resource: Resource::, + SetResource: SetResource::, + UserName: UserName::, + SetUserName: SetUserName::, + Password: Password::, + SetPassword: SetPassword::, + RetrievePassword: RetrievePassword::, + Properties: Properties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IPasswordCredential_Vtbl { @@ -13621,6 +77165,57 @@ impl PasswordCredential { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn CreatePasswordCredential(resource: &windows_core::HSTRING, username: &windows_core::HSTRING, password: &windows_core::HSTRING) -> windows_core::Result { + Self::ICredentialFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreatePasswordCredential)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(resource), core::mem::transmute_copy(username), core::mem::transmute_copy(password), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Resource(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Resource)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetResource(&self, resource: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetResource)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(resource)).ok() } + } + pub fn UserName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UserName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetUserName(&self, username: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetUserName)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(username)).ok() } + } + pub fn Password(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Password)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetPassword(&self, password: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPassword)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(password)).ok() } + } + pub fn RetrievePassword(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RetrievePassword)(windows_core::Interface::as_raw(this)).ok() } + } + #[cfg(feature = "Foundation_Collections")] + pub fn Properties(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } fn ICredentialFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -13639,13 +77234,198 @@ impl windows_core::RuntimeName for PasswordCredential { unsafe impl Send for PasswordCredential {} unsafe impl Sync for PasswordCredential {} } +#[cfg(feature = "Security_Cryptography")] pub mod Cryptography{ +#[cfg(feature = "Security_Cryptography_Certificates")] pub mod Certificates{ #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] pub struct Certificate(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(Certificate, windows_core::IUnknown, windows_core::IInspectable); impl Certificate { + pub fn BuildChainAsync(&self, certificates: P0) -> windows_core::Result> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BuildChainAsync)(windows_core::Interface::as_raw(this), certificates.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn BuildChainWithParametersAsync(&self, certificates: P0, parameters: P1) -> windows_core::Result> + where + P0: windows_core::Param>, + P1: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BuildChainWithParametersAsync)(windows_core::Interface::as_raw(this), certificates.param().abi(), parameters.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SerialNumber(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::MaybeUninit::zeroed(); + (windows_core::Interface::vtable(this).SerialNumber)(windows_core::Interface::as_raw(this), windows_core::Array::::set_abi_len(core::mem::transmute(&mut result__)), result__.as_mut_ptr() as *mut _ as _).map(|| result__.assume_init()) + } + } + pub fn GetHashValue(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::MaybeUninit::zeroed(); + (windows_core::Interface::vtable(this).GetHashValue)(windows_core::Interface::as_raw(this), windows_core::Array::::set_abi_len(core::mem::transmute(&mut result__)), result__.as_mut_ptr() as *mut _ as _).map(|| result__.assume_init()) + } + } + pub fn GetHashValueWithAlgorithm(&self, hashalgorithmname: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::MaybeUninit::zeroed(); + (windows_core::Interface::vtable(this).GetHashValueWithAlgorithm)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(hashalgorithmname), windows_core::Array::::set_abi_len(core::mem::transmute(&mut result__)), result__.as_mut_ptr() as *mut _ as _).map(|| result__.assume_init()) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetCertificateBlob(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCertificateBlob)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Subject(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Subject)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Issuer(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Issuer)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn HasPrivateKey(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HasPrivateKey)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsStronglyProtected(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsStronglyProtected)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ValidFrom(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ValidFrom)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ValidTo(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ValidTo)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn EnhancedKeyUsages(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).EnhancedKeyUsages)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetFriendlyName(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetFriendlyName)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn FriendlyName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FriendlyName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn IsSecurityDeviceBound(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsSecurityDeviceBound)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn KeyUsages(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).KeyUsages)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn KeyAlgorithmName(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).KeyAlgorithmName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SignatureAlgorithmName(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SignatureAlgorithmName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SignatureHashAlgorithmName(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SignatureHashAlgorithmName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SubjectAlternativeName(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SubjectAlternativeName)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IsPerUser(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsPerUser)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn StoreName(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StoreName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn KeyStorageProviderName(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).KeyStorageProviderName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateCertificate(certblob: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::ICertificateFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateCertificate)(windows_core::Interface::as_raw(this), certblob.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn ICertificateFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -13667,6 +77447,32 @@ unsafe impl Sync for Certificate {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct CertificateChain(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(CertificateChain, windows_core::IUnknown, windows_core::IInspectable); +impl CertificateChain { + pub fn Validate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Validate)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ValidateWithParameters(&self, parameter: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ValidateWithParameters)(windows_core::Interface::as_raw(this), parameter.param().abi(), &mut result__).map(|| result__) + } + } + pub fn GetCertificates(&self, includeroot: bool) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCertificates)(windows_core::Interface::as_raw(this), includeroot, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for CertificateChain { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -13706,7 +77512,44 @@ impl CertificateExtension { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn ObjectId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ObjectId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } } + pub fn SetObjectId(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetObjectId)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn IsCritical(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsCritical)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetIsCritical(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetIsCritical)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn EncodeValue(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).EncodeValue)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Value(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::MaybeUninit::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), windows_core::Array::::set_abi_len(core::mem::transmute(&mut result__)), result__.as_mut_ptr() as *mut _ as _).map(|| result__.assume_init()) + } + } + pub fn SetValue(&self, value: &[u8]) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetValue)(windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr()).ok() } + } +} impl windows_core::RuntimeType for CertificateExtension { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -13731,7 +77574,95 @@ impl CertificateKeyUsages { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn EncipherOnly(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).EncipherOnly)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } + pub fn SetEncipherOnly(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetEncipherOnly)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn CrlSign(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CrlSign)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetCrlSign(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetCrlSign)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn KeyCertificateSign(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).KeyCertificateSign)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetKeyCertificateSign(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetKeyCertificateSign)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn KeyAgreement(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).KeyAgreement)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetKeyAgreement(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetKeyAgreement)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn DataEncipherment(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DataEncipherment)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetDataEncipherment(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDataEncipherment)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn KeyEncipherment(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).KeyEncipherment)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetKeyEncipherment(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetKeyEncipherment)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn NonRepudiation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NonRepudiation)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetNonRepudiation(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetNonRepudiation)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn DigitalSignature(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DigitalSignature)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetDigitalSignature(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDigitalSignature)(windows_core::Interface::as_raw(this), value).ok() } + } +} impl windows_core::RuntimeType for CertificateKeyUsages { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -13756,7 +77687,76 @@ impl ChainBuildingParameters { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn EnhancedKeyUsages(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).EnhancedKeyUsages)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn ValidationTimestamp(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ValidationTimestamp)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetValidationTimestamp(&self, value: super::super::super::Foundation::DateTime) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetValidationTimestamp)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn RevocationCheckEnabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RevocationCheckEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetRevocationCheckEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetRevocationCheckEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn NetworkRetrievalEnabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NetworkRetrievalEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetNetworkRetrievalEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetNetworkRetrievalEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn AuthorityInformationAccessEnabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AuthorityInformationAccessEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetAuthorityInformationAccessEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAuthorityInformationAccessEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn CurrentTimeValidationEnabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CurrentTimeValidationEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetCurrentTimeValidationEnabled(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetCurrentTimeValidationEnabled)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ExclusiveTrustRoots(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExclusiveTrustRoots)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for ChainBuildingParameters { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -13781,7 +77781,34 @@ impl ChainValidationParameters { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn CertificateChainPolicy(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CertificateChainPolicy)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } + pub fn SetCertificateChainPolicy(&self, value: CertificateChainPolicy) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetCertificateChainPolicy)(windows_core::Interface::as_raw(this), value).ok() } + } + #[cfg(feature = "Networking")] + pub fn ServerDnsName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ServerDnsName)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Networking")] + pub fn SetServerDnsName(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetServerDnsName)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } +} impl windows_core::RuntimeType for ChainValidationParameters { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -13823,6 +77850,241 @@ windows_core::imp::define_interface!(ICertificate, ICertificate_Vtbl, 0x333f740c impl windows_core::RuntimeType for ICertificate { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for ICertificate { + const NAME: &'static str = "Windows.Security.Cryptography.Certificates.ICertificate"; +} +#[cfg(feature = "Storage_Streams")] +pub trait ICertificate_Impl: windows_core::IUnknownImpl { + fn BuildChainAsync(&self, certificates: windows_core::Ref<'_, windows_collections::IIterable>) -> windows_core::Result>; + fn BuildChainWithParametersAsync(&self, certificates: windows_core::Ref<'_, windows_collections::IIterable>, parameters: windows_core::Ref<'_, ChainBuildingParameters>) -> windows_core::Result>; + fn SerialNumber(&self) -> windows_core::Result>; + fn GetHashValue(&self) -> windows_core::Result>; + fn GetHashValueWithAlgorithm(&self, hashAlgorithmName: &windows_core::HSTRING) -> windows_core::Result>; + fn GetCertificateBlob(&self) -> windows_core::Result; + fn Subject(&self) -> windows_core::Result; + fn Issuer(&self) -> windows_core::Result; + fn HasPrivateKey(&self) -> windows_core::Result; + fn IsStronglyProtected(&self) -> windows_core::Result; + fn ValidFrom(&self) -> windows_core::Result; + fn ValidTo(&self) -> windows_core::Result; + fn EnhancedKeyUsages(&self) -> windows_core::Result>; + fn SetFriendlyName(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn FriendlyName(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl ICertificate_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn BuildChainAsync(this: *mut core::ffi::c_void, certificates: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate_Impl::BuildChainAsync(this, core::mem::transmute_copy(&certificates)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn BuildChainWithParametersAsync(this: *mut core::ffi::c_void, certificates: *mut core::ffi::c_void, parameters: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate_Impl::BuildChainWithParametersAsync(this, core::mem::transmute_copy(&certificates), core::mem::transmute_copy(¶meters)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SerialNumber(this: *mut core::ffi::c_void, result_size__: *mut u32, result__: *mut *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate_Impl::SerialNumber(this) { + Ok(ok__) => { + let (ok_data__, ok_data_len__) = ok__.into_abi(); + result__.write(core::mem::transmute(ok_data__)); + result_size__.write(ok_data_len__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetHashValue(this: *mut core::ffi::c_void, result_size__: *mut u32, result__: *mut *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate_Impl::GetHashValue(this) { + Ok(ok__) => { + let (ok_data__, ok_data_len__) = ok__.into_abi(); + result__.write(core::mem::transmute(ok_data__)); + result_size__.write(ok_data_len__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetHashValueWithAlgorithm(this: *mut core::ffi::c_void, hashalgorithmname: *mut core::ffi::c_void, result_size__: *mut u32, result__: *mut *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate_Impl::GetHashValueWithAlgorithm(this, core::mem::transmute(&hashalgorithmname)) { + Ok(ok__) => { + let (ok_data__, ok_data_len__) = ok__.into_abi(); + result__.write(core::mem::transmute(ok_data__)); + result_size__.write(ok_data_len__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetCertificateBlob(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate_Impl::GetCertificateBlob(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Subject(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate_Impl::Subject(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Issuer(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate_Impl::Issuer(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn HasPrivateKey(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate_Impl::HasPrivateKey(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsStronglyProtected(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate_Impl::IsStronglyProtected(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ValidFrom(this: *mut core::ffi::c_void, result__: *mut super::super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate_Impl::ValidFrom(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ValidTo(this: *mut core::ffi::c_void, result__: *mut super::super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate_Impl::ValidTo(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn EnhancedKeyUsages(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate_Impl::EnhancedKeyUsages(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetFriendlyName(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICertificate_Impl::SetFriendlyName(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn FriendlyName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate_Impl::FriendlyName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + BuildChainAsync: BuildChainAsync::, + BuildChainWithParametersAsync: BuildChainWithParametersAsync::, + SerialNumber: SerialNumber::, + GetHashValue: GetHashValue::, + GetHashValueWithAlgorithm: GetHashValueWithAlgorithm::, + GetCertificateBlob: GetCertificateBlob::, + Subject: Subject::, + Issuer: Issuer::, + HasPrivateKey: HasPrivateKey::, + IsStronglyProtected: IsStronglyProtected::, + ValidFrom: ValidFrom::, + ValidTo: ValidTo::, + EnhancedKeyUsages: EnhancedKeyUsages::, + SetFriendlyName: SetFriendlyName::, + FriendlyName: FriendlyName::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICertificate_Vtbl { @@ -13850,6 +78112,110 @@ windows_core::imp::define_interface!(ICertificate2, ICertificate2_Vtbl, 0x17b837 impl windows_core::RuntimeType for ICertificate2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICertificate2 { + const NAME: &'static str = "Windows.Security.Cryptography.Certificates.ICertificate2"; +} +pub trait ICertificate2_Impl: windows_core::IUnknownImpl { + fn IsSecurityDeviceBound(&self) -> windows_core::Result; + fn KeyUsages(&self) -> windows_core::Result; + fn KeyAlgorithmName(&self) -> windows_core::Result; + fn SignatureAlgorithmName(&self) -> windows_core::Result; + fn SignatureHashAlgorithmName(&self) -> windows_core::Result; + fn SubjectAlternativeName(&self) -> windows_core::Result; +} +impl ICertificate2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsSecurityDeviceBound(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate2_Impl::IsSecurityDeviceBound(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn KeyUsages(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate2_Impl::KeyUsages(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn KeyAlgorithmName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate2_Impl::KeyAlgorithmName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SignatureAlgorithmName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate2_Impl::SignatureAlgorithmName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SignatureHashAlgorithmName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate2_Impl::SignatureHashAlgorithmName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SubjectAlternativeName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate2_Impl::SubjectAlternativeName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsSecurityDeviceBound: IsSecurityDeviceBound::, + KeyUsages: KeyUsages::, + KeyAlgorithmName: KeyAlgorithmName::, + SignatureAlgorithmName: SignatureAlgorithmName::, + SignatureHashAlgorithmName: SignatureHashAlgorithmName::, + SubjectAlternativeName: SubjectAlternativeName::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICertificate2_Vtbl { @@ -13865,6 +78231,65 @@ windows_core::imp::define_interface!(ICertificate3, ICertificate3_Vtbl, 0xbe51a9 impl windows_core::RuntimeType for ICertificate3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICertificate3 { + const NAME: &'static str = "Windows.Security.Cryptography.Certificates.ICertificate3"; +} +pub trait ICertificate3_Impl: windows_core::IUnknownImpl { + fn IsPerUser(&self) -> windows_core::Result; + fn StoreName(&self) -> windows_core::Result; + fn KeyStorageProviderName(&self) -> windows_core::Result; +} +impl ICertificate3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsPerUser(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate3_Impl::IsPerUser(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn StoreName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate3_Impl::StoreName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn KeyStorageProviderName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificate3_Impl::KeyStorageProviderName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsPerUser: IsPerUser::, + StoreName: StoreName::, + KeyStorageProviderName: KeyStorageProviderName::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICertificate3_Vtbl { @@ -13877,6 +78302,64 @@ windows_core::imp::define_interface!(ICertificateChain, ICertificateChain_Vtbl, impl windows_core::RuntimeType for ICertificateChain { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICertificateChain { + const NAME: &'static str = "Windows.Security.Cryptography.Certificates.ICertificateChain"; +} +pub trait ICertificateChain_Impl: windows_core::IUnknownImpl { + fn Validate(&self) -> windows_core::Result; + fn ValidateWithParameters(&self, parameter: windows_core::Ref<'_, ChainValidationParameters>) -> windows_core::Result; + fn GetCertificates(&self, includeRoot: bool) -> windows_core::Result>; +} +impl ICertificateChain_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Validate(this: *mut core::ffi::c_void, result__: *mut ChainValidationResult) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificateChain_Impl::Validate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ValidateWithParameters(this: *mut core::ffi::c_void, parameter: *mut core::ffi::c_void, result__: *mut ChainValidationResult) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificateChain_Impl::ValidateWithParameters(this, core::mem::transmute_copy(¶meter)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetCertificates(this: *mut core::ffi::c_void, includeroot: bool, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificateChain_Impl::GetCertificates(this, includeroot) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Validate: Validate::, + ValidateWithParameters: ValidateWithParameters::, + GetCertificates: GetCertificates::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICertificateChain_Vtbl { @@ -13889,6 +78372,98 @@ windows_core::imp::define_interface!(ICertificateExtension, ICertificateExtensio impl windows_core::RuntimeType for ICertificateExtension { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICertificateExtension { + const NAME: &'static str = "Windows.Security.Cryptography.Certificates.ICertificateExtension"; +} +pub trait ICertificateExtension_Impl: windows_core::IUnknownImpl { + fn ObjectId(&self) -> windows_core::Result; + fn SetObjectId(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn IsCritical(&self) -> windows_core::Result; + fn SetIsCritical(&self, value: bool) -> windows_core::Result<()>; + fn EncodeValue(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Value(&self) -> windows_core::Result>; + fn SetValue(&self, value: &[u8]) -> windows_core::Result<()>; +} +impl ICertificateExtension_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ObjectId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificateExtension_Impl::ObjectId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetObjectId(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICertificateExtension_Impl::SetObjectId(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn IsCritical(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificateExtension_Impl::IsCritical(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetIsCritical(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICertificateExtension_Impl::SetIsCritical(this, value).into() + } + } + unsafe extern "system" fn EncodeValue(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICertificateExtension_Impl::EncodeValue(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result_size__: *mut u32, result__: *mut *mut u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificateExtension_Impl::Value(this) { + Ok(ok__) => { + let (ok_data__, ok_data_len__) = ok__.into_abi(); + result__.write(core::mem::transmute(ok_data__)); + result_size__.write(ok_data_len__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValue(this: *mut core::ffi::c_void, value_array_size: u32, value: *const u8) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICertificateExtension_Impl::SetValue(this, core::slice::from_raw_parts(core::mem::transmute_copy(&value), value_array_size as usize)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ObjectId: ObjectId::, + SetObjectId: SetObjectId::, + IsCritical: IsCritical::, + SetIsCritical: SetIsCritical::, + EncodeValue: EncodeValue::, + Value: Value::, + SetValue: SetValue::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICertificateExtension_Vtbl { @@ -13905,6 +78480,39 @@ windows_core::imp::define_interface!(ICertificateFactory, ICertificateFactory_Vt impl windows_core::RuntimeType for ICertificateFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for ICertificateFactory { + const NAME: &'static str = "Windows.Security.Cryptography.Certificates.ICertificateFactory"; +} +#[cfg(feature = "Storage_Streams")] +pub trait ICertificateFactory_Impl: windows_core::IUnknownImpl { + fn CreateCertificate(&self, certBlob: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl ICertificateFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateCertificate(this: *mut core::ffi::c_void, certblob: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificateFactory_Impl::CreateCertificate(this, core::mem::transmute_copy(&certblob)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateCertificate: CreateCertificate::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICertificateFactory_Vtbl { @@ -13918,6 +78526,197 @@ windows_core::imp::define_interface!(ICertificateKeyUsages, ICertificateKeyUsage impl windows_core::RuntimeType for ICertificateKeyUsages { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ICertificateKeyUsages { + const NAME: &'static str = "Windows.Security.Cryptography.Certificates.ICertificateKeyUsages"; +} +pub trait ICertificateKeyUsages_Impl: windows_core::IUnknownImpl { + fn EncipherOnly(&self) -> windows_core::Result; + fn SetEncipherOnly(&self, value: bool) -> windows_core::Result<()>; + fn CrlSign(&self) -> windows_core::Result; + fn SetCrlSign(&self, value: bool) -> windows_core::Result<()>; + fn KeyCertificateSign(&self) -> windows_core::Result; + fn SetKeyCertificateSign(&self, value: bool) -> windows_core::Result<()>; + fn KeyAgreement(&self) -> windows_core::Result; + fn SetKeyAgreement(&self, value: bool) -> windows_core::Result<()>; + fn DataEncipherment(&self) -> windows_core::Result; + fn SetDataEncipherment(&self, value: bool) -> windows_core::Result<()>; + fn KeyEncipherment(&self) -> windows_core::Result; + fn SetKeyEncipherment(&self, value: bool) -> windows_core::Result<()>; + fn NonRepudiation(&self) -> windows_core::Result; + fn SetNonRepudiation(&self, value: bool) -> windows_core::Result<()>; + fn DigitalSignature(&self) -> windows_core::Result; + fn SetDigitalSignature(&self, value: bool) -> windows_core::Result<()>; +} +impl ICertificateKeyUsages_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn EncipherOnly(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificateKeyUsages_Impl::EncipherOnly(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetEncipherOnly(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICertificateKeyUsages_Impl::SetEncipherOnly(this, value).into() + } + } + unsafe extern "system" fn CrlSign(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificateKeyUsages_Impl::CrlSign(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetCrlSign(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICertificateKeyUsages_Impl::SetCrlSign(this, value).into() + } + } + unsafe extern "system" fn KeyCertificateSign(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificateKeyUsages_Impl::KeyCertificateSign(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetKeyCertificateSign(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICertificateKeyUsages_Impl::SetKeyCertificateSign(this, value).into() + } + } + unsafe extern "system" fn KeyAgreement(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificateKeyUsages_Impl::KeyAgreement(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetKeyAgreement(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICertificateKeyUsages_Impl::SetKeyAgreement(this, value).into() + } + } + unsafe extern "system" fn DataEncipherment(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificateKeyUsages_Impl::DataEncipherment(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDataEncipherment(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICertificateKeyUsages_Impl::SetDataEncipherment(this, value).into() + } + } + unsafe extern "system" fn KeyEncipherment(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificateKeyUsages_Impl::KeyEncipherment(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetKeyEncipherment(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICertificateKeyUsages_Impl::SetKeyEncipherment(this, value).into() + } + } + unsafe extern "system" fn NonRepudiation(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificateKeyUsages_Impl::NonRepudiation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetNonRepudiation(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICertificateKeyUsages_Impl::SetNonRepudiation(this, value).into() + } + } + unsafe extern "system" fn DigitalSignature(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICertificateKeyUsages_Impl::DigitalSignature(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDigitalSignature(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICertificateKeyUsages_Impl::SetDigitalSignature(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + EncipherOnly: EncipherOnly::, + SetEncipherOnly: SetEncipherOnly::, + CrlSign: CrlSign::, + SetCrlSign: SetCrlSign::, + KeyCertificateSign: KeyCertificateSign::, + SetKeyCertificateSign: SetKeyCertificateSign::, + KeyAgreement: KeyAgreement::, + SetKeyAgreement: SetKeyAgreement::, + DataEncipherment: DataEncipherment::, + SetDataEncipherment: SetDataEncipherment::, + KeyEncipherment: KeyEncipherment::, + SetKeyEncipherment: SetKeyEncipherment::, + NonRepudiation: NonRepudiation::, + SetNonRepudiation: SetNonRepudiation::, + DigitalSignature: DigitalSignature::, + SetDigitalSignature: SetDigitalSignature::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ICertificateKeyUsages_Vtbl { @@ -13943,6 +78742,161 @@ windows_core::imp::define_interface!(IChainBuildingParameters, IChainBuildingPar impl windows_core::RuntimeType for IChainBuildingParameters { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IChainBuildingParameters { + const NAME: &'static str = "Windows.Security.Cryptography.Certificates.IChainBuildingParameters"; +} +pub trait IChainBuildingParameters_Impl: windows_core::IUnknownImpl { + fn EnhancedKeyUsages(&self) -> windows_core::Result>; + fn ValidationTimestamp(&self) -> windows_core::Result; + fn SetValidationTimestamp(&self, value: &super::super::super::Foundation::DateTime) -> windows_core::Result<()>; + fn RevocationCheckEnabled(&self) -> windows_core::Result; + fn SetRevocationCheckEnabled(&self, value: bool) -> windows_core::Result<()>; + fn NetworkRetrievalEnabled(&self) -> windows_core::Result; + fn SetNetworkRetrievalEnabled(&self, value: bool) -> windows_core::Result<()>; + fn AuthorityInformationAccessEnabled(&self) -> windows_core::Result; + fn SetAuthorityInformationAccessEnabled(&self, value: bool) -> windows_core::Result<()>; + fn CurrentTimeValidationEnabled(&self) -> windows_core::Result; + fn SetCurrentTimeValidationEnabled(&self, value: bool) -> windows_core::Result<()>; + fn ExclusiveTrustRoots(&self) -> windows_core::Result>; +} +impl IChainBuildingParameters_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn EnhancedKeyUsages(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IChainBuildingParameters_Impl::EnhancedKeyUsages(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ValidationTimestamp(this: *mut core::ffi::c_void, result__: *mut super::super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IChainBuildingParameters_Impl::ValidationTimestamp(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValidationTimestamp(this: *mut core::ffi::c_void, value: super::super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IChainBuildingParameters_Impl::SetValidationTimestamp(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn RevocationCheckEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IChainBuildingParameters_Impl::RevocationCheckEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRevocationCheckEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IChainBuildingParameters_Impl::SetRevocationCheckEnabled(this, value).into() + } + } + unsafe extern "system" fn NetworkRetrievalEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IChainBuildingParameters_Impl::NetworkRetrievalEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetNetworkRetrievalEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IChainBuildingParameters_Impl::SetNetworkRetrievalEnabled(this, value).into() + } + } + unsafe extern "system" fn AuthorityInformationAccessEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IChainBuildingParameters_Impl::AuthorityInformationAccessEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAuthorityInformationAccessEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IChainBuildingParameters_Impl::SetAuthorityInformationAccessEnabled(this, value).into() + } + } + unsafe extern "system" fn CurrentTimeValidationEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IChainBuildingParameters_Impl::CurrentTimeValidationEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetCurrentTimeValidationEnabled(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IChainBuildingParameters_Impl::SetCurrentTimeValidationEnabled(this, value).into() + } + } + unsafe extern "system" fn ExclusiveTrustRoots(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IChainBuildingParameters_Impl::ExclusiveTrustRoots(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + EnhancedKeyUsages: EnhancedKeyUsages::, + ValidationTimestamp: ValidationTimestamp::, + SetValidationTimestamp: SetValidationTimestamp::, + RevocationCheckEnabled: RevocationCheckEnabled::, + SetRevocationCheckEnabled: SetRevocationCheckEnabled::, + NetworkRetrievalEnabled: NetworkRetrievalEnabled::, + SetNetworkRetrievalEnabled: SetNetworkRetrievalEnabled::, + AuthorityInformationAccessEnabled: AuthorityInformationAccessEnabled::, + SetAuthorityInformationAccessEnabled: SetAuthorityInformationAccessEnabled::, + CurrentTimeValidationEnabled: CurrentTimeValidationEnabled::, + SetCurrentTimeValidationEnabled: SetCurrentTimeValidationEnabled::, + ExclusiveTrustRoots: ExclusiveTrustRoots::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IChainBuildingParameters_Vtbl { @@ -13964,6 +78918,69 @@ windows_core::imp::define_interface!(IChainValidationParameters, IChainValidatio impl windows_core::RuntimeType for IChainValidationParameters { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Networking")] +impl windows_core::RuntimeName for IChainValidationParameters { + const NAME: &'static str = "Windows.Security.Cryptography.Certificates.IChainValidationParameters"; +} +#[cfg(feature = "Networking")] +pub trait IChainValidationParameters_Impl: windows_core::IUnknownImpl { + fn CertificateChainPolicy(&self) -> windows_core::Result; + fn SetCertificateChainPolicy(&self, value: CertificateChainPolicy) -> windows_core::Result<()>; + fn ServerDnsName(&self) -> windows_core::Result; + fn SetServerDnsName(&self, value: windows_core::Ref<'_, super::super::super::Networking::HostName>) -> windows_core::Result<()>; +} +#[cfg(feature = "Networking")] +impl IChainValidationParameters_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CertificateChainPolicy(this: *mut core::ffi::c_void, result__: *mut CertificateChainPolicy) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IChainValidationParameters_Impl::CertificateChainPolicy(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetCertificateChainPolicy(this: *mut core::ffi::c_void, value: CertificateChainPolicy) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IChainValidationParameters_Impl::SetCertificateChainPolicy(this, value).into() + } + } + unsafe extern "system" fn ServerDnsName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IChainValidationParameters_Impl::ServerDnsName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetServerDnsName(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IChainValidationParameters_Impl::SetServerDnsName(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CertificateChainPolicy: CertificateChainPolicy::, + SetCertificateChainPolicy: SetCertificateChainPolicy::, + ServerDnsName: ServerDnsName::, + SetServerDnsName: SetServerDnsName::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IChainValidationParameters_Vtbl { @@ -13983,6 +79000,111 @@ windows_core::imp::define_interface!(ISubjectAlternativeNameInfo, ISubjectAltern impl windows_core::RuntimeType for ISubjectAlternativeNameInfo { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISubjectAlternativeNameInfo { + const NAME: &'static str = "Windows.Security.Cryptography.Certificates.ISubjectAlternativeNameInfo"; +} +pub trait ISubjectAlternativeNameInfo_Impl: windows_core::IUnknownImpl { + fn EmailName(&self) -> windows_core::Result>; + fn IPAddress(&self) -> windows_core::Result>; + fn Url(&self) -> windows_core::Result>; + fn DnsName(&self) -> windows_core::Result>; + fn DistinguishedName(&self) -> windows_core::Result>; + fn PrincipalName(&self) -> windows_core::Result>; +} +impl ISubjectAlternativeNameInfo_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn EmailName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISubjectAlternativeNameInfo_Impl::EmailName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IPAddress(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISubjectAlternativeNameInfo_Impl::IPAddress(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Url(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISubjectAlternativeNameInfo_Impl::Url(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DnsName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISubjectAlternativeNameInfo_Impl::DnsName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DistinguishedName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISubjectAlternativeNameInfo_Impl::DistinguishedName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PrincipalName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISubjectAlternativeNameInfo_Impl::PrincipalName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + EmailName: EmailName::, + IPAddress: IPAddress::, + Url: Url::, + DnsName: DnsName::, + DistinguishedName: DistinguishedName::, + PrincipalName: PrincipalName::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISubjectAlternativeNameInfo_Vtbl { @@ -13998,6 +79120,126 @@ windows_core::imp::define_interface!(ISubjectAlternativeNameInfo2, ISubjectAlter impl windows_core::RuntimeType for ISubjectAlternativeNameInfo2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for ISubjectAlternativeNameInfo2 { + const NAME: &'static str = "Windows.Security.Cryptography.Certificates.ISubjectAlternativeNameInfo2"; +} +pub trait ISubjectAlternativeNameInfo2_Impl: windows_core::IUnknownImpl { + fn EmailNames(&self) -> windows_core::Result>; + fn IPAddresses(&self) -> windows_core::Result>; + fn Urls(&self) -> windows_core::Result>; + fn DnsNames(&self) -> windows_core::Result>; + fn DistinguishedNames(&self) -> windows_core::Result>; + fn PrincipalNames(&self) -> windows_core::Result>; + fn Extension(&self) -> windows_core::Result; +} +impl ISubjectAlternativeNameInfo2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn EmailNames(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISubjectAlternativeNameInfo2_Impl::EmailNames(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IPAddresses(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISubjectAlternativeNameInfo2_Impl::IPAddresses(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Urls(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISubjectAlternativeNameInfo2_Impl::Urls(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DnsNames(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISubjectAlternativeNameInfo2_Impl::DnsNames(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DistinguishedNames(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISubjectAlternativeNameInfo2_Impl::DistinguishedNames(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PrincipalNames(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISubjectAlternativeNameInfo2_Impl::PrincipalNames(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Extension(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ISubjectAlternativeNameInfo2_Impl::Extension(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + EmailNames: EmailNames::, + IPAddresses: IPAddresses::, + Urls: Urls::, + DnsNames: DnsNames::, + DistinguishedNames: DistinguishedNames::, + PrincipalNames: PrincipalNames::, + Extension: Extension::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct ISubjectAlternativeNameInfo2_Vtbl { @@ -14022,6 +79264,20 @@ impl SubjectAlternativeNameInfo { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn EmailName(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).EmailName)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IPAddress(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IPAddress)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Url(&self) -> windows_core::Result> { let this = self; unsafe { @@ -14029,7 +79285,77 @@ impl SubjectAlternativeNameInfo { (windows_core::Interface::vtable(this).Url)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn DnsName(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DnsName)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn DistinguishedName(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DistinguishedName)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PrincipalName(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PrincipalName)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn EmailNames(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).EmailNames)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IPAddresses(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IPAddresses)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Urls(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Urls)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DnsNames(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DnsNames)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DistinguishedNames(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DistinguishedNames)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PrincipalNames(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PrincipalNames)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Extension(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Extension)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for SubjectAlternativeNameInfo { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -14045,6 +79371,7 @@ unsafe impl Sync for SubjectAlternativeNameInfo {} } } } +#[cfg(feature = "Storage")] pub mod Storage{ #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -14136,6 +79463,164 @@ windows_core::imp::interface_hierarchy!(IStorageFile, windows_core::IUnknown, wi windows_core::imp::required_hierarchy!(IStorageFile, Streams::IInputStreamReference, Streams::IRandomAccessStreamReference, IStorageItem); #[cfg(feature = "Storage_Streams")] impl IStorageFile { + pub fn FileType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FileType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn ContentType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn OpenAsync(&self, accessmode: FileAccessMode) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenAsync)(windows_core::Interface::as_raw(this), accessmode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn OpenTransactedWriteAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenTransactedWriteAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CopyOverloadDefaultNameAndOptions(&self, destinationfolder: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CopyOverloadDefaultNameAndOptions)(windows_core::Interface::as_raw(this), destinationfolder.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CopyOverloadDefaultOptions(&self, destinationfolder: P0, desirednewname: &windows_core::HSTRING) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CopyOverloadDefaultOptions)(windows_core::Interface::as_raw(this), destinationfolder.param().abi(), core::mem::transmute_copy(desirednewname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CopyOverload(&self, destinationfolder: P0, desirednewname: &windows_core::HSTRING, option: NameCollisionOption) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CopyOverload)(windows_core::Interface::as_raw(this), destinationfolder.param().abi(), core::mem::transmute_copy(desirednewname), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CopyAndReplaceAsync(&self, filetoreplace: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CopyAndReplaceAsync)(windows_core::Interface::as_raw(this), filetoreplace.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MoveOverloadDefaultNameAndOptions(&self, destinationfolder: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MoveOverloadDefaultNameAndOptions)(windows_core::Interface::as_raw(this), destinationfolder.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MoveOverloadDefaultOptions(&self, destinationfolder: P0, desirednewname: &windows_core::HSTRING) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MoveOverloadDefaultOptions)(windows_core::Interface::as_raw(this), destinationfolder.param().abi(), core::mem::transmute_copy(desirednewname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MoveOverload(&self, destinationfolder: P0, desirednewname: &windows_core::HSTRING, option: NameCollisionOption) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MoveOverload)(windows_core::Interface::as_raw(this), destinationfolder.param().abi(), core::mem::transmute_copy(desirednewname), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MoveAndReplaceAsync(&self, filetoreplace: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MoveAndReplaceAsync)(windows_core::Interface::as_raw(this), filetoreplace.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn OpenSequentialReadAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenSequentialReadAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn OpenReadAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenReadAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RenameAsyncOverloadDefaultOptions(&self, desiredname: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RenameAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RenameAsync(&self, desiredname: &windows_core::HSTRING, option: NameCollisionOption) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RenameAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeleteAsyncOverloadDefaultOptions(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeleteAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeleteAsync(&self, option: StorageDeleteOption) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeleteAsync)(windows_core::Interface::as_raw(this), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn GetBasicPropertiesAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetBasicPropertiesAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Name(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; unsafe { @@ -14143,7 +79628,233 @@ impl IStorageFile { (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn Path(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Path)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } } + pub fn Attributes(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Attributes)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DateCreated(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DateCreated)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsOfType(&self, r#type: StorageItemTypes) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsOfType)(windows_core::Interface::as_raw(this), r#type, &mut result__).map(|| result__) + } + } +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IStorageFile { + const NAME: &'static str = "Windows.Storage.IStorageFile"; +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] +pub trait IStorageFile_Impl: Streams::IInputStreamReference_Impl + Streams::IRandomAccessStreamReference_Impl + IStorageItem_Impl { + fn FileType(&self) -> windows_core::Result; + fn ContentType(&self) -> windows_core::Result; + fn OpenAsync(&self, accessMode: FileAccessMode) -> windows_core::Result>; + fn OpenTransactedWriteAsync(&self) -> windows_core::Result>; + fn CopyOverloadDefaultNameAndOptions(&self, destinationFolder: windows_core::Ref<'_, IStorageFolder>) -> windows_core::Result>; + fn CopyOverloadDefaultOptions(&self, destinationFolder: windows_core::Ref<'_, IStorageFolder>, desiredNewName: &windows_core::HSTRING) -> windows_core::Result>; + fn CopyOverload(&self, destinationFolder: windows_core::Ref<'_, IStorageFolder>, desiredNewName: &windows_core::HSTRING, option: NameCollisionOption) -> windows_core::Result>; + fn CopyAndReplaceAsync(&self, fileToReplace: windows_core::Ref<'_, IStorageFile>) -> windows_core::Result; + fn MoveOverloadDefaultNameAndOptions(&self, destinationFolder: windows_core::Ref<'_, IStorageFolder>) -> windows_core::Result; + fn MoveOverloadDefaultOptions(&self, destinationFolder: windows_core::Ref<'_, IStorageFolder>, desiredNewName: &windows_core::HSTRING) -> windows_core::Result; + fn MoveOverload(&self, destinationFolder: windows_core::Ref<'_, IStorageFolder>, desiredNewName: &windows_core::HSTRING, option: NameCollisionOption) -> windows_core::Result; + fn MoveAndReplaceAsync(&self, fileToReplace: windows_core::Ref<'_, IStorageFile>) -> windows_core::Result; +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl IStorageFile_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FileType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFile_Impl::FileType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ContentType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFile_Impl::ContentType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OpenAsync(this: *mut core::ffi::c_void, accessmode: FileAccessMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFile_Impl::OpenAsync(this, accessmode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OpenTransactedWriteAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFile_Impl::OpenTransactedWriteAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CopyOverloadDefaultNameAndOptions(this: *mut core::ffi::c_void, destinationfolder: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFile_Impl::CopyOverloadDefaultNameAndOptions(this, core::mem::transmute_copy(&destinationfolder)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CopyOverloadDefaultOptions(this: *mut core::ffi::c_void, destinationfolder: *mut core::ffi::c_void, desirednewname: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFile_Impl::CopyOverloadDefaultOptions(this, core::mem::transmute_copy(&destinationfolder), core::mem::transmute(&desirednewname)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CopyOverload(this: *mut core::ffi::c_void, destinationfolder: *mut core::ffi::c_void, desirednewname: *mut core::ffi::c_void, option: NameCollisionOption, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFile_Impl::CopyOverload(this, core::mem::transmute_copy(&destinationfolder), core::mem::transmute(&desirednewname), option) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CopyAndReplaceAsync(this: *mut core::ffi::c_void, filetoreplace: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFile_Impl::CopyAndReplaceAsync(this, core::mem::transmute_copy(&filetoreplace)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MoveOverloadDefaultNameAndOptions(this: *mut core::ffi::c_void, destinationfolder: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFile_Impl::MoveOverloadDefaultNameAndOptions(this, core::mem::transmute_copy(&destinationfolder)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MoveOverloadDefaultOptions(this: *mut core::ffi::c_void, destinationfolder: *mut core::ffi::c_void, desirednewname: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFile_Impl::MoveOverloadDefaultOptions(this, core::mem::transmute_copy(&destinationfolder), core::mem::transmute(&desirednewname)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MoveOverload(this: *mut core::ffi::c_void, destinationfolder: *mut core::ffi::c_void, desirednewname: *mut core::ffi::c_void, option: NameCollisionOption, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFile_Impl::MoveOverload(this, core::mem::transmute_copy(&destinationfolder), core::mem::transmute(&desirednewname), option) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn MoveAndReplaceAsync(this: *mut core::ffi::c_void, filetoreplace: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFile_Impl::MoveAndReplaceAsync(this, core::mem::transmute_copy(&filetoreplace)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FileType: FileType::, + ContentType: ContentType::, + OpenAsync: OpenAsync::, + OpenTransactedWriteAsync: OpenTransactedWriteAsync::, + CopyOverloadDefaultNameAndOptions: CopyOverloadDefaultNameAndOptions::, + CopyOverloadDefaultOptions: CopyOverloadDefaultOptions::, + CopyOverload: CopyOverload::, + CopyAndReplaceAsync: CopyAndReplaceAsync::, + MoveOverloadDefaultNameAndOptions: MoveOverloadDefaultNameAndOptions::, + MoveOverloadDefaultOptions: MoveOverloadDefaultOptions::, + MoveOverload: MoveOverload::, + MoveAndReplaceAsync: MoveAndReplaceAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[cfg(feature = "Storage_Streams")] #[repr(C)] #[doc(hidden)] @@ -14167,6 +79878,23 @@ impl windows_core::RuntimeType for IStorageFile2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } windows_core::imp::interface_hierarchy!(IStorageFile2, windows_core::IUnknown, windows_core::IInspectable); +impl IStorageFile2 { + #[cfg(feature = "Storage_Streams")] + pub fn OpenWithOptionsAsync(&self, accessmode: FileAccessMode, options: StorageOpenOptions) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenWithOptionsAsync)(windows_core::Interface::as_raw(this), accessmode, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn OpenTransactedWriteWithOptionsAsync(&self, options: StorageOpenOptions) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenTransactedWriteWithOptionsAsync)(windows_core::Interface::as_raw(this), options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[cfg(feature = "Storage_Streams")] impl windows_core::RuntimeName for IStorageFile2 { const NAME: &'static str = "Windows.Storage.IStorageFile2"; @@ -14230,6 +79958,15 @@ impl windows_core::RuntimeType for IStorageFilePropertiesWithAvailability { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } windows_core::imp::interface_hierarchy!(IStorageFilePropertiesWithAvailability, windows_core::IUnknown, windows_core::IInspectable); +impl IStorageFilePropertiesWithAvailability { + pub fn IsAvailable(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsAvailable)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeName for IStorageFilePropertiesWithAvailability { const NAME: &'static str = "Windows.Storage.IStorageFilePropertiesWithAvailability"; } @@ -14269,6 +80006,114 @@ windows_core::imp::define_interface!(IStorageFileStatics, IStorageFileStatics_Vt impl windows_core::RuntimeType for IStorageFileStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IStorageFileStatics { + const NAME: &'static str = "Windows.Storage.IStorageFileStatics"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IStorageFileStatics_Impl: windows_core::IUnknownImpl { + fn GetFileFromPathAsync(&self, path: &windows_core::HSTRING) -> windows_core::Result>; + fn GetFileFromApplicationUriAsync(&self, uri: windows_core::Ref<'_, super::Foundation::Uri>) -> windows_core::Result>; + fn CreateStreamedFileAsync(&self, displayNameWithExtension: &windows_core::HSTRING, dataRequested: windows_core::Ref<'_, StreamedFileDataRequestedHandler>, thumbnail: windows_core::Ref<'_, Streams::IRandomAccessStreamReference>) -> windows_core::Result>; + fn ReplaceWithStreamedFileAsync(&self, fileToReplace: windows_core::Ref<'_, IStorageFile>, dataRequested: windows_core::Ref<'_, StreamedFileDataRequestedHandler>, thumbnail: windows_core::Ref<'_, Streams::IRandomAccessStreamReference>) -> windows_core::Result>; + fn CreateStreamedFileFromUriAsync(&self, displayNameWithExtension: &windows_core::HSTRING, uri: windows_core::Ref<'_, super::Foundation::Uri>, thumbnail: windows_core::Ref<'_, Streams::IRandomAccessStreamReference>) -> windows_core::Result>; + fn ReplaceWithStreamedFileFromUriAsync(&self, fileToReplace: windows_core::Ref<'_, IStorageFile>, uri: windows_core::Ref<'_, super::Foundation::Uri>, thumbnail: windows_core::Ref<'_, Streams::IRandomAccessStreamReference>) -> windows_core::Result>; +} +#[cfg(feature = "Storage_Streams")] +impl IStorageFileStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetFileFromPathAsync(this: *mut core::ffi::c_void, path: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFileStatics_Impl::GetFileFromPathAsync(this, core::mem::transmute(&path)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetFileFromApplicationUriAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFileStatics_Impl::GetFileFromApplicationUriAsync(this, core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateStreamedFileAsync(this: *mut core::ffi::c_void, displaynamewithextension: *mut core::ffi::c_void, datarequested: *mut core::ffi::c_void, thumbnail: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFileStatics_Impl::CreateStreamedFileAsync(this, core::mem::transmute(&displaynamewithextension), core::mem::transmute_copy(&datarequested), core::mem::transmute_copy(&thumbnail)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReplaceWithStreamedFileAsync(this: *mut core::ffi::c_void, filetoreplace: *mut core::ffi::c_void, datarequested: *mut core::ffi::c_void, thumbnail: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFileStatics_Impl::ReplaceWithStreamedFileAsync(this, core::mem::transmute_copy(&filetoreplace), core::mem::transmute_copy(&datarequested), core::mem::transmute_copy(&thumbnail)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateStreamedFileFromUriAsync(this: *mut core::ffi::c_void, displaynamewithextension: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, thumbnail: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFileStatics_Impl::CreateStreamedFileFromUriAsync(this, core::mem::transmute(&displaynamewithextension), core::mem::transmute_copy(&uri), core::mem::transmute_copy(&thumbnail)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReplaceWithStreamedFileFromUriAsync(this: *mut core::ffi::c_void, filetoreplace: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, thumbnail: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFileStatics_Impl::ReplaceWithStreamedFileFromUriAsync(this, core::mem::transmute_copy(&filetoreplace), core::mem::transmute_copy(&uri), core::mem::transmute_copy(&thumbnail)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetFileFromPathAsync: GetFileFromPathAsync::, + GetFileFromApplicationUriAsync: GetFileFromApplicationUriAsync::, + CreateStreamedFileAsync: CreateStreamedFileAsync::, + ReplaceWithStreamedFileAsync: ReplaceWithStreamedFileAsync::, + CreateStreamedFileFromUriAsync: CreateStreamedFileFromUriAsync::, + ReplaceWithStreamedFileFromUriAsync: ReplaceWithStreamedFileFromUriAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageFileStatics_Vtbl { @@ -14302,6 +80147,39 @@ windows_core::imp::define_interface!(IStorageFileStatics2, IStorageFileStatics2_ impl windows_core::RuntimeType for IStorageFileStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(all(feature = "Storage_Streams", feature = "System"))] +impl windows_core::RuntimeName for IStorageFileStatics2 { + const NAME: &'static str = "Windows.Storage.IStorageFileStatics2"; +} +#[cfg(all(feature = "Storage_Streams", feature = "System"))] +pub trait IStorageFileStatics2_Impl: windows_core::IUnknownImpl { + fn GetFileFromPathForUserAsync(&self, user: windows_core::Ref<'_, super::System::User>, path: &windows_core::HSTRING) -> windows_core::Result>; +} +#[cfg(all(feature = "Storage_Streams", feature = "System"))] +impl IStorageFileStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetFileFromPathForUserAsync(this: *mut core::ffi::c_void, user: *mut core::ffi::c_void, path: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFileStatics2_Impl::GetFileFromPathForUserAsync(this, core::mem::transmute_copy(&user), core::mem::transmute(&path)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetFileFromPathForUserAsync: GetFileFromPathForUserAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageFileStatics2_Vtbl { @@ -14318,6 +80196,120 @@ impl windows_core::RuntimeType for IStorageFolder { windows_core::imp::interface_hierarchy!(IStorageFolder, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(IStorageFolder, IStorageItem); impl IStorageFolder { + #[cfg(feature = "Storage_Streams")] + pub fn CreateFileAsyncOverloadDefaultOptions(&self, desiredname: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFileAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFileAsync(&self, desiredname: &windows_core::HSTRING, options: CreationCollisionOption) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFileAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Search")] + pub fn CreateFolderAsyncOverloadDefaultOptions(&self, desiredname: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFolderAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Search")] + pub fn CreateFolderAsync(&self, desiredname: &windows_core::HSTRING, options: CreationCollisionOption) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFolderAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetFileAsync(&self, name: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFileAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Search")] + pub fn GetFolderAsync(&self, name: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFolderAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetItemAsync(&self, name: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetItemAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetFilesAsyncOverloadDefaultOptionsStartAndCount(&self) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFilesAsyncOverloadDefaultOptionsStartAndCount)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Search")] + pub fn GetFoldersAsyncOverloadDefaultOptionsStartAndCount(&self) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFoldersAsyncOverloadDefaultOptionsStartAndCount)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetItemsAsyncOverloadDefaultStartAndCount(&self) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetItemsAsyncOverloadDefaultStartAndCount)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RenameAsyncOverloadDefaultOptions(&self, desiredname: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RenameAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RenameAsync(&self, desiredname: &windows_core::HSTRING, option: NameCollisionOption) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RenameAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeleteAsyncOverloadDefaultOptions(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeleteAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeleteAsync(&self, option: StorageDeleteOption) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeleteAsync)(windows_core::Interface::as_raw(this), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn GetBasicPropertiesAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetBasicPropertiesAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Name(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; unsafe { @@ -14325,7 +80317,203 @@ impl IStorageFolder { (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn Path(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Path)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } } + pub fn Attributes(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Attributes)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DateCreated(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DateCreated)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsOfType(&self, r#type: StorageItemTypes) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsOfType)(windows_core::Interface::as_raw(this), r#type, &mut result__).map(|| result__) + } + } +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Search", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IStorageFolder { + const NAME: &'static str = "Windows.Storage.IStorageFolder"; +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Search", feature = "Storage_Streams"))] +pub trait IStorageFolder_Impl: IStorageItem_Impl { + fn CreateFileAsyncOverloadDefaultOptions(&self, desiredName: &windows_core::HSTRING) -> windows_core::Result>; + fn CreateFileAsync(&self, desiredName: &windows_core::HSTRING, options: CreationCollisionOption) -> windows_core::Result>; + fn CreateFolderAsyncOverloadDefaultOptions(&self, desiredName: &windows_core::HSTRING) -> windows_core::Result>; + fn CreateFolderAsync(&self, desiredName: &windows_core::HSTRING, options: CreationCollisionOption) -> windows_core::Result>; + fn GetFileAsync(&self, name: &windows_core::HSTRING) -> windows_core::Result>; + fn GetFolderAsync(&self, name: &windows_core::HSTRING) -> windows_core::Result>; + fn GetItemAsync(&self, name: &windows_core::HSTRING) -> windows_core::Result>; + fn GetFilesAsyncOverloadDefaultOptionsStartAndCount(&self) -> windows_core::Result>>; + fn GetFoldersAsyncOverloadDefaultOptionsStartAndCount(&self) -> windows_core::Result>>; + fn GetItemsAsyncOverloadDefaultStartAndCount(&self) -> windows_core::Result>>; +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Search", feature = "Storage_Streams"))] +impl IStorageFolder_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFileAsyncOverloadDefaultOptions(this: *mut core::ffi::c_void, desiredname: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolder_Impl::CreateFileAsyncOverloadDefaultOptions(this, core::mem::transmute(&desiredname)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFileAsync(this: *mut core::ffi::c_void, desiredname: *mut core::ffi::c_void, options: CreationCollisionOption, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolder_Impl::CreateFileAsync(this, core::mem::transmute(&desiredname), options) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFolderAsyncOverloadDefaultOptions(this: *mut core::ffi::c_void, desiredname: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolder_Impl::CreateFolderAsyncOverloadDefaultOptions(this, core::mem::transmute(&desiredname)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFolderAsync(this: *mut core::ffi::c_void, desiredname: *mut core::ffi::c_void, options: CreationCollisionOption, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolder_Impl::CreateFolderAsync(this, core::mem::transmute(&desiredname), options) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetFileAsync(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolder_Impl::GetFileAsync(this, core::mem::transmute(&name)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetFolderAsync(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolder_Impl::GetFolderAsync(this, core::mem::transmute(&name)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetItemAsync(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolder_Impl::GetItemAsync(this, core::mem::transmute(&name)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetFilesAsyncOverloadDefaultOptionsStartAndCount(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolder_Impl::GetFilesAsyncOverloadDefaultOptionsStartAndCount(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetFoldersAsyncOverloadDefaultOptionsStartAndCount(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolder_Impl::GetFoldersAsyncOverloadDefaultOptionsStartAndCount(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetItemsAsyncOverloadDefaultStartAndCount(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolder_Impl::GetItemsAsyncOverloadDefaultStartAndCount(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFileAsyncOverloadDefaultOptions: CreateFileAsyncOverloadDefaultOptions::, + CreateFileAsync: CreateFileAsync::, + CreateFolderAsyncOverloadDefaultOptions: CreateFolderAsyncOverloadDefaultOptions::, + CreateFolderAsync: CreateFolderAsync::, + GetFileAsync: GetFileAsync::, + GetFolderAsync: GetFolderAsync::, + GetItemAsync: GetItemAsync::, + GetFilesAsyncOverloadDefaultOptionsStartAndCount: GetFilesAsyncOverloadDefaultOptionsStartAndCount::, + GetFoldersAsyncOverloadDefaultOptionsStartAndCount: GetFoldersAsyncOverloadDefaultOptionsStartAndCount::, + GetItemsAsyncOverloadDefaultStartAndCount: GetItemsAsyncOverloadDefaultStartAndCount::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageFolder_Vtbl { @@ -14365,12 +80553,227 @@ pub struct IStorageFolder_Vtbl { GetFoldersAsyncOverloadDefaultOptionsStartAndCount: usize, pub GetItemsAsyncOverloadDefaultStartAndCount: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, } +windows_core::imp::define_interface!(IStorageFolder2, IStorageFolder2_Vtbl, 0xe827e8b9_08d9_4a8e_a0ac_fe5ed3cbbbd3); +impl windows_core::RuntimeType for IStorageFolder2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IStorageFolder2, windows_core::IUnknown, windows_core::IInspectable); +impl IStorageFolder2 { + pub fn TryGetItemAsync(&self, name: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryGetItemAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeName for IStorageFolder2 { + const NAME: &'static str = "Windows.Storage.IStorageFolder2"; +} +pub trait IStorageFolder2_Impl: windows_core::IUnknownImpl { + fn TryGetItemAsync(&self, name: &windows_core::HSTRING) -> windows_core::Result>; +} +impl IStorageFolder2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TryGetItemAsync(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolder2_Impl::TryGetItemAsync(this, core::mem::transmute(&name)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), TryGetItemAsync: TryGetItemAsync:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IStorageFolder2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub TryGetItemAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IStorageFolder3, IStorageFolder3_Vtbl, 0x9f617899_bde1_4124_aeb3_b06ad96f98d4); +impl windows_core::RuntimeType for IStorageFolder3 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IStorageFolder3 { + const NAME: &'static str = "Windows.Storage.IStorageFolder3"; +} +pub trait IStorageFolder3_Impl: windows_core::IUnknownImpl { + fn TryGetChangeTracker(&self) -> windows_core::Result; +} +impl IStorageFolder3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TryGetChangeTracker(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolder3_Impl::TryGetChangeTracker(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + TryGetChangeTracker: TryGetChangeTracker::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IStorageFolder3_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub TryGetChangeTracker: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IStorageFolderStatics, IStorageFolderStatics_Vtbl, 0x08f327ff_85d5_48b9_aee9_28511e339f9f); +impl windows_core::RuntimeType for IStorageFolderStatics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_Search")] +impl windows_core::RuntimeName for IStorageFolderStatics { + const NAME: &'static str = "Windows.Storage.IStorageFolderStatics"; +} +#[cfg(feature = "Storage_Search")] +pub trait IStorageFolderStatics_Impl: windows_core::IUnknownImpl { + fn GetFolderFromPathAsync(&self, path: &windows_core::HSTRING) -> windows_core::Result>; +} +#[cfg(feature = "Storage_Search")] +impl IStorageFolderStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetFolderFromPathAsync(this: *mut core::ffi::c_void, path: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderStatics_Impl::GetFolderFromPathAsync(this, core::mem::transmute(&path)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetFolderFromPathAsync: GetFolderFromPathAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IStorageFolderStatics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Storage_Search")] + pub GetFolderFromPathAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Search"))] + GetFolderFromPathAsync: usize, +} +windows_core::imp::define_interface!(IStorageFolderStatics2, IStorageFolderStatics2_Vtbl, 0xb4656dc3_71d2_467d_8b29_371f0f62bf6f); +impl windows_core::RuntimeType for IStorageFolderStatics2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Storage_Search", feature = "System"))] +impl windows_core::RuntimeName for IStorageFolderStatics2 { + const NAME: &'static str = "Windows.Storage.IStorageFolderStatics2"; +} +#[cfg(all(feature = "Storage_Search", feature = "System"))] +pub trait IStorageFolderStatics2_Impl: windows_core::IUnknownImpl { + fn GetFolderFromPathForUserAsync(&self, user: windows_core::Ref<'_, super::System::User>, path: &windows_core::HSTRING) -> windows_core::Result>; +} +#[cfg(all(feature = "Storage_Search", feature = "System"))] +impl IStorageFolderStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetFolderFromPathForUserAsync(this: *mut core::ffi::c_void, user: *mut core::ffi::c_void, path: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderStatics2_Impl::GetFolderFromPathForUserAsync(this, core::mem::transmute_copy(&user), core::mem::transmute(&path)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetFolderFromPathForUserAsync: GetFolderFromPathForUserAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IStorageFolderStatics2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(all(feature = "Storage_Search", feature = "System"))] + pub GetFolderFromPathForUserAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Storage_Search", feature = "System")))] + GetFolderFromPathForUserAsync: usize, +} windows_core::imp::define_interface!(IStorageItem, IStorageItem_Vtbl, 0x4207a996_ca2f_42f7_bde8_8b10457a7f30); impl windows_core::RuntimeType for IStorageItem { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } windows_core::imp::interface_hierarchy!(IStorageItem, windows_core::IUnknown, windows_core::IInspectable); impl IStorageItem { + pub fn RenameAsyncOverloadDefaultOptions(&self, desiredname: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RenameAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RenameAsync(&self, desiredname: &windows_core::HSTRING, option: NameCollisionOption) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RenameAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeleteAsyncOverloadDefaultOptions(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeleteAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeleteAsync(&self, option: StorageDeleteOption) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeleteAsync)(windows_core::Interface::as_raw(this), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn GetBasicPropertiesAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetBasicPropertiesAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Name(&self) -> windows_core::Result { let this = self; unsafe { @@ -14378,7 +80781,200 @@ impl IStorageItem { (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn Path(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Path)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } } + pub fn Attributes(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Attributes)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DateCreated(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DateCreated)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsOfType(&self, r#type: StorageItemTypes) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsOfType)(windows_core::Interface::as_raw(this), r#type, &mut result__).map(|| result__) + } + } +} +#[cfg(feature = "Storage_FileProperties")] +impl windows_core::RuntimeName for IStorageItem { + const NAME: &'static str = "Windows.Storage.IStorageItem"; +} +#[cfg(feature = "Storage_FileProperties")] +pub trait IStorageItem_Impl: windows_core::IUnknownImpl { + fn RenameAsyncOverloadDefaultOptions(&self, desiredName: &windows_core::HSTRING) -> windows_core::Result; + fn RenameAsync(&self, desiredName: &windows_core::HSTRING, option: NameCollisionOption) -> windows_core::Result; + fn DeleteAsyncOverloadDefaultOptions(&self) -> windows_core::Result; + fn DeleteAsync(&self, option: StorageDeleteOption) -> windows_core::Result; + fn GetBasicPropertiesAsync(&self) -> windows_core::Result>; + fn Name(&self) -> windows_core::Result; + fn Path(&self) -> windows_core::Result; + fn Attributes(&self) -> windows_core::Result; + fn DateCreated(&self) -> windows_core::Result; + fn IsOfType(&self, r#type: StorageItemTypes) -> windows_core::Result; +} +#[cfg(feature = "Storage_FileProperties")] +impl IStorageItem_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn RenameAsyncOverloadDefaultOptions(this: *mut core::ffi::c_void, desiredname: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItem_Impl::RenameAsyncOverloadDefaultOptions(this, core::mem::transmute(&desiredname)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RenameAsync(this: *mut core::ffi::c_void, desiredname: *mut core::ffi::c_void, option: NameCollisionOption, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItem_Impl::RenameAsync(this, core::mem::transmute(&desiredname), option) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DeleteAsyncOverloadDefaultOptions(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItem_Impl::DeleteAsyncOverloadDefaultOptions(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DeleteAsync(this: *mut core::ffi::c_void, option: StorageDeleteOption, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItem_Impl::DeleteAsync(this, option) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetBasicPropertiesAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItem_Impl::GetBasicPropertiesAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Name(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItem_Impl::Name(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Path(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItem_Impl::Path(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Attributes(this: *mut core::ffi::c_void, result__: *mut FileAttributes) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItem_Impl::Attributes(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DateCreated(this: *mut core::ffi::c_void, result__: *mut super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItem_Impl::DateCreated(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsOfType(this: *mut core::ffi::c_void, r#type: StorageItemTypes, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItem_Impl::IsOfType(this, r#type) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + RenameAsyncOverloadDefaultOptions: RenameAsyncOverloadDefaultOptions::, + RenameAsync: RenameAsync::, + DeleteAsyncOverloadDefaultOptions: DeleteAsyncOverloadDefaultOptions::, + DeleteAsync: DeleteAsync::, + GetBasicPropertiesAsync: GetBasicPropertiesAsync::, + Name: Name::, + Path: Path::, + Attributes: Attributes::, + DateCreated: DateCreated::, + IsOfType: IsOfType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageItem_Vtbl { @@ -14404,6 +81000,60 @@ impl windows_core::RuntimeType for IStorageItem2 { windows_core::imp::interface_hierarchy!(IStorageItem2, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(IStorageItem2, IStorageItem); impl IStorageItem2 { + #[cfg(feature = "Storage_Search")] + pub fn GetParentAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetParentAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IsEqual(&self, item: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsEqual)(windows_core::Interface::as_raw(this), item.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RenameAsyncOverloadDefaultOptions(&self, desiredname: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RenameAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RenameAsync(&self, desiredname: &windows_core::HSTRING, option: NameCollisionOption) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RenameAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeleteAsyncOverloadDefaultOptions(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeleteAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeleteAsync(&self, option: StorageDeleteOption) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeleteAsync)(windows_core::Interface::as_raw(this), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn GetBasicPropertiesAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetBasicPropertiesAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Name(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; unsafe { @@ -14411,7 +81061,82 @@ impl IStorageItem2 { (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn Path(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Path)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } } + pub fn Attributes(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Attributes)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DateCreated(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DateCreated)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsOfType(&self, r#type: StorageItemTypes) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsOfType)(windows_core::Interface::as_raw(this), r#type, &mut result__).map(|| result__) + } + } +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Search"))] +impl windows_core::RuntimeName for IStorageItem2 { + const NAME: &'static str = "Windows.Storage.IStorageItem2"; +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Search"))] +pub trait IStorageItem2_Impl: IStorageItem_Impl { + fn GetParentAsync(&self) -> windows_core::Result>; + fn IsEqual(&self, item: windows_core::Ref<'_, IStorageItem>) -> windows_core::Result; +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Search"))] +impl IStorageItem2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetParentAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItem2_Impl::GetParentAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsEqual(this: *mut core::ffi::c_void, item: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItem2_Impl::IsEqual(this, core::mem::transmute_copy(&item)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetParentAsync: GetParentAsync::, + IsEqual: IsEqual::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageItem2_Vtbl { @@ -14427,6 +81152,184 @@ impl windows_core::RuntimeType for IStorageItemProperties { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } windows_core::imp::interface_hierarchy!(IStorageItemProperties, windows_core::IUnknown, windows_core::IInspectable); +impl IStorageItemProperties { + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetThumbnailAsyncOverloadDefaultSizeDefaultOptions(&self, mode: FileProperties::ThumbnailMode) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsyncOverloadDefaultSizeDefaultOptions)(windows_core::Interface::as_raw(this), mode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetThumbnailAsyncOverloadDefaultOptions(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), mode, requestedsize, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetThumbnailAsync(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32, options: FileProperties::ThumbnailOptions) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsync)(windows_core::Interface::as_raw(this), mode, requestedsize, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DisplayName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn DisplayType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn FolderRelativeId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FolderRelativeId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn Properties(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IStorageItemProperties { + const NAME: &'static str = "Windows.Storage.IStorageItemProperties"; +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] +pub trait IStorageItemProperties_Impl: windows_core::IUnknownImpl { + fn GetThumbnailAsyncOverloadDefaultSizeDefaultOptions(&self, mode: FileProperties::ThumbnailMode) -> windows_core::Result>; + fn GetThumbnailAsyncOverloadDefaultOptions(&self, mode: FileProperties::ThumbnailMode, requestedSize: u32) -> windows_core::Result>; + fn GetThumbnailAsync(&self, mode: FileProperties::ThumbnailMode, requestedSize: u32, options: FileProperties::ThumbnailOptions) -> windows_core::Result>; + fn DisplayName(&self) -> windows_core::Result; + fn DisplayType(&self) -> windows_core::Result; + fn FolderRelativeId(&self) -> windows_core::Result; + fn Properties(&self) -> windows_core::Result; +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl IStorageItemProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetThumbnailAsyncOverloadDefaultSizeDefaultOptions(this: *mut core::ffi::c_void, mode: FileProperties::ThumbnailMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemProperties_Impl::GetThumbnailAsyncOverloadDefaultSizeDefaultOptions(this, mode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetThumbnailAsyncOverloadDefaultOptions(this: *mut core::ffi::c_void, mode: FileProperties::ThumbnailMode, requestedsize: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemProperties_Impl::GetThumbnailAsyncOverloadDefaultOptions(this, mode, requestedsize) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetThumbnailAsync(this: *mut core::ffi::c_void, mode: FileProperties::ThumbnailMode, requestedsize: u32, options: FileProperties::ThumbnailOptions, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemProperties_Impl::GetThumbnailAsync(this, mode, requestedsize, options) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DisplayName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemProperties_Impl::DisplayName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DisplayType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemProperties_Impl::DisplayType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FolderRelativeId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemProperties_Impl::FolderRelativeId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemProperties_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetThumbnailAsyncOverloadDefaultSizeDefaultOptions: GetThumbnailAsyncOverloadDefaultSizeDefaultOptions::, + GetThumbnailAsyncOverloadDefaultOptions: GetThumbnailAsyncOverloadDefaultOptions::, + GetThumbnailAsync: GetThumbnailAsync::, + DisplayName: DisplayName::, + DisplayType: DisplayType::, + FolderRelativeId: FolderRelativeId::, + Properties: Properties::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageItemProperties_Vtbl { @@ -14457,6 +81360,148 @@ impl windows_core::RuntimeType for IStorageItemProperties2 { } windows_core::imp::interface_hierarchy!(IStorageItemProperties2, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(IStorageItemProperties2, IStorageItemProperties); +impl IStorageItemProperties2 { + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetScaledImageAsThumbnailAsyncOverloadDefaultSizeDefaultOptions(&self, mode: FileProperties::ThumbnailMode) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetScaledImageAsThumbnailAsyncOverloadDefaultSizeDefaultOptions)(windows_core::Interface::as_raw(this), mode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetScaledImageAsThumbnailAsyncOverloadDefaultOptions(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetScaledImageAsThumbnailAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), mode, requestedsize, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetScaledImageAsThumbnailAsync(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32, options: FileProperties::ThumbnailOptions) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetScaledImageAsThumbnailAsync)(windows_core::Interface::as_raw(this), mode, requestedsize, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetThumbnailAsyncOverloadDefaultSizeDefaultOptions(&self, mode: FileProperties::ThumbnailMode) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsyncOverloadDefaultSizeDefaultOptions)(windows_core::Interface::as_raw(this), mode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetThumbnailAsyncOverloadDefaultOptions(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), mode, requestedsize, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetThumbnailAsync(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32, options: FileProperties::ThumbnailOptions) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsync)(windows_core::Interface::as_raw(this), mode, requestedsize, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DisplayName(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn DisplayType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn FolderRelativeId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FolderRelativeId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn Properties(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IStorageItemProperties2 { + const NAME: &'static str = "Windows.Storage.IStorageItemProperties2"; +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] +pub trait IStorageItemProperties2_Impl: IStorageItemProperties_Impl { + fn GetScaledImageAsThumbnailAsyncOverloadDefaultSizeDefaultOptions(&self, mode: FileProperties::ThumbnailMode) -> windows_core::Result>; + fn GetScaledImageAsThumbnailAsyncOverloadDefaultOptions(&self, mode: FileProperties::ThumbnailMode, requestedSize: u32) -> windows_core::Result>; + fn GetScaledImageAsThumbnailAsync(&self, mode: FileProperties::ThumbnailMode, requestedSize: u32, options: FileProperties::ThumbnailOptions) -> windows_core::Result>; +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl IStorageItemProperties2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetScaledImageAsThumbnailAsyncOverloadDefaultSizeDefaultOptions(this: *mut core::ffi::c_void, mode: FileProperties::ThumbnailMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemProperties2_Impl::GetScaledImageAsThumbnailAsyncOverloadDefaultSizeDefaultOptions(this, mode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetScaledImageAsThumbnailAsyncOverloadDefaultOptions(this: *mut core::ffi::c_void, mode: FileProperties::ThumbnailMode, requestedsize: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemProperties2_Impl::GetScaledImageAsThumbnailAsyncOverloadDefaultOptions(this, mode, requestedsize) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetScaledImageAsThumbnailAsync(this: *mut core::ffi::c_void, mode: FileProperties::ThumbnailMode, requestedsize: u32, options: FileProperties::ThumbnailOptions, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemProperties2_Impl::GetScaledImageAsThumbnailAsync(this, mode, requestedsize, options) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetScaledImageAsThumbnailAsyncOverloadDefaultSizeDefaultOptions: GetScaledImageAsThumbnailAsyncOverloadDefaultSizeDefaultOptions::, + GetScaledImageAsThumbnailAsyncOverloadDefaultOptions: GetScaledImageAsThumbnailAsyncOverloadDefaultOptions::, + GetScaledImageAsThumbnailAsync: GetScaledImageAsThumbnailAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageItemProperties2_Vtbl { @@ -14480,6 +81525,98 @@ impl windows_core::RuntimeType for IStorageItemPropertiesWithProvider { } windows_core::imp::interface_hierarchy!(IStorageItemPropertiesWithProvider, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(IStorageItemPropertiesWithProvider, IStorageItemProperties); +impl IStorageItemPropertiesWithProvider { + pub fn Provider(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Provider)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetThumbnailAsyncOverloadDefaultSizeDefaultOptions(&self, mode: FileProperties::ThumbnailMode) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsyncOverloadDefaultSizeDefaultOptions)(windows_core::Interface::as_raw(this), mode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetThumbnailAsyncOverloadDefaultOptions(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), mode, requestedsize, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetThumbnailAsync(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32, options: FileProperties::ThumbnailOptions) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsync)(windows_core::Interface::as_raw(this), mode, requestedsize, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DisplayName(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn DisplayType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn FolderRelativeId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FolderRelativeId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn Properties(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IStorageItemPropertiesWithProvider { + const NAME: &'static str = "Windows.Storage.IStorageItemPropertiesWithProvider"; +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] +pub trait IStorageItemPropertiesWithProvider_Impl: IStorageItemProperties_Impl { + fn Provider(&self) -> windows_core::Result; +} +#[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] +impl IStorageItemPropertiesWithProvider_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Provider(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemPropertiesWithProvider_Impl::Provider(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Provider: Provider:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageItemPropertiesWithProvider_Vtbl { @@ -14490,6 +81627,106 @@ windows_core::imp::define_interface!(IStorageLibrary, IStorageLibrary_Vtbl, 0x1e impl windows_core::RuntimeType for IStorageLibrary { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(all(feature = "Foundation_Collections", feature = "Storage_Search"))] +impl windows_core::RuntimeName for IStorageLibrary { + const NAME: &'static str = "Windows.Storage.IStorageLibrary"; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Storage_Search"))] +pub trait IStorageLibrary_Impl: windows_core::IUnknownImpl { + fn RequestAddFolderAsync(&self) -> windows_core::Result>; + fn RequestRemoveFolderAsync(&self, folder: windows_core::Ref<'_, StorageFolder>) -> windows_core::Result>; + fn Folders(&self) -> windows_core::Result>; + fn SaveFolder(&self) -> windows_core::Result; + fn DefinitionChanged(&self, handler: windows_core::Ref<'_, super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveDefinitionChanged(&self, eventCookie: i64) -> windows_core::Result<()>; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Storage_Search"))] +impl IStorageLibrary_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn RequestAddFolderAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibrary_Impl::RequestAddFolderAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RequestRemoveFolderAsync(this: *mut core::ffi::c_void, folder: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibrary_Impl::RequestRemoveFolderAsync(this, core::mem::transmute_copy(&folder)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Folders(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibrary_Impl::Folders(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SaveFolder(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibrary_Impl::SaveFolder(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DefinitionChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibrary_Impl::DefinitionChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveDefinitionChanged(this: *mut core::ffi::c_void, eventcookie: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStorageLibrary_Impl::RemoveDefinitionChanged(this, eventcookie).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + RequestAddFolderAsync: RequestAddFolderAsync::, + RequestRemoveFolderAsync: RequestRemoveFolderAsync::, + Folders: Folders::, + SaveFolder: SaveFolder::, + DefinitionChanged: DefinitionChanged::, + RemoveDefinitionChanged: RemoveDefinitionChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageLibrary_Vtbl { @@ -14517,6 +81754,33 @@ windows_core::imp::define_interface!(IStorageLibrary2, IStorageLibrary2_Vtbl, 0x impl windows_core::RuntimeType for IStorageLibrary2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStorageLibrary2 { + const NAME: &'static str = "Windows.Storage.IStorageLibrary2"; +} +pub trait IStorageLibrary2_Impl: windows_core::IUnknownImpl { + fn ChangeTracker(&self) -> windows_core::Result; +} +impl IStorageLibrary2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ChangeTracker(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibrary2_Impl::ChangeTracker(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), ChangeTracker: ChangeTracker:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageLibrary2_Vtbl { @@ -14527,6 +81791,36 @@ windows_core::imp::define_interface!(IStorageLibrary3, IStorageLibrary3_Vtbl, 0x impl windows_core::RuntimeType for IStorageLibrary3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStorageLibrary3 { + const NAME: &'static str = "Windows.Storage.IStorageLibrary3"; +} +pub trait IStorageLibrary3_Impl: windows_core::IUnknownImpl { + fn AreFolderSuggestionsAvailableAsync(&self) -> windows_core::Result>; +} +impl IStorageLibrary3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AreFolderSuggestionsAvailableAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibrary3_Impl::AreFolderSuggestionsAvailableAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + AreFolderSuggestionsAvailableAsync: AreFolderSuggestionsAvailableAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageLibrary3_Vtbl { @@ -14537,6 +81831,94 @@ windows_core::imp::define_interface!(IStorageLibraryChange, IStorageLibraryChang impl windows_core::RuntimeType for IStorageLibraryChange { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStorageLibraryChange { + const NAME: &'static str = "Windows.Storage.IStorageLibraryChange"; +} +pub trait IStorageLibraryChange_Impl: windows_core::IUnknownImpl { + fn ChangeType(&self) -> windows_core::Result; + fn Path(&self) -> windows_core::Result; + fn PreviousPath(&self) -> windows_core::Result; + fn IsOfType(&self, r#type: StorageItemTypes) -> windows_core::Result; + fn GetStorageItemAsync(&self) -> windows_core::Result>; +} +impl IStorageLibraryChange_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ChangeType(this: *mut core::ffi::c_void, result__: *mut StorageLibraryChangeType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibraryChange_Impl::ChangeType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Path(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibraryChange_Impl::Path(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PreviousPath(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibraryChange_Impl::PreviousPath(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsOfType(this: *mut core::ffi::c_void, r#type: StorageItemTypes, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibraryChange_Impl::IsOfType(this, r#type) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetStorageItemAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibraryChange_Impl::GetStorageItemAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ChangeType: ChangeType::, + Path: Path::, + PreviousPath: PreviousPath::, + IsOfType: IsOfType::, + GetStorageItemAsync: GetStorageItemAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageLibraryChange_Vtbl { @@ -14551,6 +81933,51 @@ windows_core::imp::define_interface!(IStorageLibraryChangeReader, IStorageLibrar impl windows_core::RuntimeType for IStorageLibraryChangeReader { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStorageLibraryChangeReader { + const NAME: &'static str = "Windows.Storage.IStorageLibraryChangeReader"; +} +pub trait IStorageLibraryChangeReader_Impl: windows_core::IUnknownImpl { + fn ReadBatchAsync(&self) -> windows_core::Result>>; + fn AcceptChangesAsync(&self) -> windows_core::Result; +} +impl IStorageLibraryChangeReader_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ReadBatchAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibraryChangeReader_Impl::ReadBatchAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AcceptChangesAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibraryChangeReader_Impl::AcceptChangesAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ReadBatchAsync: ReadBatchAsync::, + AcceptChangesAsync: AcceptChangesAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageLibraryChangeReader_Vtbl { @@ -14562,6 +81989,35 @@ windows_core::imp::define_interface!(IStorageLibraryChangeReader2, IStorageLibra impl windows_core::RuntimeType for IStorageLibraryChangeReader2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStorageLibraryChangeReader2 { + const NAME: &'static str = "Windows.Storage.IStorageLibraryChangeReader2"; +} +pub trait IStorageLibraryChangeReader2_Impl: windows_core::IUnknownImpl { + fn GetLastChangeId(&self) -> windows_core::Result; +} +impl IStorageLibraryChangeReader2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetLastChangeId(this: *mut core::ffi::c_void, result__: *mut u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibraryChangeReader2_Impl::GetLastChangeId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetLastChangeId: GetLastChangeId::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageLibraryChangeReader2_Vtbl { @@ -14572,6 +82028,52 @@ windows_core::imp::define_interface!(IStorageLibraryChangeTracker, IStorageLibra impl windows_core::RuntimeType for IStorageLibraryChangeTracker { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStorageLibraryChangeTracker { + const NAME: &'static str = "Windows.Storage.IStorageLibraryChangeTracker"; +} +pub trait IStorageLibraryChangeTracker_Impl: windows_core::IUnknownImpl { + fn GetChangeReader(&self) -> windows_core::Result; + fn Enable(&self) -> windows_core::Result<()>; + fn Reset(&self) -> windows_core::Result<()>; +} +impl IStorageLibraryChangeTracker_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetChangeReader(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibraryChangeTracker_Impl::GetChangeReader(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Enable(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStorageLibraryChangeTracker_Impl::Enable(this).into() + } + } + unsafe extern "system" fn Reset(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStorageLibraryChangeTracker_Impl::Reset(this).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetChangeReader: GetChangeReader::, + Enable: Enable::, + Reset: Reset::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageLibraryChangeTracker_Vtbl { @@ -14584,6 +82086,37 @@ windows_core::imp::define_interface!(IStorageLibraryChangeTracker2, IStorageLibr impl windows_core::RuntimeType for IStorageLibraryChangeTracker2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStorageLibraryChangeTracker2 { + const NAME: &'static str = "Windows.Storage.IStorageLibraryChangeTracker2"; +} +pub trait IStorageLibraryChangeTracker2_Impl: windows_core::IUnknownImpl { + fn EnableWithOptions(&self, options: windows_core::Ref<'_, StorageLibraryChangeTrackerOptions>) -> windows_core::Result<()>; + fn Disable(&self) -> windows_core::Result<()>; +} +impl IStorageLibraryChangeTracker2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn EnableWithOptions(this: *mut core::ffi::c_void, options: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStorageLibraryChangeTracker2_Impl::EnableWithOptions(this, core::mem::transmute_copy(&options)).into() + } + } + unsafe extern "system" fn Disable(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStorageLibraryChangeTracker2_Impl::Disable(this).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + EnableWithOptions: EnableWithOptions::, + Disable: Disable::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageLibraryChangeTracker2_Vtbl { @@ -14595,6 +82128,43 @@ windows_core::imp::define_interface!(IStorageLibraryChangeTrackerOptions, IStora impl windows_core::RuntimeType for IStorageLibraryChangeTrackerOptions { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStorageLibraryChangeTrackerOptions { + const NAME: &'static str = "Windows.Storage.IStorageLibraryChangeTrackerOptions"; +} +pub trait IStorageLibraryChangeTrackerOptions_Impl: windows_core::IUnknownImpl { + fn TrackChangeDetails(&self) -> windows_core::Result; + fn SetTrackChangeDetails(&self, value: bool) -> windows_core::Result<()>; +} +impl IStorageLibraryChangeTrackerOptions_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TrackChangeDetails(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibraryChangeTrackerOptions_Impl::TrackChangeDetails(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetTrackChangeDetails(this: *mut core::ffi::c_void, value: bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStorageLibraryChangeTrackerOptions_Impl::SetTrackChangeDetails(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + TrackChangeDetails: TrackChangeDetails::, + SetTrackChangeDetails: SetTrackChangeDetails::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageLibraryChangeTrackerOptions_Vtbl { @@ -14606,6 +82176,33 @@ windows_core::imp::define_interface!(IStorageLibraryStatics, IStorageLibraryStat impl windows_core::RuntimeType for IStorageLibraryStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStorageLibraryStatics { + const NAME: &'static str = "Windows.Storage.IStorageLibraryStatics"; +} +pub trait IStorageLibraryStatics_Impl: windows_core::IUnknownImpl { + fn GetLibraryAsync(&self, libraryId: KnownLibraryId) -> windows_core::Result>; +} +impl IStorageLibraryStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetLibraryAsync(this: *mut core::ffi::c_void, libraryid: KnownLibraryId, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibraryStatics_Impl::GetLibraryAsync(this, libraryid) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), GetLibraryAsync: GetLibraryAsync:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageLibraryStatics_Vtbl { @@ -14616,6 +82213,39 @@ windows_core::imp::define_interface!(IStorageLibraryStatics2, IStorageLibrarySta impl windows_core::RuntimeType for IStorageLibraryStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "System")] +impl windows_core::RuntimeName for IStorageLibraryStatics2 { + const NAME: &'static str = "Windows.Storage.IStorageLibraryStatics2"; +} +#[cfg(feature = "System")] +pub trait IStorageLibraryStatics2_Impl: windows_core::IUnknownImpl { + fn GetLibraryForUserAsync(&self, user: windows_core::Ref<'_, super::System::User>, libraryId: KnownLibraryId) -> windows_core::Result>; +} +#[cfg(feature = "System")] +impl IStorageLibraryStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetLibraryForUserAsync(this: *mut core::ffi::c_void, user: *mut core::ffi::c_void, libraryid: KnownLibraryId, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageLibraryStatics2_Impl::GetLibraryForUserAsync(this, core::mem::transmute_copy(&user), libraryid) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetLibraryForUserAsync: GetLibraryForUserAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageLibraryStatics2_Vtbl { @@ -14629,6 +82259,51 @@ windows_core::imp::define_interface!(IStorageProvider, IStorageProvider_Vtbl, 0x impl windows_core::RuntimeType for IStorageProvider { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStorageProvider { + const NAME: &'static str = "Windows.Storage.IStorageProvider"; +} +pub trait IStorageProvider_Impl: windows_core::IUnknownImpl { + fn Id(&self) -> windows_core::Result; + fn DisplayName(&self) -> windows_core::Result; +} +impl IStorageProvider_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Id(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageProvider_Impl::Id(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DisplayName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageProvider_Impl::DisplayName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Id: Id::, + DisplayName: DisplayName::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageProvider_Vtbl { @@ -14640,6 +82315,36 @@ windows_core::imp::define_interface!(IStorageProvider2, IStorageProvider2_Vtbl, impl windows_core::RuntimeType for IStorageProvider2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IStorageProvider2 { + const NAME: &'static str = "Windows.Storage.IStorageProvider2"; +} +pub trait IStorageProvider2_Impl: IStorageProvider_Impl { + fn IsPropertySupportedForPartialFileAsync(&self, propertyCanonicalName: &windows_core::HSTRING) -> windows_core::Result>; +} +impl IStorageProvider2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsPropertySupportedForPartialFileAsync(this: *mut core::ffi::c_void, propertycanonicalname: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageProvider2_Impl::IsPropertySupportedForPartialFileAsync(this, core::mem::transmute(&propertycanonicalname)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsPropertySupportedForPartialFileAsync: IsPropertySupportedForPartialFileAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageProvider2_Vtbl { @@ -14650,6 +82355,54 @@ windows_core::imp::define_interface!(IStorageStreamTransaction, IStorageStreamTr impl windows_core::RuntimeType for IStorageStreamTransaction { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IStorageStreamTransaction { + const NAME: &'static str = "Windows.Storage.IStorageStreamTransaction"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IStorageStreamTransaction_Impl: super::Foundation::IClosable_Impl { + fn Stream(&self) -> windows_core::Result; + fn CommitAsync(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IStorageStreamTransaction_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Stream(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageStreamTransaction_Impl::Stream(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CommitAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageStreamTransaction_Impl::CommitAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Stream: Stream::, + CommitAsync: CommitAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IStorageStreamTransaction_Vtbl { @@ -14665,6 +82418,12 @@ impl windows_core::RuntimeType for IStreamedFileDataRequest { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } windows_core::imp::interface_hierarchy!(IStreamedFileDataRequest, windows_core::IUnknown, windows_core::IInspectable); +impl IStreamedFileDataRequest { + pub fn FailAndClose(&self, failuremode: StreamedFileFailureMode) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).FailAndClose)(windows_core::Interface::as_raw(this), failuremode).ok() } + } +} impl windows_core::RuntimeName for IStreamedFileDataRequest { const NAME: &'static str = "Windows.Storage.IStreamedFileDataRequest"; } @@ -14743,6 +82502,252 @@ windows_core::imp::interface_hierarchy!(StorageFile, windows_core::IUnknown, win windows_core::imp::required_hierarchy!(StorageFile, Streams::IInputStreamReference, Streams::IRandomAccessStreamReference, IStorageFile2, IStorageFilePropertiesWithAvailability, IStorageItem, IStorageItem2, IStorageItemProperties, IStorageItemProperties2, IStorageItemPropertiesWithProvider); #[cfg(feature = "Storage_Streams")] impl StorageFile { + pub fn OpenSequentialReadAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenSequentialReadAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn OpenReadAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenReadAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn FileType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FileType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn ContentType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn OpenAsync(&self, accessmode: FileAccessMode) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenAsync)(windows_core::Interface::as_raw(this), accessmode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn OpenTransactedWriteAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenTransactedWriteAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CopyOverloadDefaultNameAndOptions(&self, destinationfolder: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CopyOverloadDefaultNameAndOptions)(windows_core::Interface::as_raw(this), destinationfolder.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CopyOverloadDefaultOptions(&self, destinationfolder: P0, desirednewname: &windows_core::HSTRING) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CopyOverloadDefaultOptions)(windows_core::Interface::as_raw(this), destinationfolder.param().abi(), core::mem::transmute_copy(desirednewname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CopyOverload(&self, destinationfolder: P0, desirednewname: &windows_core::HSTRING, option: NameCollisionOption) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CopyOverload)(windows_core::Interface::as_raw(this), destinationfolder.param().abi(), core::mem::transmute_copy(desirednewname), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CopyAndReplaceAsync(&self, filetoreplace: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CopyAndReplaceAsync)(windows_core::Interface::as_raw(this), filetoreplace.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MoveOverloadDefaultNameAndOptions(&self, destinationfolder: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MoveOverloadDefaultNameAndOptions)(windows_core::Interface::as_raw(this), destinationfolder.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MoveOverloadDefaultOptions(&self, destinationfolder: P0, desirednewname: &windows_core::HSTRING) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MoveOverloadDefaultOptions)(windows_core::Interface::as_raw(this), destinationfolder.param().abi(), core::mem::transmute_copy(desirednewname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MoveOverload(&self, destinationfolder: P0, desirednewname: &windows_core::HSTRING, option: NameCollisionOption) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MoveOverload)(windows_core::Interface::as_raw(this), destinationfolder.param().abi(), core::mem::transmute_copy(desirednewname), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn MoveAndReplaceAsync(&self, filetoreplace: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MoveAndReplaceAsync)(windows_core::Interface::as_raw(this), filetoreplace.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn OpenWithOptionsAsync(&self, accessmode: FileAccessMode, options: StorageOpenOptions) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenWithOptionsAsync)(windows_core::Interface::as_raw(this), accessmode, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn OpenTransactedWriteWithOptionsAsync(&self, options: StorageOpenOptions) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenTransactedWriteWithOptionsAsync)(windows_core::Interface::as_raw(this), options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IsAvailable(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsAvailable)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetFileFromPathAsync(path: &windows_core::HSTRING) -> windows_core::Result> { + Self::IStorageFileStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFileFromPathAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(path), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetFileFromApplicationUriAsync(uri: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::IStorageFileStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFileFromApplicationUriAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateStreamedFileAsync(displaynamewithextension: &windows_core::HSTRING, datarequested: P1, thumbnail: P2) -> windows_core::Result> + where + P1: windows_core::Param, + P2: windows_core::Param, + { + Self::IStorageFileStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateStreamedFileAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(displaynamewithextension), datarequested.param().abi(), thumbnail.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn ReplaceWithStreamedFileAsync(filetoreplace: P0, datarequested: P1, thumbnail: P2) -> windows_core::Result> + where + P0: windows_core::Param, + P1: windows_core::Param, + P2: windows_core::Param, + { + Self::IStorageFileStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReplaceWithStreamedFileAsync)(windows_core::Interface::as_raw(this), filetoreplace.param().abi(), datarequested.param().abi(), thumbnail.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateStreamedFileFromUriAsync(displaynamewithextension: &windows_core::HSTRING, uri: P1, thumbnail: P2) -> windows_core::Result> + where + P1: windows_core::Param, + P2: windows_core::Param, + { + Self::IStorageFileStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateStreamedFileFromUriAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(displaynamewithextension), uri.param().abi(), thumbnail.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn ReplaceWithStreamedFileFromUriAsync(filetoreplace: P0, uri: P1, thumbnail: P2) -> windows_core::Result> + where + P0: windows_core::Param, + P1: windows_core::Param, + P2: windows_core::Param, + { + Self::IStorageFileStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReplaceWithStreamedFileFromUriAsync)(windows_core::Interface::as_raw(this), filetoreplace.param().abi(), uri.param().abi(), thumbnail.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "System")] + pub fn GetFileFromPathForUserAsync(user: P0, path: &windows_core::HSTRING) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::IStorageFileStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFileFromPathForUserAsync)(windows_core::Interface::as_raw(this), user.param().abi(), core::mem::transmute_copy(path), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn RenameAsyncOverloadDefaultOptions(&self, desiredname: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RenameAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RenameAsync(&self, desiredname: &windows_core::HSTRING, option: NameCollisionOption) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RenameAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeleteAsyncOverloadDefaultOptions(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeleteAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeleteAsync(&self, option: StorageDeleteOption) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeleteAsync)(windows_core::Interface::as_raw(this), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn GetBasicPropertiesAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetBasicPropertiesAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Name(&self) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; unsafe { @@ -14750,6 +82755,136 @@ impl StorageFile { (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn Path(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Path)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Attributes(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Attributes)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DateCreated(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DateCreated)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsOfType(&self, r#type: StorageItemTypes) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsOfType)(windows_core::Interface::as_raw(this), r#type, &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Search")] + pub fn GetParentAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetParentAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IsEqual(&self, item: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsEqual)(windows_core::Interface::as_raw(this), item.param().abi(), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn GetThumbnailAsyncOverloadDefaultSizeDefaultOptions(&self, mode: FileProperties::ThumbnailMode) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsyncOverloadDefaultSizeDefaultOptions)(windows_core::Interface::as_raw(this), mode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn GetThumbnailAsyncOverloadDefaultOptions(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), mode, requestedsize, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn GetThumbnailAsync(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32, options: FileProperties::ThumbnailOptions) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsync)(windows_core::Interface::as_raw(this), mode, requestedsize, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DisplayName(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn DisplayType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn FolderRelativeId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FolderRelativeId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn Properties(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn GetScaledImageAsThumbnailAsyncOverloadDefaultSizeDefaultOptions(&self, mode: FileProperties::ThumbnailMode) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetScaledImageAsThumbnailAsyncOverloadDefaultSizeDefaultOptions)(windows_core::Interface::as_raw(this), mode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn GetScaledImageAsThumbnailAsyncOverloadDefaultOptions(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetScaledImageAsThumbnailAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), mode, requestedsize, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn GetScaledImageAsThumbnailAsync(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32, options: FileProperties::ThumbnailOptions) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetScaledImageAsThumbnailAsync)(windows_core::Interface::as_raw(this), mode, requestedsize, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Provider(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Provider)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } fn IStorageFileStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -14772,6 +82907,447 @@ unsafe impl windows_core::Interface for StorageFile { impl windows_core::RuntimeName for StorageFile { const NAME: &'static str = "Windows.Storage.StorageFile"; } +#[cfg(feature = "Storage_Search")] +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct StorageFolder(windows_core::IUnknown); +#[cfg(feature = "Storage_Search")] +windows_core::imp::interface_hierarchy!(StorageFolder, windows_core::IUnknown, windows_core::IInspectable, IStorageFolder); +#[cfg(feature = "Storage_Search")] +windows_core::imp::required_hierarchy!(StorageFolder, IStorageFolder2, Search::IStorageFolderQueryOperations, IStorageItem, IStorageItem2, IStorageItemProperties, IStorageItemProperties2, IStorageItemPropertiesWithProvider); +#[cfg(feature = "Storage_Search")] +impl StorageFolder { + #[cfg(feature = "Storage_Streams")] + pub fn CreateFileAsyncOverloadDefaultOptions(&self, desiredname: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFileAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFileAsync(&self, desiredname: &windows_core::HSTRING, options: CreationCollisionOption) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFileAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFolderAsyncOverloadDefaultOptions(&self, desiredname: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFolderAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFolderAsync(&self, desiredname: &windows_core::HSTRING, options: CreationCollisionOption) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFolderAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetFileAsync(&self, name: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFileAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetFolderAsync(&self, name: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFolderAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetItemAsync(&self, name: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetItemAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetFilesAsyncOverloadDefaultOptionsStartAndCount(&self) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFilesAsyncOverloadDefaultOptionsStartAndCount)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetFoldersAsyncOverloadDefaultOptionsStartAndCount(&self) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFoldersAsyncOverloadDefaultOptionsStartAndCount)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetItemsAsyncOverloadDefaultStartAndCount(&self) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetItemsAsyncOverloadDefaultStartAndCount)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryGetItemAsync(&self, name: &windows_core::HSTRING) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryGetItemAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryGetChangeTracker(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryGetChangeTracker)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetIndexedStateAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetIndexedStateAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFileQueryOverloadDefault(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFileQueryOverloadDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFileQuery(&self, query: Search::CommonFileQuery) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFileQuery)(windows_core::Interface::as_raw(this), query, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFileQueryWithOptions(&self, queryoptions: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFileQueryWithOptions)(windows_core::Interface::as_raw(this), queryoptions.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFolderQueryOverloadDefault(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFolderQueryOverloadDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFolderQuery(&self, query: Search::CommonFolderQuery) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFolderQuery)(windows_core::Interface::as_raw(this), query, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFolderQueryWithOptions(&self, queryoptions: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFolderQueryWithOptions)(windows_core::Interface::as_raw(this), queryoptions.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateItemQuery(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateItemQuery)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateItemQueryWithOptions(&self, queryoptions: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateItemQueryWithOptions)(windows_core::Interface::as_raw(this), queryoptions.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetFilesAsync(&self, query: Search::CommonFileQuery, startindex: u32, maxitemstoretrieve: u32) -> windows_core::Result>> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFilesAsync)(windows_core::Interface::as_raw(this), query, startindex, maxitemstoretrieve, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetFilesAsyncOverloadDefaultStartAndCount(&self, query: Search::CommonFileQuery) -> windows_core::Result>> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFilesAsyncOverloadDefaultStartAndCount)(windows_core::Interface::as_raw(this), query, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetFoldersAsync(&self, query: Search::CommonFolderQuery, startindex: u32, maxitemstoretrieve: u32) -> windows_core::Result>> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFoldersAsync)(windows_core::Interface::as_raw(this), query, startindex, maxitemstoretrieve, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetFoldersAsyncOverloadDefaultStartAndCount(&self, query: Search::CommonFolderQuery) -> windows_core::Result>> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFoldersAsyncOverloadDefaultStartAndCount)(windows_core::Interface::as_raw(this), query, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetItemsAsync(&self, startindex: u32, maxitemstoretrieve: u32) -> windows_core::Result>> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetItemsAsync)(windows_core::Interface::as_raw(this), startindex, maxitemstoretrieve, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn AreQueryOptionsSupported(&self, queryoptions: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AreQueryOptionsSupported)(windows_core::Interface::as_raw(this), queryoptions.param().abi(), &mut result__).map(|| result__) + } + } + pub fn IsCommonFolderQuerySupported(&self, query: Search::CommonFolderQuery) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsCommonFolderQuerySupported)(windows_core::Interface::as_raw(this), query, &mut result__).map(|| result__) + } + } + pub fn IsCommonFileQuerySupported(&self, query: Search::CommonFileQuery) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsCommonFileQuerySupported)(windows_core::Interface::as_raw(this), query, &mut result__).map(|| result__) + } + } + pub fn GetFolderFromPathAsync(path: &windows_core::HSTRING) -> windows_core::Result> { + Self::IStorageFolderStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFolderFromPathAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(path), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "System")] + pub fn GetFolderFromPathForUserAsync(user: P0, path: &windows_core::HSTRING) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::IStorageFolderStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFolderFromPathForUserAsync)(windows_core::Interface::as_raw(this), user.param().abi(), core::mem::transmute_copy(path), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn RenameAsyncOverloadDefaultOptions(&self, desiredname: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RenameAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RenameAsync(&self, desiredname: &windows_core::HSTRING, option: NameCollisionOption) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RenameAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(desiredname), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeleteAsyncOverloadDefaultOptions(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeleteAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DeleteAsync(&self, option: StorageDeleteOption) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeleteAsync)(windows_core::Interface::as_raw(this), option, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn GetBasicPropertiesAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetBasicPropertiesAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Name(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Path(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Path)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Attributes(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Attributes)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DateCreated(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DateCreated)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn IsOfType(&self, r#type: StorageItemTypes) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsOfType)(windows_core::Interface::as_raw(this), r#type, &mut result__).map(|| result__) + } + } + pub fn GetParentAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetParentAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IsEqual(&self, item: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsEqual)(windows_core::Interface::as_raw(this), item.param().abi(), &mut result__).map(|| result__) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetThumbnailAsyncOverloadDefaultSizeDefaultOptions(&self, mode: FileProperties::ThumbnailMode) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsyncOverloadDefaultSizeDefaultOptions)(windows_core::Interface::as_raw(this), mode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetThumbnailAsyncOverloadDefaultOptions(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), mode, requestedsize, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetThumbnailAsync(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32, options: FileProperties::ThumbnailOptions) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetThumbnailAsync)(windows_core::Interface::as_raw(this), mode, requestedsize, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DisplayName(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn DisplayType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn FolderRelativeId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FolderRelativeId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn Properties(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetScaledImageAsThumbnailAsyncOverloadDefaultSizeDefaultOptions(&self, mode: FileProperties::ThumbnailMode) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetScaledImageAsThumbnailAsyncOverloadDefaultSizeDefaultOptions)(windows_core::Interface::as_raw(this), mode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetScaledImageAsThumbnailAsyncOverloadDefaultOptions(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetScaledImageAsThumbnailAsyncOverloadDefaultOptions)(windows_core::Interface::as_raw(this), mode, requestedsize, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Storage_FileProperties", feature = "Storage_Streams"))] + pub fn GetScaledImageAsThumbnailAsync(&self, mode: FileProperties::ThumbnailMode, requestedsize: u32, options: FileProperties::ThumbnailOptions) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetScaledImageAsThumbnailAsync)(windows_core::Interface::as_raw(this), mode, requestedsize, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Provider(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Provider)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + fn IStorageFolderStatics windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + fn IStorageFolderStatics2 windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +#[cfg(feature = "Storage_Search")] +impl windows_core::RuntimeType for StorageFolder { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +#[cfg(feature = "Storage_Search")] +unsafe impl windows_core::Interface for StorageFolder { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +#[cfg(feature = "Storage_Search")] +impl windows_core::RuntimeName for StorageFolder { + const NAME: &'static str = "Windows.Storage.StorageFolder"; +} #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct StorageItemTypes(pub u32); @@ -14824,6 +83400,85 @@ impl core::ops::Not for StorageItemTypes { pub struct StorageLibrary(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(StorageLibrary, windows_core::IUnknown, windows_core::IInspectable); impl StorageLibrary { + #[cfg(feature = "Storage_Search")] + pub fn RequestAddFolderAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestAddFolderAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Search")] + pub fn RequestRemoveFolderAsync(&self, folder: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestRemoveFolderAsync)(windows_core::Interface::as_raw(this), folder.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Foundation_Collections", feature = "Storage_Search"))] + pub fn Folders(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Folders)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Search")] + pub fn SaveFolder(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SaveFolder)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DefinitionChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DefinitionChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveDefinitionChanged(&self, eventcookie: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveDefinitionChanged)(windows_core::Interface::as_raw(this), eventcookie).ok() } + } + pub fn ChangeTracker(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ChangeTracker)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn AreFolderSuggestionsAvailableAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AreFolderSuggestionsAvailableAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetLibraryAsync(libraryid: KnownLibraryId) -> windows_core::Result> { + Self::IStorageLibraryStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetLibraryAsync)(windows_core::Interface::as_raw(this), libraryid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "System")] + pub fn GetLibraryForUserAsync(user: P0, libraryid: KnownLibraryId) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::IStorageLibraryStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetLibraryForUserAsync)(windows_core::Interface::as_raw(this), user.param().abi(), libraryid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IStorageLibraryStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -14847,6 +83502,43 @@ impl windows_core::RuntimeName for StorageLibrary { #[derive(Clone, Debug, Eq, PartialEq)] pub struct StorageLibraryChange(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(StorageLibraryChange, windows_core::IUnknown, windows_core::IInspectable); +impl StorageLibraryChange { + pub fn ChangeType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ChangeType)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Path(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Path)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn PreviousPath(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PreviousPath)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn IsOfType(&self, r#type: StorageItemTypes) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsOfType)(windows_core::Interface::as_raw(this), r#type, &mut result__).map(|| result__) + } + } + pub fn GetStorageItemAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetStorageItemAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for StorageLibraryChange { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -14863,6 +83555,29 @@ unsafe impl Sync for StorageLibraryChange {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct StorageLibraryChangeReader(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(StorageLibraryChangeReader, windows_core::IUnknown, windows_core::IInspectable); +impl StorageLibraryChangeReader { + pub fn ReadBatchAsync(&self) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadBatchAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn AcceptChangesAsync(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AcceptChangesAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetLastChangeId(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetLastChangeId)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for StorageLibraryChangeReader { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -14879,6 +83594,34 @@ unsafe impl Sync for StorageLibraryChangeReader {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct StorageLibraryChangeTracker(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(StorageLibraryChangeTracker, windows_core::IUnknown, windows_core::IInspectable); +impl StorageLibraryChangeTracker { + pub fn GetChangeReader(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetChangeReader)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Enable(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Enable)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn Reset(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Reset)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn EnableWithOptions(&self, options: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).EnableWithOptions)(windows_core::Interface::as_raw(this), options.param().abi()).ok() } + } + pub fn Disable(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Disable)(windows_core::Interface::as_raw(this)).ok() } + } +} impl windows_core::RuntimeType for StorageLibraryChangeTracker { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -14903,7 +83646,18 @@ impl StorageLibraryChangeTrackerOptions { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn TrackChangeDetails(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrackChangeDetails)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } + pub fn SetTrackChangeDetails(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetTrackChangeDetails)(windows_core::Interface::as_raw(this), value).ok() } + } +} impl windows_core::RuntimeType for StorageLibraryChangeTrackerOptions { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -14996,7 +83750,21 @@ impl StorageProvider { (windows_core::Interface::vtable(this).Id)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn DisplayName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } } + pub fn IsPropertySupportedForPartialFileAsync(&self, propertycanonicalname: &windows_core::HSTRING) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsPropertySupportedForPartialFileAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(propertycanonicalname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for StorageProvider { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -15017,7 +83785,22 @@ impl StorageStreamTransaction { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + #[cfg(feature = "Storage_Streams")] + pub fn Stream(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Stream)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn CommitAsync(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CommitAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for StorageStreamTransaction { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -15042,6 +83825,16 @@ impl StreamedFileDataRequest { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn WriteAsync(&self, buffer: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn FlushAsync(&self) -> windows_core::Result> { let this = self; unsafe { @@ -15049,7 +83842,11 @@ impl StreamedFileDataRequest { (windows_core::Interface::vtable(this).FlushAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn FailAndClose(&self, failuremode: StreamedFileFailureMode) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).FailAndClose)(windows_core::Interface::as_raw(this), failuremode).ok() } } +} #[cfg(feature = "Storage_Streams")] impl windows_core::RuntimeType for StreamedFileDataRequest { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); @@ -15071,11 +83868,18 @@ impl windows_core::RuntimeType for StreamedFileDataRequestedHandler { } #[cfg(feature = "Storage_Streams")] impl StreamedFileDataRequestedHandler { - pub fn new) -> windows_core::Result<()> + Send + 'static>(invoke: F) -> Self { + pub fn new) -> windows_core::Result<()> + Send + 'static>(invoke: F) -> Self { let com = StreamedFileDataRequestedHandlerBox { vtable: &StreamedFileDataRequestedHandlerBox::::VTABLE, count: windows_core::imp::RefCount::new(1), invoke }; unsafe { core::mem::transmute(windows_core::imp::Box::new(com)) } } + pub fn Invoke(&self, stream: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Invoke)(windows_core::Interface::as_raw(this), stream.param().abi()).ok() } } +} #[cfg(feature = "Storage_Streams")] #[repr(C)] #[doc(hidden)] @@ -15085,13 +83889,13 @@ pub struct StreamedFileDataRequestedHandler_Vtbl { } #[cfg(feature = "Storage_Streams")] #[repr(C)] -struct StreamedFileDataRequestedHandlerBox) -> windows_core::Result<()> + Send + 'static> { +struct StreamedFileDataRequestedHandlerBox) -> windows_core::Result<()> + Send + 'static> { vtable: *const StreamedFileDataRequestedHandler_Vtbl, invoke: F, count: windows_core::imp::RefCount, } #[cfg(feature = "Storage_Streams")] -impl) -> windows_core::Result<()> + Send + 'static> StreamedFileDataRequestedHandlerBox { +impl) -> windows_core::Result<()> + Send + 'static> StreamedFileDataRequestedHandlerBox { const VTABLE: StreamedFileDataRequestedHandler_Vtbl = StreamedFileDataRequestedHandler_Vtbl { base__: windows_core::IUnknown_Vtbl { QueryInterface: Self::QueryInterface, AddRef: Self::AddRef, Release: Self::Release }, Invoke: Self::Invoke }; unsafe extern "system" fn QueryInterface(this: *mut core::ffi::c_void, iid: *const windows_core::GUID, interface: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { unsafe { @@ -15152,6 +83956,4240 @@ impl windows_core::TypeKind for StreamedFileFailureMode { impl windows_core::RuntimeType for StreamedFileFailureMode { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Storage.StreamedFileFailureMode;i4)"); } +#[cfg(feature = "Storage_FileProperties")] +pub mod FileProperties{ +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct BasicProperties(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(BasicProperties, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(BasicProperties, IStorageItemExtraProperties); +impl BasicProperties { + pub fn Size(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn DateModified(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DateModified)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ItemDate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ItemDate)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn RetrievePropertiesAsync(&self, propertiestoretrieve: P0) -> windows_core::Result>> + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RetrievePropertiesAsync)(windows_core::Interface::as_raw(this), propertiestoretrieve.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SavePropertiesAsync(&self, propertiestosave: P0) -> windows_core::Result + where + P0: windows_core::Param>>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SavePropertiesAsync)(windows_core::Interface::as_raw(this), propertiestosave.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SavePropertiesAsyncOverloadDefault(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SavePropertiesAsyncOverloadDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for BasicProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for BasicProperties { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for BasicProperties { + const NAME: &'static str = "Windows.Storage.FileProperties.BasicProperties"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct DocumentProperties(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(DocumentProperties, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(DocumentProperties, IStorageItemExtraProperties); +impl DocumentProperties { + pub fn Author(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Author)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Title(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Title)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetTitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetTitle)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Keywords(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Keywords)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Comment(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Comment)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetComment(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetComment)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn RetrievePropertiesAsync(&self, propertiestoretrieve: P0) -> windows_core::Result>> + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RetrievePropertiesAsync)(windows_core::Interface::as_raw(this), propertiestoretrieve.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SavePropertiesAsync(&self, propertiestosave: P0) -> windows_core::Result + where + P0: windows_core::Param>>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SavePropertiesAsync)(windows_core::Interface::as_raw(this), propertiestosave.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SavePropertiesAsyncOverloadDefault(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SavePropertiesAsyncOverloadDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for DocumentProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for DocumentProperties { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for DocumentProperties { + const NAME: &'static str = "Windows.Storage.FileProperties.DocumentProperties"; +} +windows_core::imp::define_interface!(IBasicProperties, IBasicProperties_Vtbl, 0xd05d55db_785e_4a66_be02_9beec58aea81); +impl windows_core::RuntimeType for IBasicProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IBasicProperties { + const NAME: &'static str = "Windows.Storage.FileProperties.IBasicProperties"; +} +pub trait IBasicProperties_Impl: windows_core::IUnknownImpl { + fn Size(&self) -> windows_core::Result; + fn DateModified(&self) -> windows_core::Result; + fn ItemDate(&self) -> windows_core::Result; +} +impl IBasicProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Size(this: *mut core::ffi::c_void, result__: *mut u64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBasicProperties_Impl::Size(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DateModified(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBasicProperties_Impl::DateModified(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ItemDate(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBasicProperties_Impl::ItemDate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Size: Size::, + DateModified: DateModified::, + ItemDate: ItemDate::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IBasicProperties_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Size: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u64) -> windows_core::HRESULT, + pub DateModified: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::DateTime) -> windows_core::HRESULT, + pub ItemDate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::DateTime) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IDocumentProperties, IDocumentProperties_Vtbl, 0x7eab19bc_1821_4923_b4a9_0aea404d0070); +impl windows_core::RuntimeType for IDocumentProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IDocumentProperties { + const NAME: &'static str = "Windows.Storage.FileProperties.IDocumentProperties"; +} +pub trait IDocumentProperties_Impl: IStorageItemExtraProperties_Impl { + fn Author(&self) -> windows_core::Result>; + fn Title(&self) -> windows_core::Result; + fn SetTitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Keywords(&self) -> windows_core::Result>; + fn Comment(&self) -> windows_core::Result; + fn SetComment(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; +} +impl IDocumentProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Author(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDocumentProperties_Impl::Author(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Title(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDocumentProperties_Impl::Title(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetTitle(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDocumentProperties_Impl::SetTitle(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Keywords(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDocumentProperties_Impl::Keywords(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Comment(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDocumentProperties_Impl::Comment(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetComment(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDocumentProperties_Impl::SetComment(this, core::mem::transmute(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Author: Author::, + Title: Title::, + SetTitle: SetTitle::, + Keywords: Keywords::, + Comment: Comment::, + SetComment: SetComment::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IDocumentProperties_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Author: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Title: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetTitle: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Keywords: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Comment: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetComment: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IImageProperties, IImageProperties_Vtbl, 0x523c9424_fcff_4275_afee_ecdb9ab47973); +impl windows_core::RuntimeType for IImageProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IImageProperties { + const NAME: &'static str = "Windows.Storage.FileProperties.IImageProperties"; +} +pub trait IImageProperties_Impl: IStorageItemExtraProperties_Impl { + fn Rating(&self) -> windows_core::Result; + fn SetRating(&self, value: u32) -> windows_core::Result<()>; + fn Keywords(&self) -> windows_core::Result>; + fn DateTaken(&self) -> windows_core::Result; + fn SetDateTaken(&self, value: &super::super::Foundation::DateTime) -> windows_core::Result<()>; + fn Width(&self) -> windows_core::Result; + fn Height(&self) -> windows_core::Result; + fn Title(&self) -> windows_core::Result; + fn SetTitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Latitude(&self) -> windows_core::Result>; + fn Longitude(&self) -> windows_core::Result>; + fn CameraManufacturer(&self) -> windows_core::Result; + fn SetCameraManufacturer(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn CameraModel(&self) -> windows_core::Result; + fn SetCameraModel(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Orientation(&self) -> windows_core::Result; + fn PeopleNames(&self) -> windows_core::Result>; +} +impl IImageProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Rating(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IImageProperties_Impl::Rating(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRating(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IImageProperties_Impl::SetRating(this, value).into() + } + } + unsafe extern "system" fn Keywords(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IImageProperties_Impl::Keywords(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DateTaken(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IImageProperties_Impl::DateTaken(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDateTaken(this: *mut core::ffi::c_void, value: super::super::Foundation::DateTime) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IImageProperties_Impl::SetDateTaken(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Width(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IImageProperties_Impl::Width(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Height(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IImageProperties_Impl::Height(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Title(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IImageProperties_Impl::Title(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetTitle(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IImageProperties_Impl::SetTitle(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Latitude(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IImageProperties_Impl::Latitude(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Longitude(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IImageProperties_Impl::Longitude(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CameraManufacturer(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IImageProperties_Impl::CameraManufacturer(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetCameraManufacturer(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IImageProperties_Impl::SetCameraManufacturer(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn CameraModel(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IImageProperties_Impl::CameraModel(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetCameraModel(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IImageProperties_Impl::SetCameraModel(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Orientation(this: *mut core::ffi::c_void, result__: *mut PhotoOrientation) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IImageProperties_Impl::Orientation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PeopleNames(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IImageProperties_Impl::PeopleNames(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Rating: Rating::, + SetRating: SetRating::, + Keywords: Keywords::, + DateTaken: DateTaken::, + SetDateTaken: SetDateTaken::, + Width: Width::, + Height: Height::, + Title: Title::, + SetTitle: SetTitle::, + Latitude: Latitude::, + Longitude: Longitude::, + CameraManufacturer: CameraManufacturer::, + SetCameraManufacturer: SetCameraManufacturer::, + CameraModel: CameraModel::, + SetCameraModel: SetCameraModel::, + Orientation: Orientation::, + PeopleNames: PeopleNames::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IImageProperties_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Rating: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetRating: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub Keywords: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub DateTaken: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::DateTime) -> windows_core::HRESULT, + pub SetDateTaken: unsafe extern "system" fn(*mut core::ffi::c_void, super::super::Foundation::DateTime) -> windows_core::HRESULT, + pub Width: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Height: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Title: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetTitle: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Latitude: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Longitude: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CameraManufacturer: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetCameraManufacturer: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CameraModel: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetCameraModel: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Orientation: unsafe extern "system" fn(*mut core::ffi::c_void, *mut PhotoOrientation) -> windows_core::HRESULT, + pub PeopleNames: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IMusicProperties, IMusicProperties_Vtbl, 0xbc8aab62_66ec_419a_bc5d_ca65a4cb46da); +impl windows_core::RuntimeType for IMusicProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IMusicProperties { + const NAME: &'static str = "Windows.Storage.FileProperties.IMusicProperties"; +} +pub trait IMusicProperties_Impl: IStorageItemExtraProperties_Impl { + fn Album(&self) -> windows_core::Result; + fn SetAlbum(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Artist(&self) -> windows_core::Result; + fn SetArtist(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Genre(&self) -> windows_core::Result>; + fn TrackNumber(&self) -> windows_core::Result; + fn SetTrackNumber(&self, value: u32) -> windows_core::Result<()>; + fn Title(&self) -> windows_core::Result; + fn SetTitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Rating(&self) -> windows_core::Result; + fn SetRating(&self, value: u32) -> windows_core::Result<()>; + fn Duration(&self) -> windows_core::Result; + fn Bitrate(&self) -> windows_core::Result; + fn AlbumArtist(&self) -> windows_core::Result; + fn SetAlbumArtist(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Composers(&self) -> windows_core::Result>; + fn Conductors(&self) -> windows_core::Result>; + fn Subtitle(&self) -> windows_core::Result; + fn SetSubtitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Producers(&self) -> windows_core::Result>; + fn Publisher(&self) -> windows_core::Result; + fn SetPublisher(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Writers(&self) -> windows_core::Result>; + fn Year(&self) -> windows_core::Result; + fn SetYear(&self, value: u32) -> windows_core::Result<()>; +} +impl IMusicProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Album(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::Album(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAlbum(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMusicProperties_Impl::SetAlbum(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Artist(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::Artist(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetArtist(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMusicProperties_Impl::SetArtist(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Genre(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::Genre(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TrackNumber(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::TrackNumber(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetTrackNumber(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMusicProperties_Impl::SetTrackNumber(this, value).into() + } + } + unsafe extern "system" fn Title(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::Title(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetTitle(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMusicProperties_Impl::SetTitle(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Rating(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::Rating(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRating(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMusicProperties_Impl::SetRating(this, value).into() + } + } + unsafe extern "system" fn Duration(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::Duration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Bitrate(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::Bitrate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AlbumArtist(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::AlbumArtist(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAlbumArtist(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMusicProperties_Impl::SetAlbumArtist(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Composers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::Composers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Conductors(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::Conductors(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Subtitle(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::Subtitle(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetSubtitle(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMusicProperties_Impl::SetSubtitle(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Producers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::Producers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Publisher(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::Publisher(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPublisher(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMusicProperties_Impl::SetPublisher(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Writers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::Writers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Year(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMusicProperties_Impl::Year(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetYear(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMusicProperties_Impl::SetYear(this, value).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Album: Album::, + SetAlbum: SetAlbum::, + Artist: Artist::, + SetArtist: SetArtist::, + Genre: Genre::, + TrackNumber: TrackNumber::, + SetTrackNumber: SetTrackNumber::, + Title: Title::, + SetTitle: SetTitle::, + Rating: Rating::, + SetRating: SetRating::, + Duration: Duration::, + Bitrate: Bitrate::, + AlbumArtist: AlbumArtist::, + SetAlbumArtist: SetAlbumArtist::, + Composers: Composers::, + Conductors: Conductors::, + Subtitle: Subtitle::, + SetSubtitle: SetSubtitle::, + Producers: Producers::, + Publisher: Publisher::, + SetPublisher: SetPublisher::, + Writers: Writers::, + Year: Year::, + SetYear: SetYear::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMusicProperties_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Album: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetAlbum: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Artist: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetArtist: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Genre: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub TrackNumber: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetTrackNumber: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub Title: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetTitle: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Rating: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetRating: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub Duration: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub Bitrate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub AlbumArtist: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetAlbumArtist: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Composers: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Conductors: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Subtitle: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetSubtitle: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Producers: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Publisher: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetPublisher: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Writers: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Year: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetYear: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IStorageItemContentProperties, IStorageItemContentProperties_Vtbl, 0x05294bad_bc38_48bf_85d7_770e0e2ae0ba); +impl windows_core::RuntimeType for IStorageItemContentProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IStorageItemContentProperties { + const NAME: &'static str = "Windows.Storage.FileProperties.IStorageItemContentProperties"; +} +pub trait IStorageItemContentProperties_Impl: IStorageItemExtraProperties_Impl { + fn GetMusicPropertiesAsync(&self) -> windows_core::Result>; + fn GetVideoPropertiesAsync(&self) -> windows_core::Result>; + fn GetImagePropertiesAsync(&self) -> windows_core::Result>; + fn GetDocumentPropertiesAsync(&self) -> windows_core::Result>; +} +impl IStorageItemContentProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetMusicPropertiesAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemContentProperties_Impl::GetMusicPropertiesAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetVideoPropertiesAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemContentProperties_Impl::GetVideoPropertiesAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetImagePropertiesAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemContentProperties_Impl::GetImagePropertiesAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDocumentPropertiesAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemContentProperties_Impl::GetDocumentPropertiesAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetMusicPropertiesAsync: GetMusicPropertiesAsync::, + GetVideoPropertiesAsync: GetVideoPropertiesAsync::, + GetImagePropertiesAsync: GetImagePropertiesAsync::, + GetDocumentPropertiesAsync: GetDocumentPropertiesAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IStorageItemContentProperties_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub GetMusicPropertiesAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetVideoPropertiesAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetImagePropertiesAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetDocumentPropertiesAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IStorageItemExtraProperties, IStorageItemExtraProperties_Vtbl, 0xc54361b2_54cd_432b_bdbc_4b19c4b470d7); +impl windows_core::RuntimeType for IStorageItemExtraProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IStorageItemExtraProperties, windows_core::IUnknown, windows_core::IInspectable); +impl IStorageItemExtraProperties { + pub fn RetrievePropertiesAsync(&self, propertiestoretrieve: P0) -> windows_core::Result>> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RetrievePropertiesAsync)(windows_core::Interface::as_raw(this), propertiestoretrieve.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SavePropertiesAsync(&self, propertiestosave: P0) -> windows_core::Result + where + P0: windows_core::Param>>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SavePropertiesAsync)(windows_core::Interface::as_raw(this), propertiestosave.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SavePropertiesAsyncOverloadDefault(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SavePropertiesAsyncOverloadDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeName for IStorageItemExtraProperties { + const NAME: &'static str = "Windows.Storage.FileProperties.IStorageItemExtraProperties"; +} +pub trait IStorageItemExtraProperties_Impl: windows_core::IUnknownImpl { + fn RetrievePropertiesAsync(&self, propertiesToRetrieve: windows_core::Ref<'_, windows_collections::IIterable>) -> windows_core::Result>>; + fn SavePropertiesAsync(&self, propertiesToSave: windows_core::Ref<'_, windows_collections::IIterable>>) -> windows_core::Result; + fn SavePropertiesAsyncOverloadDefault(&self) -> windows_core::Result; +} +impl IStorageItemExtraProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn RetrievePropertiesAsync(this: *mut core::ffi::c_void, propertiestoretrieve: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemExtraProperties_Impl::RetrievePropertiesAsync(this, core::mem::transmute_copy(&propertiestoretrieve)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SavePropertiesAsync(this: *mut core::ffi::c_void, propertiestosave: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemExtraProperties_Impl::SavePropertiesAsync(this, core::mem::transmute_copy(&propertiestosave)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SavePropertiesAsyncOverloadDefault(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemExtraProperties_Impl::SavePropertiesAsyncOverloadDefault(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + RetrievePropertiesAsync: RetrievePropertiesAsync::, + SavePropertiesAsync: SavePropertiesAsync::, + SavePropertiesAsyncOverloadDefault: SavePropertiesAsyncOverloadDefault::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IStorageItemExtraProperties_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub RetrievePropertiesAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SavePropertiesAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SavePropertiesAsyncOverloadDefault: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IThumbnailProperties, IThumbnailProperties_Vtbl, 0x693dd42f_dbe7_49b5_b3b3_2893ac5d3423); +impl windows_core::RuntimeType for IThumbnailProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IThumbnailProperties { + const NAME: &'static str = "Windows.Storage.FileProperties.IThumbnailProperties"; +} +pub trait IThumbnailProperties_Impl: windows_core::IUnknownImpl { + fn OriginalWidth(&self) -> windows_core::Result; + fn OriginalHeight(&self) -> windows_core::Result; + fn ReturnedSmallerCachedSize(&self) -> windows_core::Result; + fn Type(&self) -> windows_core::Result; +} +impl IThumbnailProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn OriginalWidth(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IThumbnailProperties_Impl::OriginalWidth(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OriginalHeight(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IThumbnailProperties_Impl::OriginalHeight(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReturnedSmallerCachedSize(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IThumbnailProperties_Impl::ReturnedSmallerCachedSize(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Type(this: *mut core::ffi::c_void, result__: *mut ThumbnailType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IThumbnailProperties_Impl::Type(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + OriginalWidth: OriginalWidth::, + OriginalHeight: OriginalHeight::, + ReturnedSmallerCachedSize: ReturnedSmallerCachedSize::, + Type: Type::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IThumbnailProperties_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub OriginalWidth: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub OriginalHeight: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub ReturnedSmallerCachedSize: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Type: unsafe extern "system" fn(*mut core::ffi::c_void, *mut ThumbnailType) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IVideoProperties, IVideoProperties_Vtbl, 0x719ae507_68de_4db8_97de_49998c059f2f); +impl windows_core::RuntimeType for IVideoProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IVideoProperties { + const NAME: &'static str = "Windows.Storage.FileProperties.IVideoProperties"; +} +pub trait IVideoProperties_Impl: IStorageItemExtraProperties_Impl { + fn Rating(&self) -> windows_core::Result; + fn SetRating(&self, value: u32) -> windows_core::Result<()>; + fn Keywords(&self) -> windows_core::Result>; + fn Width(&self) -> windows_core::Result; + fn Height(&self) -> windows_core::Result; + fn Duration(&self) -> windows_core::Result; + fn Latitude(&self) -> windows_core::Result>; + fn Longitude(&self) -> windows_core::Result>; + fn Title(&self) -> windows_core::Result; + fn SetTitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Subtitle(&self) -> windows_core::Result; + fn SetSubtitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Producers(&self) -> windows_core::Result>; + fn Publisher(&self) -> windows_core::Result; + fn SetPublisher(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Writers(&self) -> windows_core::Result>; + fn Year(&self) -> windows_core::Result; + fn SetYear(&self, value: u32) -> windows_core::Result<()>; + fn Bitrate(&self) -> windows_core::Result; + fn Directors(&self) -> windows_core::Result>; + fn Orientation(&self) -> windows_core::Result; +} +impl IVideoProperties_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Rating(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Rating(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRating(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVideoProperties_Impl::SetRating(this, value).into() + } + } + unsafe extern "system" fn Keywords(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Keywords(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Width(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Width(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Height(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Height(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Duration(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Duration(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Latitude(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Latitude(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Longitude(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Longitude(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Title(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Title(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetTitle(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVideoProperties_Impl::SetTitle(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Subtitle(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Subtitle(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetSubtitle(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVideoProperties_Impl::SetSubtitle(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Producers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Producers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Publisher(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Publisher(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPublisher(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVideoProperties_Impl::SetPublisher(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Writers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Writers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Year(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Year(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetYear(this: *mut core::ffi::c_void, value: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IVideoProperties_Impl::SetYear(this, value).into() + } + } + unsafe extern "system" fn Bitrate(this: *mut core::ffi::c_void, result__: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Bitrate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Directors(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Directors(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Orientation(this: *mut core::ffi::c_void, result__: *mut VideoOrientation) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IVideoProperties_Impl::Orientation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Rating: Rating::, + SetRating: SetRating::, + Keywords: Keywords::, + Width: Width::, + Height: Height::, + Duration: Duration::, + Latitude: Latitude::, + Longitude: Longitude::, + Title: Title::, + SetTitle: SetTitle::, + Subtitle: Subtitle::, + SetSubtitle: SetSubtitle::, + Producers: Producers::, + Publisher: Publisher::, + SetPublisher: SetPublisher::, + Writers: Writers::, + Year: Year::, + SetYear: SetYear::, + Bitrate: Bitrate::, + Directors: Directors::, + Orientation: Orientation::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IVideoProperties_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub Rating: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetRating: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub Keywords: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Width: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Height: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Duration: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::TimeSpan) -> windows_core::HRESULT, + pub Latitude: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Longitude: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Title: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetTitle: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Subtitle: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetSubtitle: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Producers: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Publisher: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetPublisher: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Writers: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Year: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetYear: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub Bitrate: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub Directors: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Orientation: unsafe extern "system" fn(*mut core::ffi::c_void, *mut VideoOrientation) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ImageProperties(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(ImageProperties, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(ImageProperties, IStorageItemExtraProperties); +impl ImageProperties { + pub fn Rating(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Rating)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetRating(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetRating)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Keywords(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Keywords)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DateTaken(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DateTaken)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetDateTaken(&self, value: super::super::Foundation::DateTime) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDateTaken)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Width(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Width)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Height(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Height)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Title(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Title)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetTitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetTitle)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Latitude(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Latitude)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Longitude(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Longitude)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CameraManufacturer(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CameraManufacturer)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetCameraManufacturer(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetCameraManufacturer)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn CameraModel(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CameraModel)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetCameraModel(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetCameraModel)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Orientation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Orientation)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn PeopleNames(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PeopleNames)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RetrievePropertiesAsync(&self, propertiestoretrieve: P0) -> windows_core::Result>> + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RetrievePropertiesAsync)(windows_core::Interface::as_raw(this), propertiestoretrieve.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SavePropertiesAsync(&self, propertiestosave: P0) -> windows_core::Result + where + P0: windows_core::Param>>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SavePropertiesAsync)(windows_core::Interface::as_raw(this), propertiestosave.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SavePropertiesAsyncOverloadDefault(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SavePropertiesAsyncOverloadDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for ImageProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for ImageProperties { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for ImageProperties { + const NAME: &'static str = "Windows.Storage.FileProperties.ImageProperties"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MusicProperties(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(MusicProperties, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(MusicProperties, IStorageItemExtraProperties); +impl MusicProperties { + pub fn Album(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Album)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetAlbum(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAlbum)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Artist(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Artist)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetArtist(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetArtist)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Genre(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Genre)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TrackNumber(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrackNumber)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetTrackNumber(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetTrackNumber)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Title(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Title)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetTitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetTitle)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Rating(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Rating)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetRating(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetRating)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Duration(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Duration)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Bitrate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Bitrate)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn AlbumArtist(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AlbumArtist)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetAlbumArtist(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAlbumArtist)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Composers(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Composers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Conductors(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Conductors)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Subtitle(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Subtitle)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetSubtitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSubtitle)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Producers(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Producers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Publisher(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Publisher)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetPublisher(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPublisher)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Writers(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Writers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Year(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Year)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetYear(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetYear)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn RetrievePropertiesAsync(&self, propertiestoretrieve: P0) -> windows_core::Result>> + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RetrievePropertiesAsync)(windows_core::Interface::as_raw(this), propertiestoretrieve.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SavePropertiesAsync(&self, propertiestosave: P0) -> windows_core::Result + where + P0: windows_core::Param>>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SavePropertiesAsync)(windows_core::Interface::as_raw(this), propertiestosave.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SavePropertiesAsyncOverloadDefault(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SavePropertiesAsyncOverloadDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for MusicProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for MusicProperties { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for MusicProperties { + const NAME: &'static str = "Windows.Storage.FileProperties.MusicProperties"; +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct PhotoOrientation(pub i32); +impl PhotoOrientation { + pub const Unspecified: Self = Self(0i32); + pub const Normal: Self = Self(1i32); + pub const FlipHorizontal: Self = Self(2i32); + pub const Rotate180: Self = Self(3i32); + pub const FlipVertical: Self = Self(4i32); + pub const Transpose: Self = Self(5i32); + pub const Rotate270: Self = Self(6i32); + pub const Transverse: Self = Self(7i32); + pub const Rotate90: Self = Self(8i32); +} +impl windows_core::TypeKind for PhotoOrientation { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for PhotoOrientation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Storage.FileProperties.PhotoOrientation;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct PropertyPrefetchOptions(pub u32); +impl PropertyPrefetchOptions { + pub const None: Self = Self(0u32); + pub const MusicProperties: Self = Self(1u32); + pub const VideoProperties: Self = Self(2u32); + pub const ImageProperties: Self = Self(4u32); + pub const DocumentProperties: Self = Self(8u32); + pub const BasicProperties: Self = Self(16u32); +} +impl windows_core::TypeKind for PropertyPrefetchOptions { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for PropertyPrefetchOptions { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Storage.FileProperties.PropertyPrefetchOptions;u4)"); +} +impl PropertyPrefetchOptions { + pub const fn contains(&self, other: Self) -> bool { + self.0 & other.0 == other.0 + } +} +impl core::ops::BitOr for PropertyPrefetchOptions { + type Output = Self; + fn bitor(self, other: Self) -> Self { + Self(self.0 | other.0) + } +} +impl core::ops::BitAnd for PropertyPrefetchOptions { + type Output = Self; + fn bitand(self, other: Self) -> Self { + Self(self.0 & other.0) + } +} +impl core::ops::BitOrAssign for PropertyPrefetchOptions { + fn bitor_assign(&mut self, other: Self) { + self.0.bitor_assign(other.0) + } +} +impl core::ops::BitAndAssign for PropertyPrefetchOptions { + fn bitand_assign(&mut self, other: Self) { + self.0.bitand_assign(other.0) + } +} +impl core::ops::Not for PropertyPrefetchOptions { + type Output = Self; + fn not(self) -> Self { + Self(self.0.not()) + } +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct StorageItemContentProperties(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(StorageItemContentProperties, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(StorageItemContentProperties, IStorageItemExtraProperties); +impl StorageItemContentProperties { + pub fn GetMusicPropertiesAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMusicPropertiesAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetVideoPropertiesAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetVideoPropertiesAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetImagePropertiesAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetImagePropertiesAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetDocumentPropertiesAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDocumentPropertiesAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RetrievePropertiesAsync(&self, propertiestoretrieve: P0) -> windows_core::Result>> + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RetrievePropertiesAsync)(windows_core::Interface::as_raw(this), propertiestoretrieve.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SavePropertiesAsync(&self, propertiestosave: P0) -> windows_core::Result + where + P0: windows_core::Param>>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SavePropertiesAsync)(windows_core::Interface::as_raw(this), propertiestosave.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SavePropertiesAsyncOverloadDefault(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SavePropertiesAsyncOverloadDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} +impl windows_core::RuntimeType for StorageItemContentProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for StorageItemContentProperties { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for StorageItemContentProperties { + const NAME: &'static str = "Windows.Storage.FileProperties.StorageItemContentProperties"; +} +#[cfg(feature = "Storage_Streams")] +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct StorageItemThumbnail(windows_core::IUnknown); +#[cfg(feature = "Storage_Streams")] +windows_core::imp::interface_hierarchy!(StorageItemThumbnail, windows_core::IUnknown, windows_core::IInspectable, super::Streams::IRandomAccessStreamWithContentType); +#[cfg(feature = "Storage_Streams")] +windows_core::imp::required_hierarchy!(StorageItemThumbnail, super::super::Foundation::IClosable, super::Streams::IContentTypeProvider, super::Streams::IInputStream, super::Streams::IOutputStream, super::Streams::IRandomAccessStream); +#[cfg(feature = "Storage_Streams")] +impl StorageItemThumbnail { + pub fn Close(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn ContentType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn ReadAsync(&self, buffer: P0, count: u32, options: super::Streams::InputStreamOptions) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), count, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn WriteAsync(&self, buffer: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn FlushAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FlushAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetSize(&self, value: u64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetSize)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn GetInputStreamAt(&self, position: u64) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetOutputStreamAt(&self, position: u64) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetOutputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Position(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Position)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Seek(&self, position: u64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Seek)(windows_core::Interface::as_raw(this), position).ok() } + } + pub fn CloneStream(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CloneStream)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CanRead(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanRead)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CanWrite(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanWrite)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn OriginalWidth(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OriginalWidth)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn OriginalHeight(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OriginalHeight)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReturnedSmallerCachedSize(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReturnedSmallerCachedSize)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Type(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeType for StorageItemThumbnail { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +#[cfg(feature = "Storage_Streams")] +unsafe impl windows_core::Interface for StorageItemThumbnail { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for StorageItemThumbnail { + const NAME: &'static str = "Windows.Storage.FileProperties.StorageItemThumbnail"; +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct ThumbnailMode(pub i32); +impl ThumbnailMode { + pub const PicturesView: Self = Self(0i32); + pub const VideosView: Self = Self(1i32); + pub const MusicView: Self = Self(2i32); + pub const DocumentsView: Self = Self(3i32); + pub const ListView: Self = Self(4i32); + pub const SingleItem: Self = Self(5i32); +} +impl windows_core::TypeKind for ThumbnailMode { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for ThumbnailMode { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Storage.FileProperties.ThumbnailMode;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct ThumbnailOptions(pub u32); +impl ThumbnailOptions { + pub const None: Self = Self(0u32); + pub const ReturnOnlyIfCached: Self = Self(1u32); + pub const ResizeThumbnail: Self = Self(2u32); + pub const UseCurrentScale: Self = Self(4u32); +} +impl windows_core::TypeKind for ThumbnailOptions { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for ThumbnailOptions { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Storage.FileProperties.ThumbnailOptions;u4)"); +} +impl ThumbnailOptions { + pub const fn contains(&self, other: Self) -> bool { + self.0 & other.0 == other.0 + } +} +impl core::ops::BitOr for ThumbnailOptions { + type Output = Self; + fn bitor(self, other: Self) -> Self { + Self(self.0 | other.0) + } +} +impl core::ops::BitAnd for ThumbnailOptions { + type Output = Self; + fn bitand(self, other: Self) -> Self { + Self(self.0 & other.0) + } +} +impl core::ops::BitOrAssign for ThumbnailOptions { + fn bitor_assign(&mut self, other: Self) { + self.0.bitor_assign(other.0) + } +} +impl core::ops::BitAndAssign for ThumbnailOptions { + fn bitand_assign(&mut self, other: Self) { + self.0.bitand_assign(other.0) + } +} +impl core::ops::Not for ThumbnailOptions { + type Output = Self; + fn not(self) -> Self { + Self(self.0.not()) + } +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct ThumbnailType(pub i32); +impl ThumbnailType { + pub const Image: Self = Self(0i32); + pub const Icon: Self = Self(1i32); +} +impl windows_core::TypeKind for ThumbnailType { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for ThumbnailType { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Storage.FileProperties.ThumbnailType;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct VideoOrientation(pub i32); +impl VideoOrientation { + pub const Normal: Self = Self(0i32); + pub const Rotate90: Self = Self(90i32); + pub const Rotate180: Self = Self(180i32); + pub const Rotate270: Self = Self(270i32); +} +impl windows_core::TypeKind for VideoOrientation { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for VideoOrientation { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Storage.FileProperties.VideoOrientation;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VideoProperties(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(VideoProperties, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(VideoProperties, IStorageItemExtraProperties); +impl VideoProperties { + pub fn RetrievePropertiesAsync(&self, propertiestoretrieve: P0) -> windows_core::Result>> + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RetrievePropertiesAsync)(windows_core::Interface::as_raw(this), propertiestoretrieve.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SavePropertiesAsync(&self, propertiestosave: P0) -> windows_core::Result + where + P0: windows_core::Param>>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SavePropertiesAsync)(windows_core::Interface::as_raw(this), propertiestosave.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SavePropertiesAsyncOverloadDefault(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SavePropertiesAsyncOverloadDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Rating(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Rating)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetRating(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetRating)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Keywords(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Keywords)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Width(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Width)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Height(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Height)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Duration(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Duration)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Latitude(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Latitude)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Longitude(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Longitude)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Title(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Title)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetTitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetTitle)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Subtitle(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Subtitle)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetSubtitle(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSubtitle)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Producers(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Producers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Publisher(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Publisher)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetPublisher(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPublisher)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Writers(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Writers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Year(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Year)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetYear(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetYear)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Bitrate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Bitrate)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Directors(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Directors)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Orientation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Orientation)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} +impl windows_core::RuntimeType for VideoProperties { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for VideoProperties { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for VideoProperties { + const NAME: &'static str = "Windows.Storage.FileProperties.VideoProperties"; +} +} +#[cfg(feature = "Storage_Search")] +pub mod Search{ +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct CommonFileQuery(pub i32); +impl CommonFileQuery { + pub const DefaultQuery: Self = Self(0i32); + pub const OrderByName: Self = Self(1i32); + pub const OrderByTitle: Self = Self(2i32); + pub const OrderByMusicProperties: Self = Self(3i32); + pub const OrderBySearchRank: Self = Self(4i32); + pub const OrderByDate: Self = Self(5i32); +} +impl windows_core::TypeKind for CommonFileQuery { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for CommonFileQuery { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Storage.Search.CommonFileQuery;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct CommonFolderQuery(pub i32); +impl CommonFolderQuery { + pub const DefaultQuery: Self = Self(0i32); + pub const GroupByYear: Self = Self(100i32); + pub const GroupByMonth: Self = Self(101i32); + pub const GroupByArtist: Self = Self(102i32); + pub const GroupByAlbum: Self = Self(103i32); + pub const GroupByAlbumArtist: Self = Self(104i32); + pub const GroupByComposer: Self = Self(105i32); + pub const GroupByGenre: Self = Self(106i32); + pub const GroupByPublishedYear: Self = Self(107i32); + pub const GroupByRating: Self = Self(108i32); + pub const GroupByTag: Self = Self(109i32); + pub const GroupByAuthor: Self = Self(110i32); + pub const GroupByType: Self = Self(111i32); +} +impl windows_core::TypeKind for CommonFolderQuery { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for CommonFolderQuery { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Storage.Search.CommonFolderQuery;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct DateStackOption(pub i32); +impl DateStackOption { + pub const None: Self = Self(0i32); + pub const Year: Self = Self(1i32); + pub const Month: Self = Self(2i32); +} +impl windows_core::TypeKind for DateStackOption { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for DateStackOption { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Storage.Search.DateStackOption;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct FolderDepth(pub i32); +impl FolderDepth { + pub const Shallow: Self = Self(0i32); + pub const Deep: Self = Self(1i32); +} +impl windows_core::TypeKind for FolderDepth { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for FolderDepth { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Storage.Search.FolderDepth;i4)"); +} +windows_core::imp::define_interface!(IQueryOptions, IQueryOptions_Vtbl, 0x1e5e46ee_0f45_4838_a8e9_d0479d446c30); +impl windows_core::RuntimeType for IQueryOptions { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_FileProperties")] +impl windows_core::RuntimeName for IQueryOptions { + const NAME: &'static str = "Windows.Storage.Search.IQueryOptions"; +} +#[cfg(feature = "Storage_FileProperties")] +pub trait IQueryOptions_Impl: windows_core::IUnknownImpl { + fn FileTypeFilter(&self) -> windows_core::Result>; + fn FolderDepth(&self) -> windows_core::Result; + fn SetFolderDepth(&self, value: FolderDepth) -> windows_core::Result<()>; + fn ApplicationSearchFilter(&self) -> windows_core::Result; + fn SetApplicationSearchFilter(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn UserSearchFilter(&self) -> windows_core::Result; + fn SetUserSearchFilter(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Language(&self) -> windows_core::Result; + fn SetLanguage(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn IndexerOption(&self) -> windows_core::Result; + fn SetIndexerOption(&self, value: IndexerOption) -> windows_core::Result<()>; + fn SortOrder(&self) -> windows_core::Result>; + fn GroupPropertyName(&self) -> windows_core::Result; + fn DateStackOption(&self) -> windows_core::Result; + fn SaveToString(&self) -> windows_core::Result; + fn LoadFromString(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn SetThumbnailPrefetch(&self, mode: super::FileProperties::ThumbnailMode, requestedSize: u32, options: super::FileProperties::ThumbnailOptions) -> windows_core::Result<()>; + fn SetPropertyPrefetch(&self, options: super::FileProperties::PropertyPrefetchOptions, propertiesToRetrieve: windows_core::Ref<'_, windows_collections::IIterable>) -> windows_core::Result<()>; +} +#[cfg(feature = "Storage_FileProperties")] +impl IQueryOptions_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FileTypeFilter(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IQueryOptions_Impl::FileTypeFilter(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FolderDepth(this: *mut core::ffi::c_void, result__: *mut FolderDepth) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IQueryOptions_Impl::FolderDepth(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetFolderDepth(this: *mut core::ffi::c_void, value: FolderDepth) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IQueryOptions_Impl::SetFolderDepth(this, value).into() + } + } + unsafe extern "system" fn ApplicationSearchFilter(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IQueryOptions_Impl::ApplicationSearchFilter(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetApplicationSearchFilter(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IQueryOptions_Impl::SetApplicationSearchFilter(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn UserSearchFilter(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IQueryOptions_Impl::UserSearchFilter(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetUserSearchFilter(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IQueryOptions_Impl::SetUserSearchFilter(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Language(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IQueryOptions_Impl::Language(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetLanguage(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IQueryOptions_Impl::SetLanguage(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn IndexerOption(this: *mut core::ffi::c_void, result__: *mut IndexerOption) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IQueryOptions_Impl::IndexerOption(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetIndexerOption(this: *mut core::ffi::c_void, value: IndexerOption) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IQueryOptions_Impl::SetIndexerOption(this, value).into() + } + } + unsafe extern "system" fn SortOrder(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IQueryOptions_Impl::SortOrder(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GroupPropertyName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IQueryOptions_Impl::GroupPropertyName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DateStackOption(this: *mut core::ffi::c_void, result__: *mut DateStackOption) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IQueryOptions_Impl::DateStackOption(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SaveToString(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IQueryOptions_Impl::SaveToString(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn LoadFromString(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IQueryOptions_Impl::LoadFromString(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn SetThumbnailPrefetch(this: *mut core::ffi::c_void, mode: super::FileProperties::ThumbnailMode, requestedsize: u32, options: super::FileProperties::ThumbnailOptions) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IQueryOptions_Impl::SetThumbnailPrefetch(this, mode, requestedsize, options).into() + } + } + unsafe extern "system" fn SetPropertyPrefetch(this: *mut core::ffi::c_void, options: super::FileProperties::PropertyPrefetchOptions, propertiestoretrieve: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IQueryOptions_Impl::SetPropertyPrefetch(this, options, core::mem::transmute_copy(&propertiestoretrieve)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FileTypeFilter: FileTypeFilter::, + FolderDepth: FolderDepth::, + SetFolderDepth: SetFolderDepth::, + ApplicationSearchFilter: ApplicationSearchFilter::, + SetApplicationSearchFilter: SetApplicationSearchFilter::, + UserSearchFilter: UserSearchFilter::, + SetUserSearchFilter: SetUserSearchFilter::, + Language: Language::, + SetLanguage: SetLanguage::, + IndexerOption: IndexerOption::, + SetIndexerOption: SetIndexerOption::, + SortOrder: SortOrder::, + GroupPropertyName: GroupPropertyName::, + DateStackOption: DateStackOption::, + SaveToString: SaveToString::, + LoadFromString: LoadFromString::, + SetThumbnailPrefetch: SetThumbnailPrefetch::, + SetPropertyPrefetch: SetPropertyPrefetch::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IQueryOptions_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub FileTypeFilter: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub FolderDepth: unsafe extern "system" fn(*mut core::ffi::c_void, *mut FolderDepth) -> windows_core::HRESULT, + pub SetFolderDepth: unsafe extern "system" fn(*mut core::ffi::c_void, FolderDepth) -> windows_core::HRESULT, + pub ApplicationSearchFilter: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetApplicationSearchFilter: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub UserSearchFilter: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetUserSearchFilter: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Language: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SetLanguage: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub IndexerOption: unsafe extern "system" fn(*mut core::ffi::c_void, *mut IndexerOption) -> windows_core::HRESULT, + pub SetIndexerOption: unsafe extern "system" fn(*mut core::ffi::c_void, IndexerOption) -> windows_core::HRESULT, + pub SortOrder: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GroupPropertyName: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub DateStackOption: unsafe extern "system" fn(*mut core::ffi::c_void, *mut DateStackOption) -> windows_core::HRESULT, + pub SaveToString: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub LoadFromString: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Storage_FileProperties")] + pub SetThumbnailPrefetch: unsafe extern "system" fn(*mut core::ffi::c_void, super::FileProperties::ThumbnailMode, u32, super::FileProperties::ThumbnailOptions) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_FileProperties"))] + SetThumbnailPrefetch: usize, + #[cfg(feature = "Storage_FileProperties")] + pub SetPropertyPrefetch: unsafe extern "system" fn(*mut core::ffi::c_void, super::FileProperties::PropertyPrefetchOptions, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_FileProperties"))] + SetPropertyPrefetch: usize, +} +windows_core::imp::define_interface!(IQueryOptionsFactory, IQueryOptionsFactory_Vtbl, 0x032e1f8c_a9c1_4e71_8011_0dee9d4811a3); +impl windows_core::RuntimeType for IQueryOptionsFactory { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IQueryOptionsFactory { + const NAME: &'static str = "Windows.Storage.Search.IQueryOptionsFactory"; +} +pub trait IQueryOptionsFactory_Impl: windows_core::IUnknownImpl { + fn CreateCommonFileQuery(&self, query: CommonFileQuery, fileTypeFilter: windows_core::Ref<'_, windows_collections::IIterable>) -> windows_core::Result; + fn CreateCommonFolderQuery(&self, query: CommonFolderQuery) -> windows_core::Result; +} +impl IQueryOptionsFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateCommonFileQuery(this: *mut core::ffi::c_void, query: CommonFileQuery, filetypefilter: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IQueryOptionsFactory_Impl::CreateCommonFileQuery(this, query, core::mem::transmute_copy(&filetypefilter)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateCommonFolderQuery(this: *mut core::ffi::c_void, query: CommonFolderQuery, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IQueryOptionsFactory_Impl::CreateCommonFolderQuery(this, query) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateCommonFileQuery: CreateCommonFileQuery::, + CreateCommonFolderQuery: CreateCommonFolderQuery::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IQueryOptionsFactory_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub CreateCommonFileQuery: unsafe extern "system" fn(*mut core::ffi::c_void, CommonFileQuery, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateCommonFolderQuery: unsafe extern "system" fn(*mut core::ffi::c_void, CommonFolderQuery, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IQueryOptionsWithProviderFilter, IQueryOptionsWithProviderFilter_Vtbl, 0x5b9d1026_15c4_44dd_b89a_47a59b7d7c4f); +impl windows_core::RuntimeType for IQueryOptionsWithProviderFilter { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IQueryOptionsWithProviderFilter { + const NAME: &'static str = "Windows.Storage.Search.IQueryOptionsWithProviderFilter"; +} +pub trait IQueryOptionsWithProviderFilter_Impl: windows_core::IUnknownImpl { + fn StorageProviderIdFilter(&self) -> windows_core::Result>; +} +impl IQueryOptionsWithProviderFilter_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn StorageProviderIdFilter(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IQueryOptionsWithProviderFilter_Impl::StorageProviderIdFilter(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + StorageProviderIdFilter: StorageProviderIdFilter::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IQueryOptionsWithProviderFilter_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub StorageProviderIdFilter: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IStorageFileQueryResult, IStorageFileQueryResult_Vtbl, 0x52fda447_2baa_412c_b29f_d4b1778efa1e); +impl windows_core::RuntimeType for IStorageFileQueryResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IStorageFileQueryResult { + const NAME: &'static str = "Windows.Storage.Search.IStorageFileQueryResult"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IStorageFileQueryResult_Impl: IStorageQueryResultBase_Impl { + fn GetFilesAsync(&self, startIndex: u32, maxNumberOfItems: u32) -> windows_core::Result>>; + fn GetFilesAsyncDefaultStartAndCount(&self) -> windows_core::Result>>; +} +#[cfg(feature = "Storage_Streams")] +impl IStorageFileQueryResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetFilesAsync(this: *mut core::ffi::c_void, startindex: u32, maxnumberofitems: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFileQueryResult_Impl::GetFilesAsync(this, startindex, maxnumberofitems) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetFilesAsyncDefaultStartAndCount(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFileQueryResult_Impl::GetFilesAsyncDefaultStartAndCount(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetFilesAsync: GetFilesAsync::, + GetFilesAsyncDefaultStartAndCount: GetFilesAsyncDefaultStartAndCount::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IStorageFileQueryResult_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(feature = "Storage_Streams")] + pub GetFilesAsync: unsafe extern "system" fn(*mut core::ffi::c_void, u32, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + GetFilesAsync: usize, + #[cfg(feature = "Storage_Streams")] + pub GetFilesAsyncDefaultStartAndCount: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + GetFilesAsyncDefaultStartAndCount: usize, +} +windows_core::imp::define_interface!(IStorageFileQueryResult2, IStorageFileQueryResult2_Vtbl, 0x4e5db9dd_7141_46c4_8be3_e9dc9e27275c); +impl windows_core::RuntimeType for IStorageFileQueryResult2 { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +#[cfg(all(feature = "Data_Text", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IStorageFileQueryResult2 { + const NAME: &'static str = "Windows.Storage.Search.IStorageFileQueryResult2"; +} +#[cfg(all(feature = "Data_Text", feature = "Storage_Streams"))] +pub trait IStorageFileQueryResult2_Impl: IStorageQueryResultBase_Impl { + fn GetMatchingPropertiesWithRanges(&self, file: windows_core::Ref<'_, super::StorageFile>) -> windows_core::Result>>; +} +#[cfg(all(feature = "Data_Text", feature = "Storage_Streams"))] +impl IStorageFileQueryResult2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetMatchingPropertiesWithRanges(this: *mut core::ffi::c_void, file: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFileQueryResult2_Impl::GetMatchingPropertiesWithRanges(this, core::mem::transmute_copy(&file)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetMatchingPropertiesWithRanges: GetMatchingPropertiesWithRanges::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IStorageFileQueryResult2_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + #[cfg(all(feature = "Data_Text", feature = "Storage_Streams"))] + pub GetMatchingPropertiesWithRanges: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Data_Text", feature = "Storage_Streams")))] + GetMatchingPropertiesWithRanges: usize, +} +windows_core::imp::define_interface!(IStorageFolderQueryOperations, IStorageFolderQueryOperations_Vtbl, 0xcb43ccc9_446b_4a4f_be97_757771be5203); +impl windows_core::RuntimeType for IStorageFolderQueryOperations { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IStorageFolderQueryOperations, windows_core::IUnknown, windows_core::IInspectable); +impl IStorageFolderQueryOperations { + pub fn GetIndexedStateAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetIndexedStateAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFileQueryOverloadDefault(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFileQueryOverloadDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFileQuery(&self, query: CommonFileQuery) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFileQuery)(windows_core::Interface::as_raw(this), query, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFileQueryWithOptions(&self, queryoptions: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFileQueryWithOptions)(windows_core::Interface::as_raw(this), queryoptions.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFolderQueryOverloadDefault(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFolderQueryOverloadDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFolderQuery(&self, query: CommonFolderQuery) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFolderQuery)(windows_core::Interface::as_raw(this), query, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFolderQueryWithOptions(&self, queryoptions: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFolderQueryWithOptions)(windows_core::Interface::as_raw(this), queryoptions.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateItemQuery(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateItemQuery)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateItemQueryWithOptions(&self, queryoptions: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateItemQueryWithOptions)(windows_core::Interface::as_raw(this), queryoptions.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetFilesAsync(&self, query: CommonFileQuery, startindex: u32, maxitemstoretrieve: u32) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFilesAsync)(windows_core::Interface::as_raw(this), query, startindex, maxitemstoretrieve, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetFilesAsyncOverloadDefaultStartAndCount(&self, query: CommonFileQuery) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFilesAsyncOverloadDefaultStartAndCount)(windows_core::Interface::as_raw(this), query, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetFoldersAsync(&self, query: CommonFolderQuery, startindex: u32, maxitemstoretrieve: u32) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFoldersAsync)(windows_core::Interface::as_raw(this), query, startindex, maxitemstoretrieve, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetFoldersAsyncOverloadDefaultStartAndCount(&self, query: CommonFolderQuery) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFoldersAsyncOverloadDefaultStartAndCount)(windows_core::Interface::as_raw(this), query, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetItemsAsync(&self, startindex: u32, maxitemstoretrieve: u32) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetItemsAsync)(windows_core::Interface::as_raw(this), startindex, maxitemstoretrieve, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn AreQueryOptionsSupported(&self, queryoptions: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AreQueryOptionsSupported)(windows_core::Interface::as_raw(this), queryoptions.param().abi(), &mut result__).map(|| result__) + } + } + pub fn IsCommonFolderQuerySupported(&self, query: CommonFolderQuery) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsCommonFolderQuerySupported)(windows_core::Interface::as_raw(this), query, &mut result__).map(|| result__) + } + } + pub fn IsCommonFileQuerySupported(&self, query: CommonFileQuery) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsCommonFileQuerySupported)(windows_core::Interface::as_raw(this), query, &mut result__).map(|| result__) + } + } +} +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IStorageFolderQueryOperations { + const NAME: &'static str = "Windows.Storage.Search.IStorageFolderQueryOperations"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IStorageFolderQueryOperations_Impl: windows_core::IUnknownImpl { + fn GetIndexedStateAsync(&self) -> windows_core::Result>; + fn CreateFileQueryOverloadDefault(&self) -> windows_core::Result; + fn CreateFileQuery(&self, query: CommonFileQuery) -> windows_core::Result; + fn CreateFileQueryWithOptions(&self, queryOptions: windows_core::Ref<'_, QueryOptions>) -> windows_core::Result; + fn CreateFolderQueryOverloadDefault(&self) -> windows_core::Result; + fn CreateFolderQuery(&self, query: CommonFolderQuery) -> windows_core::Result; + fn CreateFolderQueryWithOptions(&self, queryOptions: windows_core::Ref<'_, QueryOptions>) -> windows_core::Result; + fn CreateItemQuery(&self) -> windows_core::Result; + fn CreateItemQueryWithOptions(&self, queryOptions: windows_core::Ref<'_, QueryOptions>) -> windows_core::Result; + fn GetFilesAsync(&self, query: CommonFileQuery, startIndex: u32, maxItemsToRetrieve: u32) -> windows_core::Result>>; + fn GetFilesAsyncOverloadDefaultStartAndCount(&self, query: CommonFileQuery) -> windows_core::Result>>; + fn GetFoldersAsync(&self, query: CommonFolderQuery, startIndex: u32, maxItemsToRetrieve: u32) -> windows_core::Result>>; + fn GetFoldersAsyncOverloadDefaultStartAndCount(&self, query: CommonFolderQuery) -> windows_core::Result>>; + fn GetItemsAsync(&self, startIndex: u32, maxItemsToRetrieve: u32) -> windows_core::Result>>; + fn AreQueryOptionsSupported(&self, queryOptions: windows_core::Ref<'_, QueryOptions>) -> windows_core::Result; + fn IsCommonFolderQuerySupported(&self, query: CommonFolderQuery) -> windows_core::Result; + fn IsCommonFileQuerySupported(&self, query: CommonFileQuery) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IStorageFolderQueryOperations_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetIndexedStateAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::GetIndexedStateAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFileQueryOverloadDefault(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::CreateFileQueryOverloadDefault(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFileQuery(this: *mut core::ffi::c_void, query: CommonFileQuery, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::CreateFileQuery(this, query) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFileQueryWithOptions(this: *mut core::ffi::c_void, queryoptions: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::CreateFileQueryWithOptions(this, core::mem::transmute_copy(&queryoptions)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFolderQueryOverloadDefault(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::CreateFolderQueryOverloadDefault(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFolderQuery(this: *mut core::ffi::c_void, query: CommonFolderQuery, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::CreateFolderQuery(this, query) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFolderQueryWithOptions(this: *mut core::ffi::c_void, queryoptions: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::CreateFolderQueryWithOptions(this, core::mem::transmute_copy(&queryoptions)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateItemQuery(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::CreateItemQuery(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateItemQueryWithOptions(this: *mut core::ffi::c_void, queryoptions: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::CreateItemQueryWithOptions(this, core::mem::transmute_copy(&queryoptions)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetFilesAsync(this: *mut core::ffi::c_void, query: CommonFileQuery, startindex: u32, maxitemstoretrieve: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::GetFilesAsync(this, query, startindex, maxitemstoretrieve) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetFilesAsyncOverloadDefaultStartAndCount(this: *mut core::ffi::c_void, query: CommonFileQuery, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::GetFilesAsyncOverloadDefaultStartAndCount(this, query) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetFoldersAsync(this: *mut core::ffi::c_void, query: CommonFolderQuery, startindex: u32, maxitemstoretrieve: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::GetFoldersAsync(this, query, startindex, maxitemstoretrieve) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetFoldersAsyncOverloadDefaultStartAndCount(this: *mut core::ffi::c_void, query: CommonFolderQuery, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::GetFoldersAsyncOverloadDefaultStartAndCount(this, query) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetItemsAsync(this: *mut core::ffi::c_void, startindex: u32, maxitemstoretrieve: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::GetItemsAsync(this, startindex, maxitemstoretrieve) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AreQueryOptionsSupported(this: *mut core::ffi::c_void, queryoptions: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::AreQueryOptionsSupported(this, core::mem::transmute_copy(&queryoptions)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsCommonFolderQuerySupported(this: *mut core::ffi::c_void, query: CommonFolderQuery, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::IsCommonFolderQuerySupported(this, query) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsCommonFileQuerySupported(this: *mut core::ffi::c_void, query: CommonFileQuery, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryOperations_Impl::IsCommonFileQuerySupported(this, query) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetIndexedStateAsync: GetIndexedStateAsync::, + CreateFileQueryOverloadDefault: CreateFileQueryOverloadDefault::, + CreateFileQuery: CreateFileQuery::, + CreateFileQueryWithOptions: CreateFileQueryWithOptions::, + CreateFolderQueryOverloadDefault: CreateFolderQueryOverloadDefault::, + CreateFolderQuery: CreateFolderQuery::, + CreateFolderQueryWithOptions: CreateFolderQueryWithOptions::, + CreateItemQuery: CreateItemQuery::, + CreateItemQueryWithOptions: CreateItemQueryWithOptions::, + GetFilesAsync: GetFilesAsync::, + GetFilesAsyncOverloadDefaultStartAndCount: GetFilesAsyncOverloadDefaultStartAndCount::, + GetFoldersAsync: GetFoldersAsync::, + GetFoldersAsyncOverloadDefaultStartAndCount: GetFoldersAsyncOverloadDefaultStartAndCount::, + GetItemsAsync: GetItemsAsync::, + AreQueryOptionsSupported: AreQueryOptionsSupported::, + IsCommonFolderQuerySupported: IsCommonFolderQuerySupported::, + IsCommonFileQuerySupported: IsCommonFileQuerySupported::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IStorageFolderQueryOperations_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub GetIndexedStateAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateFileQueryOverloadDefault: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateFileQuery: unsafe extern "system" fn(*mut core::ffi::c_void, CommonFileQuery, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateFileQueryWithOptions: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateFolderQueryOverloadDefault: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateFolderQuery: unsafe extern "system" fn(*mut core::ffi::c_void, CommonFolderQuery, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateFolderQueryWithOptions: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateItemQuery: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub CreateItemQueryWithOptions: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "Storage_Streams")] + pub GetFilesAsync: unsafe extern "system" fn(*mut core::ffi::c_void, CommonFileQuery, u32, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + GetFilesAsync: usize, + #[cfg(feature = "Storage_Streams")] + pub GetFilesAsyncOverloadDefaultStartAndCount: unsafe extern "system" fn(*mut core::ffi::c_void, CommonFileQuery, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Storage_Streams"))] + GetFilesAsyncOverloadDefaultStartAndCount: usize, + pub GetFoldersAsync: unsafe extern "system" fn(*mut core::ffi::c_void, CommonFolderQuery, u32, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetFoldersAsyncOverloadDefaultStartAndCount: unsafe extern "system" fn(*mut core::ffi::c_void, CommonFolderQuery, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetItemsAsync: unsafe extern "system" fn(*mut core::ffi::c_void, u32, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub AreQueryOptionsSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub IsCommonFolderQuerySupported: unsafe extern "system" fn(*mut core::ffi::c_void, CommonFolderQuery, *mut bool) -> windows_core::HRESULT, + pub IsCommonFileQuerySupported: unsafe extern "system" fn(*mut core::ffi::c_void, CommonFileQuery, *mut bool) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IStorageFolderQueryResult, IStorageFolderQueryResult_Vtbl, 0x6654c911_7d66_46fa_aecf_e4a4baa93ab8); +impl windows_core::RuntimeType for IStorageFolderQueryResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IStorageFolderQueryResult { + const NAME: &'static str = "Windows.Storage.Search.IStorageFolderQueryResult"; +} +pub trait IStorageFolderQueryResult_Impl: IStorageQueryResultBase_Impl { + fn GetFoldersAsync(&self, startIndex: u32, maxNumberOfItems: u32) -> windows_core::Result>>; + fn GetFoldersAsyncDefaultStartAndCount(&self) -> windows_core::Result>>; +} +impl IStorageFolderQueryResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetFoldersAsync(this: *mut core::ffi::c_void, startindex: u32, maxnumberofitems: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryResult_Impl::GetFoldersAsync(this, startindex, maxnumberofitems) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetFoldersAsyncDefaultStartAndCount(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageFolderQueryResult_Impl::GetFoldersAsyncDefaultStartAndCount(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetFoldersAsync: GetFoldersAsync::, + GetFoldersAsyncDefaultStartAndCount: GetFoldersAsyncDefaultStartAndCount::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IStorageFolderQueryResult_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub GetFoldersAsync: unsafe extern "system" fn(*mut core::ffi::c_void, u32, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetFoldersAsyncDefaultStartAndCount: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IStorageItemQueryResult, IStorageItemQueryResult_Vtbl, 0xe8948079_9d58_47b8_b2b2_41b07f4795f9); +impl windows_core::RuntimeType for IStorageItemQueryResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IStorageItemQueryResult { + const NAME: &'static str = "Windows.Storage.Search.IStorageItemQueryResult"; +} +pub trait IStorageItemQueryResult_Impl: IStorageQueryResultBase_Impl { + fn GetItemsAsync(&self, startIndex: u32, maxNumberOfItems: u32) -> windows_core::Result>>; + fn GetItemsAsyncDefaultStartAndCount(&self) -> windows_core::Result>>; +} +impl IStorageItemQueryResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetItemsAsync(this: *mut core::ffi::c_void, startindex: u32, maxnumberofitems: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemQueryResult_Impl::GetItemsAsync(this, startindex, maxnumberofitems) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetItemsAsyncDefaultStartAndCount(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageItemQueryResult_Impl::GetItemsAsyncDefaultStartAndCount(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetItemsAsync: GetItemsAsync::, + GetItemsAsyncDefaultStartAndCount: GetItemsAsyncDefaultStartAndCount::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IStorageItemQueryResult_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub GetItemsAsync: unsafe extern "system" fn(*mut core::ffi::c_void, u32, u32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetItemsAsyncDefaultStartAndCount: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IStorageQueryResultBase, IStorageQueryResultBase_Vtbl, 0xc297d70d_7353_47ab_ba58_8c61425dc54b); +impl windows_core::RuntimeType for IStorageQueryResultBase { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IStorageQueryResultBase, windows_core::IUnknown, windows_core::IInspectable); +impl IStorageQueryResultBase { + pub fn GetItemCountAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetItemCountAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Folder(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Folder)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ContentsChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentsChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveContentsChanged(&self, eventcookie: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveContentsChanged)(windows_core::Interface::as_raw(this), eventcookie).ok() } + } + pub fn OptionsChanged(&self, changedhandler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OptionsChanged)(windows_core::Interface::as_raw(this), changedhandler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveOptionsChanged(&self, eventcookie: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveOptionsChanged)(windows_core::Interface::as_raw(this), eventcookie).ok() } + } + pub fn FindStartIndexAsync(&self, value: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindStartIndexAsync)(windows_core::Interface::as_raw(this), value.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetCurrentQueryOptions(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentQueryOptions)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ApplyNewQueryOptions(&self, newqueryoptions: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ApplyNewQueryOptions)(windows_core::Interface::as_raw(this), newqueryoptions.param().abi()).ok() } + } +} +impl windows_core::RuntimeName for IStorageQueryResultBase { + const NAME: &'static str = "Windows.Storage.Search.IStorageQueryResultBase"; +} +pub trait IStorageQueryResultBase_Impl: windows_core::IUnknownImpl { + fn GetItemCountAsync(&self) -> windows_core::Result>; + fn Folder(&self) -> windows_core::Result; + fn ContentsChanged(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveContentsChanged(&self, eventCookie: i64) -> windows_core::Result<()>; + fn OptionsChanged(&self, changedHandler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveOptionsChanged(&self, eventCookie: i64) -> windows_core::Result<()>; + fn FindStartIndexAsync(&self, value: windows_core::Ref<'_, windows_core::IInspectable>) -> windows_core::Result>; + fn GetCurrentQueryOptions(&self) -> windows_core::Result; + fn ApplyNewQueryOptions(&self, newQueryOptions: windows_core::Ref<'_, QueryOptions>) -> windows_core::Result<()>; +} +impl IStorageQueryResultBase_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetItemCountAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageQueryResultBase_Impl::GetItemCountAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Folder(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageQueryResultBase_Impl::Folder(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ContentsChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageQueryResultBase_Impl::ContentsChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveContentsChanged(this: *mut core::ffi::c_void, eventcookie: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStorageQueryResultBase_Impl::RemoveContentsChanged(this, eventcookie).into() + } + } + unsafe extern "system" fn OptionsChanged(this: *mut core::ffi::c_void, changedhandler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageQueryResultBase_Impl::OptionsChanged(this, core::mem::transmute_copy(&changedhandler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveOptionsChanged(this: *mut core::ffi::c_void, eventcookie: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStorageQueryResultBase_Impl::RemoveOptionsChanged(this, eventcookie).into() + } + } + unsafe extern "system" fn FindStartIndexAsync(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageQueryResultBase_Impl::FindStartIndexAsync(this, core::mem::transmute_copy(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetCurrentQueryOptions(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IStorageQueryResultBase_Impl::GetCurrentQueryOptions(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ApplyNewQueryOptions(this: *mut core::ffi::c_void, newqueryoptions: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IStorageQueryResultBase_Impl::ApplyNewQueryOptions(this, core::mem::transmute_copy(&newqueryoptions)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetItemCountAsync: GetItemCountAsync::, + Folder: Folder::, + ContentsChanged: ContentsChanged::, + RemoveContentsChanged: RemoveContentsChanged::, + OptionsChanged: OptionsChanged::, + RemoveOptionsChanged: RemoveOptionsChanged::, + FindStartIndexAsync: FindStartIndexAsync::, + GetCurrentQueryOptions: GetCurrentQueryOptions::, + ApplyNewQueryOptions: ApplyNewQueryOptions::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IStorageQueryResultBase_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub GetItemCountAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Folder: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ContentsChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveContentsChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub OptionsChanged: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveOptionsChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, + pub FindStartIndexAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetCurrentQueryOptions: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub ApplyNewQueryOptions: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct IndexedState(pub i32); +impl IndexedState { + pub const Unknown: Self = Self(0i32); + pub const NotIndexed: Self = Self(1i32); + pub const PartiallyIndexed: Self = Self(2i32); + pub const FullyIndexed: Self = Self(3i32); +} +impl windows_core::TypeKind for IndexedState { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for IndexedState { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Storage.Search.IndexedState;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct IndexerOption(pub i32); +impl IndexerOption { + pub const UseIndexerWhenAvailable: Self = Self(0i32); + pub const OnlyUseIndexer: Self = Self(1i32); + pub const DoNotUseIndexer: Self = Self(2i32); + pub const OnlyUseIndexerAndOptimizeForIndexedProperties: Self = Self(3i32); +} +impl windows_core::TypeKind for IndexerOption { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for IndexerOption { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Storage.Search.IndexerOption;i4)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct QueryOptions(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(QueryOptions, windows_core::IUnknown, windows_core::IInspectable); +impl QueryOptions { + pub fn new() -> windows_core::Result { + Self::IActivationFactory(|f| f.ActivateInstance::()) + } + fn IActivationFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } + pub fn FileTypeFilter(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FileTypeFilter)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn FolderDepth(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FolderDepth)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetFolderDepth(&self, value: FolderDepth) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetFolderDepth)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ApplicationSearchFilter(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ApplicationSearchFilter)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetApplicationSearchFilter(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetApplicationSearchFilter)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn UserSearchFilter(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UserSearchFilter)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetUserSearchFilter(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetUserSearchFilter)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Language(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Language)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetLanguage(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetLanguage)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn IndexerOption(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexerOption)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetIndexerOption(&self, value: IndexerOption) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetIndexerOption)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn SortOrder(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SortOrder)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GroupPropertyName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GroupPropertyName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn DateStackOption(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DateStackOption)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SaveToString(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SaveToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn LoadFromString(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).LoadFromString)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn SetThumbnailPrefetch(&self, mode: super::FileProperties::ThumbnailMode, requestedsize: u32, options: super::FileProperties::ThumbnailOptions) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetThumbnailPrefetch)(windows_core::Interface::as_raw(this), mode, requestedsize, options).ok() } + } + #[cfg(feature = "Storage_FileProperties")] + pub fn SetPropertyPrefetch(&self, options: super::FileProperties::PropertyPrefetchOptions, propertiestoretrieve: P1) -> windows_core::Result<()> + where + P1: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetPropertyPrefetch)(windows_core::Interface::as_raw(this), options, propertiestoretrieve.param().abi()).ok() } + } + pub fn CreateCommonFileQuery(query: CommonFileQuery, filetypefilter: P1) -> windows_core::Result + where + P1: windows_core::Param>, + { + Self::IQueryOptionsFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateCommonFileQuery)(windows_core::Interface::as_raw(this), query, filetypefilter.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateCommonFolderQuery(query: CommonFolderQuery) -> windows_core::Result { + Self::IQueryOptionsFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateCommonFolderQuery)(windows_core::Interface::as_raw(this), query, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn StorageProviderIdFilter(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StorageProviderIdFilter)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + fn IQueryOptionsFactory windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for QueryOptions { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for QueryOptions { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for QueryOptions { + const NAME: &'static str = "Windows.Storage.Search.QueryOptions"; +} +unsafe impl Send for QueryOptions {} +unsafe impl Sync for QueryOptions {} +#[repr(C)] +#[derive(Clone, Debug, Default, PartialEq)] +pub struct SortEntry { + pub PropertyName: windows_core::HSTRING, + pub AscendingOrder: bool, +} +impl windows_core::TypeKind for SortEntry { + type TypeKind = windows_core::CloneType; +} +impl windows_core::RuntimeType for SortEntry { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"struct(Windows.Storage.Search.SortEntry;string;b1)"); +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct StorageFileQueryResult(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(StorageFileQueryResult, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(StorageFileQueryResult, IStorageQueryResultBase); +impl StorageFileQueryResult { + #[cfg(feature = "Storage_Streams")] + pub fn GetFilesAsync(&self, startindex: u32, maxnumberofitems: u32) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFilesAsync)(windows_core::Interface::as_raw(this), startindex, maxnumberofitems, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetFilesAsyncDefaultStartAndCount(&self) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFilesAsyncDefaultStartAndCount)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Data_Text", feature = "Storage_Streams"))] + pub fn GetMatchingPropertiesWithRanges(&self, file: P0) -> windows_core::Result>> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMatchingPropertiesWithRanges)(windows_core::Interface::as_raw(this), file.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetItemCountAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetItemCountAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Folder(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Folder)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ContentsChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentsChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveContentsChanged(&self, eventcookie: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveContentsChanged)(windows_core::Interface::as_raw(this), eventcookie).ok() } + } + pub fn OptionsChanged(&self, changedhandler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OptionsChanged)(windows_core::Interface::as_raw(this), changedhandler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveOptionsChanged(&self, eventcookie: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveOptionsChanged)(windows_core::Interface::as_raw(this), eventcookie).ok() } + } + pub fn FindStartIndexAsync(&self, value: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindStartIndexAsync)(windows_core::Interface::as_raw(this), value.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetCurrentQueryOptions(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentQueryOptions)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ApplyNewQueryOptions(&self, newqueryoptions: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).ApplyNewQueryOptions)(windows_core::Interface::as_raw(this), newqueryoptions.param().abi()).ok() } + } +} +impl windows_core::RuntimeType for StorageFileQueryResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for StorageFileQueryResult { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for StorageFileQueryResult { + const NAME: &'static str = "Windows.Storage.Search.StorageFileQueryResult"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct StorageFolderQueryResult(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(StorageFolderQueryResult, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(StorageFolderQueryResult, IStorageQueryResultBase); +impl StorageFolderQueryResult { + pub fn GetFoldersAsync(&self, startindex: u32, maxnumberofitems: u32) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFoldersAsync)(windows_core::Interface::as_raw(this), startindex, maxnumberofitems, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetFoldersAsyncDefaultStartAndCount(&self) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFoldersAsyncDefaultStartAndCount)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetItemCountAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetItemCountAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Folder(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Folder)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ContentsChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentsChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveContentsChanged(&self, eventcookie: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveContentsChanged)(windows_core::Interface::as_raw(this), eventcookie).ok() } + } + pub fn OptionsChanged(&self, changedhandler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OptionsChanged)(windows_core::Interface::as_raw(this), changedhandler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveOptionsChanged(&self, eventcookie: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveOptionsChanged)(windows_core::Interface::as_raw(this), eventcookie).ok() } + } + pub fn FindStartIndexAsync(&self, value: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindStartIndexAsync)(windows_core::Interface::as_raw(this), value.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetCurrentQueryOptions(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentQueryOptions)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ApplyNewQueryOptions(&self, newqueryoptions: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).ApplyNewQueryOptions)(windows_core::Interface::as_raw(this), newqueryoptions.param().abi()).ok() } + } +} +impl windows_core::RuntimeType for StorageFolderQueryResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for StorageFolderQueryResult { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for StorageFolderQueryResult { + const NAME: &'static str = "Windows.Storage.Search.StorageFolderQueryResult"; +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct StorageItemQueryResult(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(StorageItemQueryResult, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(StorageItemQueryResult, IStorageQueryResultBase); +impl StorageItemQueryResult { + pub fn GetItemsAsync(&self, startindex: u32, maxnumberofitems: u32) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetItemsAsync)(windows_core::Interface::as_raw(this), startindex, maxnumberofitems, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetItemsAsyncDefaultStartAndCount(&self) -> windows_core::Result>> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetItemsAsyncDefaultStartAndCount)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetItemCountAsync(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetItemCountAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Folder(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Folder)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ContentsChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentsChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveContentsChanged(&self, eventcookie: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveContentsChanged)(windows_core::Interface::as_raw(this), eventcookie).ok() } + } + pub fn OptionsChanged(&self, changedhandler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OptionsChanged)(windows_core::Interface::as_raw(this), changedhandler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveOptionsChanged(&self, eventcookie: i64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveOptionsChanged)(windows_core::Interface::as_raw(this), eventcookie).ok() } + } + pub fn FindStartIndexAsync(&self, value: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindStartIndexAsync)(windows_core::Interface::as_raw(this), value.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetCurrentQueryOptions(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetCurrentQueryOptions)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ApplyNewQueryOptions(&self, newqueryoptions: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).ApplyNewQueryOptions)(windows_core::Interface::as_raw(this), newqueryoptions.param().abi()).ok() } + } +} +impl windows_core::RuntimeType for StorageItemQueryResult { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for StorageItemQueryResult { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for StorageItemQueryResult { + const NAME: &'static str = "Windows.Storage.Search.StorageItemQueryResult"; +} +} +#[cfg(feature = "Storage_Streams")] pub mod Streams{ #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] @@ -15172,12 +88210,34 @@ impl Buffer { (windows_core::Interface::vtable(this).Length)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) } } + pub fn SetLength(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetLength)(windows_core::Interface::as_raw(this), value).ok() } + } pub fn Create(capacity: u32) -> windows_core::Result { Self::IBufferFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), capacity, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn CreateCopyFromMemoryBuffer(input: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IBufferStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateCopyFromMemoryBuffer)(windows_core::Interface::as_raw(this), input.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateMemoryBufferOverIBuffer(input: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IBufferStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateMemoryBufferOverIBuffer)(windows_core::Interface::as_raw(this), input.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IBufferFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -15222,14 +88282,155 @@ impl DataReader { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn UnconsumedBufferLength(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UnconsumedBufferLength)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn UnicodeEncoding(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UnicodeEncoding)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetUnicodeEncoding(&self, value: UnicodeEncoding) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetUnicodeEncoding)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ByteOrder(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ByteOrder)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetByteOrder(&self, value: ByteOrder) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetByteOrder)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn InputStreamOptions(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InputStreamOptions)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn SetInputStreamOptions(&self, value: InputStreamOptions) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).SetInputStreamOptions)(windows_core::Interface::as_raw(this), value).ok() } } + pub fn ReadByte(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadByte)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn ReadBytes(&self, value: &mut [u8]) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).ReadBytes)(windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_mut_ptr()).ok() } } + pub fn ReadBuffer(&self, length: u32) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadBuffer)(windows_core::Interface::as_raw(this), length, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ReadBoolean(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadBoolean)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadGuid(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadGuid)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadInt16(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadInt16)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadInt32(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadInt32)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadInt64(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadInt64)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadUInt16(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadUInt16)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadUInt32(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadUInt32)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadUInt64(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadUInt64)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadSingle(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadSingle)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadDouble(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadDouble)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadString(&self, codeunitcount: u32) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadString)(windows_core::Interface::as_raw(this), codeunitcount, &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn ReadDateTime(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadDateTime)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadTimeSpan(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadTimeSpan)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn LoadAsync(&self, count: u32) -> windows_core::Result { let this = self; unsafe { @@ -15244,6 +88445,13 @@ impl DataReader { (windows_core::Interface::vtable(this).DetachBuffer)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn DetachStream(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DetachStream)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn CreateDataReader(inputstream: P0) -> windows_core::Result where P0: windows_core::Param, @@ -15301,10 +88509,119 @@ impl DataWriter { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn UnstoredBufferLength(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UnstoredBufferLength)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn UnicodeEncoding(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UnicodeEncoding)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetUnicodeEncoding(&self, value: UnicodeEncoding) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetUnicodeEncoding)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ByteOrder(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ByteOrder)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetByteOrder(&self, value: ByteOrder) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetByteOrder)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteByte(&self, value: u8) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteByte)(windows_core::Interface::as_raw(this), value).ok() } + } pub fn WriteBytes(&self, value: &[u8]) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).WriteBytes)(windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr()).ok() } } + pub fn WriteBuffer(&self, buffer: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteBuffer)(windows_core::Interface::as_raw(this), buffer.param().abi()).ok() } + } + pub fn WriteBufferRange(&self, buffer: P0, start: u32, count: u32) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteBufferRange)(windows_core::Interface::as_raw(this), buffer.param().abi(), start, count).ok() } + } + pub fn WriteBoolean(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteBoolean)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteGuid(&self, value: windows_core::GUID) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteGuid)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteInt16(&self, value: i16) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteInt16)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteInt32(&self, value: i32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteInt32)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteInt64(&self, value: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteInt64)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteUInt16(&self, value: u16) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteUInt16)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteUInt32(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteUInt32)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteUInt64(&self, value: u64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteUInt64)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteSingle(&self, value: f32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteSingle)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteDouble(&self, value: f64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteDouble)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteDateTime(&self, value: super::super::Foundation::DateTime) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteDateTime)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteTimeSpan(&self, value: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteTimeSpan)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteString(&self, value: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteString)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value), &mut result__).map(|| result__) + } + } + pub fn MeasureString(&self, value: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MeasureString)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value), &mut result__).map(|| result__) + } + } pub fn StoreAsync(&self) -> windows_core::Result { let this = self; unsafe { @@ -15326,6 +88643,13 @@ impl DataWriter { (windows_core::Interface::vtable(this).DetachBuffer)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn DetachStream(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DetachStream)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn CreateDataWriter(outputstream: P0) -> windows_core::Result where P0: windows_core::Param, @@ -15412,6 +88736,16 @@ impl FileOutputStream { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn WriteAsync(&self, buffer: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn FlushAsync(&self) -> windows_core::Result> { let this = self; unsafe { @@ -15442,6 +88776,70 @@ impl FileRandomAccessStream { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn OpenAsync(filepath: &windows_core::HSTRING, accessmode: super::FileAccessMode) -> windows_core::Result> { + Self::IFileRandomAccessStreamStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(filepath), accessmode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn OpenWithOptionsAsync(filepath: &windows_core::HSTRING, accessmode: super::FileAccessMode, sharingoptions: super::StorageOpenOptions, opendisposition: FileOpenDisposition) -> windows_core::Result> { + Self::IFileRandomAccessStreamStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenWithOptionsAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(filepath), accessmode, sharingoptions, opendisposition, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn OpenTransactedWriteAsync(filepath: &windows_core::HSTRING) -> windows_core::Result> { + Self::IFileRandomAccessStreamStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenTransactedWriteAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(filepath), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn OpenTransactedWriteWithOptionsAsync(filepath: &windows_core::HSTRING, openoptions: super::StorageOpenOptions, opendisposition: FileOpenDisposition) -> windows_core::Result> { + Self::IFileRandomAccessStreamStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenTransactedWriteWithOptionsAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(filepath), openoptions, opendisposition, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "System")] + pub fn OpenForUserAsync(user: P0, filepath: &windows_core::HSTRING, accessmode: super::FileAccessMode) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::IFileRandomAccessStreamStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenForUserAsync)(windows_core::Interface::as_raw(this), user.param().abi(), core::mem::transmute_copy(filepath), accessmode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "System")] + pub fn OpenForUserWithOptionsAsync(user: P0, filepath: &windows_core::HSTRING, accessmode: super::FileAccessMode, sharingoptions: super::StorageOpenOptions, opendisposition: FileOpenDisposition) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::IFileRandomAccessStreamStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenForUserWithOptionsAsync)(windows_core::Interface::as_raw(this), user.param().abi(), core::mem::transmute_copy(filepath), accessmode, sharingoptions, opendisposition, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "System")] + pub fn OpenTransactedWriteForUserAsync(user: P0, filepath: &windows_core::HSTRING) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::IFileRandomAccessStreamStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenTransactedWriteForUserAsync)(windows_core::Interface::as_raw(this), user.param().abi(), core::mem::transmute_copy(filepath), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "System")] + pub fn OpenTransactedWriteForUserWithOptionsAsync(user: P0, filepath: &windows_core::HSTRING, openoptions: super::StorageOpenOptions, opendisposition: FileOpenDisposition) -> windows_core::Result> + where + P0: windows_core::Param, + { + Self::IFileRandomAccessStreamStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenTransactedWriteForUserWithOptionsAsync)(windows_core::Interface::as_raw(this), user.param().abi(), core::mem::transmute_copy(filepath), openoptions, opendisposition, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn ReadAsync(&self, buffer: P0, count: u32, options: InputStreamOptions) -> windows_core::Result> where P0: windows_core::Param, @@ -15452,6 +88850,16 @@ impl FileRandomAccessStream { (windows_core::Interface::vtable(this).ReadAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), count, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn WriteAsync(&self, buffer: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn FlushAsync(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::(self)?; unsafe { @@ -15459,6 +88867,24 @@ impl FileRandomAccessStream { (windows_core::Interface::vtable(this).FlushAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Size(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetSize(&self, value: u64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSize)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn GetInputStreamAt(&self, position: u64) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn GetOutputStreamAt(&self, position: u64) -> windows_core::Result { let this = self; unsafe { @@ -15466,10 +88892,38 @@ impl FileRandomAccessStream { (windows_core::Interface::vtable(this).GetOutputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Position(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Position)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Seek(&self, position: u64) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).Seek)(windows_core::Interface::as_raw(this), position).ok() } } + pub fn CloneStream(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CloneStream)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CanRead(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanRead)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CanWrite(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanWrite)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } fn IFileRandomAccessStreamStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -15507,7 +88961,11 @@ impl IBuffer { (windows_core::Interface::vtable(this).Length)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) } } + pub fn SetLength(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetLength)(windows_core::Interface::as_raw(this), value).ok() } } +} impl windows_core::RuntimeName for IBuffer { const NAME: &'static str = "Windows.Storage.Streams.IBuffer"; } @@ -15571,6 +89029,33 @@ windows_core::imp::define_interface!(IBufferFactory, IBufferFactory_Vtbl, 0x71af impl windows_core::RuntimeType for IBufferFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBufferFactory { + const NAME: &'static str = "Windows.Storage.Streams.IBufferFactory"; +} +pub trait IBufferFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, capacity: u32) -> windows_core::Result; +} +impl IBufferFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, capacity: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBufferFactory_Impl::Create(this, capacity) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBufferFactory_Vtbl { @@ -15581,6 +89066,51 @@ windows_core::imp::define_interface!(IBufferStatics, IBufferStatics_Vtbl, 0xe901 impl windows_core::RuntimeType for IBufferStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IBufferStatics { + const NAME: &'static str = "Windows.Storage.Streams.IBufferStatics"; +} +pub trait IBufferStatics_Impl: windows_core::IUnknownImpl { + fn CreateCopyFromMemoryBuffer(&self, input: windows_core::Ref<'_, super::super::Foundation::IMemoryBuffer>) -> windows_core::Result; + fn CreateMemoryBufferOverIBuffer(&self, input: windows_core::Ref<'_, IBuffer>) -> windows_core::Result; +} +impl IBufferStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateCopyFromMemoryBuffer(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBufferStatics_Impl::CreateCopyFromMemoryBuffer(this, core::mem::transmute_copy(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateMemoryBufferOverIBuffer(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IBufferStatics_Impl::CreateMemoryBufferOverIBuffer(this, core::mem::transmute_copy(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateCopyFromMemoryBuffer: CreateCopyFromMemoryBuffer::, + CreateMemoryBufferOverIBuffer: CreateMemoryBufferOverIBuffer::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IBufferStatics_Vtbl { @@ -15593,6 +89123,15 @@ impl windows_core::RuntimeType for IContentTypeProvider { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } windows_core::imp::interface_hierarchy!(IContentTypeProvider, windows_core::IUnknown, windows_core::IInspectable); +impl IContentTypeProvider { + pub fn ContentType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} impl windows_core::RuntimeName for IContentTypeProvider { const NAME: &'static str = "Windows.Storage.Streams.IContentTypeProvider"; } @@ -15632,14 +89171,155 @@ impl windows_core::RuntimeType for IDataReader { } windows_core::imp::interface_hierarchy!(IDataReader, windows_core::IUnknown, windows_core::IInspectable); impl IDataReader { + pub fn UnconsumedBufferLength(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UnconsumedBufferLength)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn UnicodeEncoding(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UnicodeEncoding)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetUnicodeEncoding(&self, value: UnicodeEncoding) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetUnicodeEncoding)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ByteOrder(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ByteOrder)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetByteOrder(&self, value: ByteOrder) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetByteOrder)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn InputStreamOptions(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).InputStreamOptions)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn SetInputStreamOptions(&self, value: InputStreamOptions) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).SetInputStreamOptions)(windows_core::Interface::as_raw(this), value).ok() } } + pub fn ReadByte(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadByte)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn ReadBytes(&self, value: &mut [u8]) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).ReadBytes)(windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_mut_ptr()).ok() } } + pub fn ReadBuffer(&self, length: u32) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadBuffer)(windows_core::Interface::as_raw(this), length, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ReadBoolean(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadBoolean)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadGuid(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadGuid)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadInt16(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadInt16)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadInt32(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadInt32)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadInt64(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadInt64)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadUInt16(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadUInt16)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadUInt32(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadUInt32)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadUInt64(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadUInt64)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadSingle(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadSingle)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadDouble(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadDouble)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadString(&self, codeunitcount: u32) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadString)(windows_core::Interface::as_raw(this), codeunitcount, &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn ReadDateTime(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadDateTime)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReadTimeSpan(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadTimeSpan)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn LoadAsync(&self, count: u32) -> windows_core::Result { let this = self; unsafe { @@ -15654,7 +89334,14 @@ impl IDataReader { (windows_core::Interface::vtable(this).DetachBuffer)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn DetachStream(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DetachStream)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } +} impl windows_core::RuntimeName for IDataReader { const NAME: &'static str = "Windows.Storage.Streams.IDataReader"; } @@ -16050,6 +89737,33 @@ windows_core::imp::define_interface!(IDataReaderFactory, IDataReaderFactory_Vtbl impl windows_core::RuntimeType for IDataReaderFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDataReaderFactory { + const NAME: &'static str = "Windows.Storage.Streams.IDataReaderFactory"; +} +pub trait IDataReaderFactory_Impl: windows_core::IUnknownImpl { + fn CreateDataReader(&self, inputStream: windows_core::Ref<'_, IInputStream>) -> windows_core::Result; +} +impl IDataReaderFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateDataReader(this: *mut core::ffi::c_void, inputstream: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDataReaderFactory_Impl::CreateDataReader(this, core::mem::transmute_copy(&inputstream)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), CreateDataReader: CreateDataReader:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDataReaderFactory_Vtbl { @@ -16060,6 +89774,33 @@ windows_core::imp::define_interface!(IDataReaderStatics, IDataReaderStatics_Vtbl impl windows_core::RuntimeType for IDataReaderStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDataReaderStatics { + const NAME: &'static str = "Windows.Storage.Streams.IDataReaderStatics"; +} +pub trait IDataReaderStatics_Impl: windows_core::IUnknownImpl { + fn FromBuffer(&self, buffer: windows_core::Ref<'_, IBuffer>) -> windows_core::Result; +} +impl IDataReaderStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FromBuffer(this: *mut core::ffi::c_void, buffer: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDataReaderStatics_Impl::FromBuffer(this, core::mem::transmute_copy(&buffer)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), FromBuffer: FromBuffer:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDataReaderStatics_Vtbl { @@ -16072,10 +89813,119 @@ impl windows_core::RuntimeType for IDataWriter { } windows_core::imp::interface_hierarchy!(IDataWriter, windows_core::IUnknown, windows_core::IInspectable); impl IDataWriter { + pub fn UnstoredBufferLength(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UnstoredBufferLength)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn UnicodeEncoding(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UnicodeEncoding)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetUnicodeEncoding(&self, value: UnicodeEncoding) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetUnicodeEncoding)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn ByteOrder(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ByteOrder)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetByteOrder(&self, value: ByteOrder) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetByteOrder)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteByte(&self, value: u8) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteByte)(windows_core::Interface::as_raw(this), value).ok() } + } pub fn WriteBytes(&self, value: &[u8]) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).WriteBytes)(windows_core::Interface::as_raw(this), value.len().try_into().unwrap(), value.as_ptr()).ok() } } + pub fn WriteBuffer(&self, buffer: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteBuffer)(windows_core::Interface::as_raw(this), buffer.param().abi()).ok() } + } + pub fn WriteBufferRange(&self, buffer: P0, start: u32, count: u32) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteBufferRange)(windows_core::Interface::as_raw(this), buffer.param().abi(), start, count).ok() } + } + pub fn WriteBoolean(&self, value: bool) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteBoolean)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteGuid(&self, value: windows_core::GUID) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteGuid)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteInt16(&self, value: i16) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteInt16)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteInt32(&self, value: i32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteInt32)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteInt64(&self, value: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteInt64)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteUInt16(&self, value: u16) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteUInt16)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteUInt32(&self, value: u32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteUInt32)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteUInt64(&self, value: u64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteUInt64)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteSingle(&self, value: f32) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteSingle)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteDouble(&self, value: f64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteDouble)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteDateTime(&self, value: super::super::Foundation::DateTime) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteDateTime)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteTimeSpan(&self, value: super::super::Foundation::TimeSpan) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).WriteTimeSpan)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn WriteString(&self, value: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteString)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value), &mut result__).map(|| result__) + } + } + pub fn MeasureString(&self, value: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MeasureString)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value), &mut result__).map(|| result__) + } + } pub fn StoreAsync(&self) -> windows_core::Result { let this = self; unsafe { @@ -16097,7 +89947,14 @@ impl IDataWriter { (windows_core::Interface::vtable(this).DetachBuffer)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn DetachStream(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DetachStream)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } +} impl windows_core::RuntimeName for IDataWriter { const NAME: &'static str = "Windows.Storage.Streams.IDataWriter"; } @@ -16109,8 +89966,8 @@ pub trait IDataWriter_Impl: windows_core::IUnknownImpl { fn SetByteOrder(&self, value: ByteOrder) -> windows_core::Result<()>; fn WriteByte(&self, value: u8) -> windows_core::Result<()>; fn WriteBytes(&self, value: &[u8]) -> windows_core::Result<()>; - fn WriteBuffer(&self, buffer: windows_core::Ref) -> windows_core::Result<()>; - fn WriteBufferRange(&self, buffer: windows_core::Ref, start: u32, count: u32) -> windows_core::Result<()>; + fn WriteBuffer(&self, buffer: windows_core::Ref<'_, IBuffer>) -> windows_core::Result<()>; + fn WriteBufferRange(&self, buffer: windows_core::Ref<'_, IBuffer>, start: u32, count: u32) -> windows_core::Result<()>; fn WriteBoolean(&self, value: bool) -> windows_core::Result<()>; fn WriteGuid(&self, value: &windows_core::GUID) -> windows_core::Result<()>; fn WriteInt16(&self, value: i16) -> windows_core::Result<()>; @@ -16423,6 +90280,33 @@ windows_core::imp::define_interface!(IDataWriterFactory, IDataWriterFactory_Vtbl impl windows_core::RuntimeType for IDataWriterFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IDataWriterFactory { + const NAME: &'static str = "Windows.Storage.Streams.IDataWriterFactory"; +} +pub trait IDataWriterFactory_Impl: windows_core::IUnknownImpl { + fn CreateDataWriter(&self, outputStream: windows_core::Ref<'_, IOutputStream>) -> windows_core::Result; +} +impl IDataWriterFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateDataWriter(this: *mut core::ffi::c_void, outputstream: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDataWriterFactory_Impl::CreateDataWriter(this, core::mem::transmute_copy(&outputstream)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), CreateDataWriter: CreateDataWriter:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IDataWriterFactory_Vtbl { @@ -16433,6 +90317,144 @@ windows_core::imp::define_interface!(IFileRandomAccessStreamStatics, IFileRandom impl windows_core::RuntimeType for IFileRandomAccessStreamStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "System")] +impl windows_core::RuntimeName for IFileRandomAccessStreamStatics { + const NAME: &'static str = "Windows.Storage.Streams.IFileRandomAccessStreamStatics"; +} +#[cfg(feature = "System")] +pub trait IFileRandomAccessStreamStatics_Impl: windows_core::IUnknownImpl { + fn OpenAsync(&self, filePath: &windows_core::HSTRING, accessMode: super::FileAccessMode) -> windows_core::Result>; + fn OpenWithOptionsAsync(&self, filePath: &windows_core::HSTRING, accessMode: super::FileAccessMode, sharingOptions: super::StorageOpenOptions, openDisposition: FileOpenDisposition) -> windows_core::Result>; + fn OpenTransactedWriteAsync(&self, filePath: &windows_core::HSTRING) -> windows_core::Result>; + fn OpenTransactedWriteWithOptionsAsync(&self, filePath: &windows_core::HSTRING, openOptions: super::StorageOpenOptions, openDisposition: FileOpenDisposition) -> windows_core::Result>; + fn OpenForUserAsync(&self, user: windows_core::Ref<'_, super::super::System::User>, filePath: &windows_core::HSTRING, accessMode: super::FileAccessMode) -> windows_core::Result>; + fn OpenForUserWithOptionsAsync(&self, user: windows_core::Ref<'_, super::super::System::User>, filePath: &windows_core::HSTRING, accessMode: super::FileAccessMode, sharingOptions: super::StorageOpenOptions, openDisposition: FileOpenDisposition) -> windows_core::Result>; + fn OpenTransactedWriteForUserAsync(&self, user: windows_core::Ref<'_, super::super::System::User>, filePath: &windows_core::HSTRING) -> windows_core::Result>; + fn OpenTransactedWriteForUserWithOptionsAsync(&self, user: windows_core::Ref<'_, super::super::System::User>, filePath: &windows_core::HSTRING, openOptions: super::StorageOpenOptions, openDisposition: FileOpenDisposition) -> windows_core::Result>; +} +#[cfg(feature = "System")] +impl IFileRandomAccessStreamStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn OpenAsync(this: *mut core::ffi::c_void, filepath: *mut core::ffi::c_void, accessmode: super::FileAccessMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFileRandomAccessStreamStatics_Impl::OpenAsync(this, core::mem::transmute(&filepath), accessmode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OpenWithOptionsAsync(this: *mut core::ffi::c_void, filepath: *mut core::ffi::c_void, accessmode: super::FileAccessMode, sharingoptions: super::StorageOpenOptions, opendisposition: FileOpenDisposition, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFileRandomAccessStreamStatics_Impl::OpenWithOptionsAsync(this, core::mem::transmute(&filepath), accessmode, sharingoptions, opendisposition) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OpenTransactedWriteAsync(this: *mut core::ffi::c_void, filepath: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFileRandomAccessStreamStatics_Impl::OpenTransactedWriteAsync(this, core::mem::transmute(&filepath)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OpenTransactedWriteWithOptionsAsync(this: *mut core::ffi::c_void, filepath: *mut core::ffi::c_void, openoptions: super::StorageOpenOptions, opendisposition: FileOpenDisposition, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFileRandomAccessStreamStatics_Impl::OpenTransactedWriteWithOptionsAsync(this, core::mem::transmute(&filepath), openoptions, opendisposition) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OpenForUserAsync(this: *mut core::ffi::c_void, user: *mut core::ffi::c_void, filepath: *mut core::ffi::c_void, accessmode: super::FileAccessMode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFileRandomAccessStreamStatics_Impl::OpenForUserAsync(this, core::mem::transmute_copy(&user), core::mem::transmute(&filepath), accessmode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OpenForUserWithOptionsAsync(this: *mut core::ffi::c_void, user: *mut core::ffi::c_void, filepath: *mut core::ffi::c_void, accessmode: super::FileAccessMode, sharingoptions: super::StorageOpenOptions, opendisposition: FileOpenDisposition, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFileRandomAccessStreamStatics_Impl::OpenForUserWithOptionsAsync(this, core::mem::transmute_copy(&user), core::mem::transmute(&filepath), accessmode, sharingoptions, opendisposition) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OpenTransactedWriteForUserAsync(this: *mut core::ffi::c_void, user: *mut core::ffi::c_void, filepath: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFileRandomAccessStreamStatics_Impl::OpenTransactedWriteForUserAsync(this, core::mem::transmute_copy(&user), core::mem::transmute(&filepath)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn OpenTransactedWriteForUserWithOptionsAsync(this: *mut core::ffi::c_void, user: *mut core::ffi::c_void, filepath: *mut core::ffi::c_void, openoptions: super::StorageOpenOptions, opendisposition: FileOpenDisposition, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IFileRandomAccessStreamStatics_Impl::OpenTransactedWriteForUserWithOptionsAsync(this, core::mem::transmute_copy(&user), core::mem::transmute(&filepath), openoptions, opendisposition) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + OpenAsync: OpenAsync::, + OpenWithOptionsAsync: OpenWithOptionsAsync::, + OpenTransactedWriteAsync: OpenTransactedWriteAsync::, + OpenTransactedWriteWithOptionsAsync: OpenTransactedWriteWithOptionsAsync::, + OpenForUserAsync: OpenForUserAsync::, + OpenForUserWithOptionsAsync: OpenForUserWithOptionsAsync::, + OpenTransactedWriteForUserAsync: OpenTransactedWriteForUserAsync::, + OpenTransactedWriteForUserWithOptionsAsync: OpenTransactedWriteForUserWithOptionsAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IFileRandomAccessStreamStatics_Vtbl { @@ -16484,7 +90506,7 @@ impl windows_core::RuntimeName for IInputStream { const NAME: &'static str = "Windows.Storage.Streams.IInputStream"; } pub trait IInputStream_Impl: super::super::Foundation::IClosable_Impl { - fn ReadAsync(&self, buffer: windows_core::Ref, count: u32, options: InputStreamOptions) -> windows_core::Result>; + fn ReadAsync(&self, buffer: windows_core::Ref<'_, IBuffer>, count: u32, options: InputStreamOptions) -> windows_core::Result>; } impl IInputStream_Vtbl { pub const fn new() -> Self { @@ -16518,6 +90540,15 @@ impl windows_core::RuntimeType for IInputStreamReference { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } windows_core::imp::interface_hierarchy!(IInputStreamReference, windows_core::IUnknown, windows_core::IInspectable); +impl IInputStreamReference { + pub fn OpenSequentialReadAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenSequentialReadAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeName for IInputStreamReference { const NAME: &'static str = "Windows.Storage.Streams.IInputStreamReference"; } @@ -16561,6 +90592,16 @@ impl windows_core::RuntimeType for IOutputStream { windows_core::imp::interface_hierarchy!(IOutputStream, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(IOutputStream, super::super::Foundation::IClosable); impl IOutputStream { + pub fn WriteAsync(&self, buffer: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn FlushAsync(&self) -> windows_core::Result> { let this = self; unsafe { @@ -16577,7 +90618,7 @@ impl windows_core::RuntimeName for IOutputStream { const NAME: &'static str = "Windows.Storage.Streams.IOutputStream"; } pub trait IOutputStream_Impl: super::super::Foundation::IClosable_Impl { - fn WriteAsync(&self, buffer: windows_core::Ref) -> windows_core::Result>; + fn WriteAsync(&self, buffer: windows_core::Ref<'_, IBuffer>) -> windows_core::Result>; fn FlushAsync(&self) -> windows_core::Result>; } impl IOutputStream_Vtbl { @@ -16632,6 +90673,24 @@ impl windows_core::RuntimeType for IRandomAccessStream { windows_core::imp::interface_hierarchy!(IRandomAccessStream, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(IRandomAccessStream, super::super::Foundation::IClosable, IInputStream, IOutputStream); impl IRandomAccessStream { + pub fn Size(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetSize(&self, value: u64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSize)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn GetInputStreamAt(&self, position: u64) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn GetOutputStreamAt(&self, position: u64) -> windows_core::Result { let this = self; unsafe { @@ -16639,10 +90698,38 @@ impl IRandomAccessStream { (windows_core::Interface::vtable(this).GetOutputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Position(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Position)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Seek(&self, position: u64) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).Seek)(windows_core::Interface::as_raw(this), position).ok() } } + pub fn CloneStream(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CloneStream)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CanRead(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanRead)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CanWrite(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanWrite)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Close(&self) -> windows_core::Result<()> { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } @@ -16657,6 +90744,16 @@ impl IRandomAccessStream { (windows_core::Interface::vtable(this).ReadAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), count, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn WriteAsync(&self, buffer: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn FlushAsync(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::(self)?; unsafe { @@ -16816,6 +90913,15 @@ impl windows_core::RuntimeType for IRandomAccessStreamReference { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } windows_core::imp::interface_hierarchy!(IRandomAccessStreamReference, windows_core::IUnknown, windows_core::IInspectable); +impl IRandomAccessStreamReference { + pub fn OpenReadAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenReadAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeName for IRandomAccessStreamReference { const NAME: &'static str = "Windows.Storage.Streams.IRandomAccessStreamReference"; } @@ -16856,6 +90962,66 @@ windows_core::imp::define_interface!(IRandomAccessStreamReferenceStatics, IRando impl windows_core::RuntimeType for IRandomAccessStreamReferenceStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IRandomAccessStreamReferenceStatics { + const NAME: &'static str = "Windows.Storage.Streams.IRandomAccessStreamReferenceStatics"; +} +pub trait IRandomAccessStreamReferenceStatics_Impl: windows_core::IUnknownImpl { + fn CreateFromFile(&self, file: windows_core::Ref<'_, super::IStorageFile>) -> windows_core::Result; + fn CreateFromUri(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result; + fn CreateFromStream(&self, stream: windows_core::Ref<'_, IRandomAccessStream>) -> windows_core::Result; +} +impl IRandomAccessStreamReferenceStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromFile(this: *mut core::ffi::c_void, file: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRandomAccessStreamReferenceStatics_Impl::CreateFromFile(this, core::mem::transmute_copy(&file)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromUri(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRandomAccessStreamReferenceStatics_Impl::CreateFromUri(this, core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromStream(this: *mut core::ffi::c_void, stream: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IRandomAccessStreamReferenceStatics_Impl::CreateFromStream(this, core::mem::transmute_copy(&stream)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromFile: CreateFromFile::, + CreateFromUri: CreateFromUri::, + CreateFromStream: CreateFromStream::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IRandomAccessStreamReferenceStatics_Vtbl { @@ -16875,6 +91041,13 @@ impl IRandomAccessStreamWithContentType { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn ContentType(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } pub fn ReadAsync(&self, buffer: P0, count: u32, options: InputStreamOptions) -> windows_core::Result> where P0: windows_core::Param, @@ -16885,6 +91058,16 @@ impl IRandomAccessStreamWithContentType { (windows_core::Interface::vtable(this).ReadAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), count, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn WriteAsync(&self, buffer: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn FlushAsync(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::(self)?; unsafe { @@ -16892,6 +91075,24 @@ impl IRandomAccessStreamWithContentType { (windows_core::Interface::vtable(this).FlushAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetSize(&self, value: u64) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetSize)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn GetInputStreamAt(&self, position: u64) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn GetOutputStreamAt(&self, position: u64) -> windows_core::Result { let this = &windows_core::Interface::cast::(self)?; unsafe { @@ -16899,11 +91100,39 @@ impl IRandomAccessStreamWithContentType { (windows_core::Interface::vtable(this).GetOutputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Position(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Position)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Seek(&self, position: u64) -> windows_core::Result<()> { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Seek)(windows_core::Interface::as_raw(this), position).ok() } } + pub fn CloneStream(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CloneStream)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn CanRead(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanRead)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CanWrite(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanWrite)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeName for IRandomAccessStreamWithContentType { const NAME: &'static str = "Windows.Storage.Streams.IRandomAccessStreamWithContentType"; } @@ -16948,6 +91177,16 @@ impl InMemoryRandomAccessStream { (windows_core::Interface::vtable(this).ReadAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), count, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn WriteAsync(&self, buffer: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn FlushAsync(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::(self)?; unsafe { @@ -16955,6 +91194,24 @@ impl InMemoryRandomAccessStream { (windows_core::Interface::vtable(this).FlushAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Size(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetSize(&self, value: u64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSize)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn GetInputStreamAt(&self, position: u64) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn GetOutputStreamAt(&self, position: u64) -> windows_core::Result { let this = self; unsafe { @@ -16962,11 +91219,39 @@ impl InMemoryRandomAccessStream { (windows_core::Interface::vtable(this).GetOutputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Position(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Position)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Seek(&self, position: u64) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).Seek)(windows_core::Interface::as_raw(this), position).ok() } } + pub fn CloneStream(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CloneStream)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn CanRead(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanRead)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CanWrite(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanWrite)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for InMemoryRandomAccessStream { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -17069,6 +91354,16 @@ impl OutputStreamOverStream { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn WriteAsync(&self, buffer: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn FlushAsync(&self) -> windows_core::Result> { let this = self; unsafe { @@ -17109,6 +91404,16 @@ impl RandomAccessStreamOverStream { (windows_core::Interface::vtable(this).ReadAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), count, options, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn WriteAsync(&self, buffer: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteAsync)(windows_core::Interface::as_raw(this), buffer.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn FlushAsync(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::(self)?; unsafe { @@ -17116,6 +91421,24 @@ impl RandomAccessStreamOverStream { (windows_core::Interface::vtable(this).FlushAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Size(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetSize(&self, value: u64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSize)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn GetInputStreamAt(&self, position: u64) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn GetOutputStreamAt(&self, position: u64) -> windows_core::Result { let this = self; unsafe { @@ -17123,11 +91446,39 @@ impl RandomAccessStreamOverStream { (windows_core::Interface::vtable(this).GetOutputStreamAt)(windows_core::Interface::as_raw(this), position, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Position(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Position)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Seek(&self, position: u64) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).Seek)(windows_core::Interface::as_raw(this), position).ok() } } + pub fn CloneStream(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CloneStream)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub fn CanRead(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanRead)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CanWrite(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CanWrite)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for RandomAccessStreamOverStream { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -17145,6 +91496,40 @@ unsafe impl Sync for RandomAccessStreamOverStream {} pub struct RandomAccessStreamReference(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(RandomAccessStreamReference, windows_core::IUnknown, windows_core::IInspectable, IRandomAccessStreamReference); impl RandomAccessStreamReference { + pub fn OpenReadAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).OpenReadAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFromFile(file: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IRandomAccessStreamReferenceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromFile)(windows_core::Interface::as_raw(this), file.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromUri(uri: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IRandomAccessStreamReferenceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromUri)(windows_core::Interface::as_raw(this), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromStream(stream: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IRandomAccessStreamReferenceStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromStream)(windows_core::Interface::as_raw(this), stream.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IRandomAccessStreamReferenceStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -17178,11 +91563,118 @@ impl windows_core::RuntimeType for UnicodeEncoding { } } } +#[cfg(feature = "System")] pub mod System{ windows_core::imp::define_interface!(IUser, IUser_Vtbl, 0xdf9a26c6_e746_4bcd_b5d4_120103c4209b); impl windows_core::RuntimeType for IUser { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(all(feature = "Foundation_Collections", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IUser { + const NAME: &'static str = "Windows.System.IUser"; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Storage_Streams"))] +pub trait IUser_Impl: windows_core::IUnknownImpl { + fn NonRoamableId(&self) -> windows_core::Result; + fn AuthenticationStatus(&self) -> windows_core::Result; + fn Type(&self) -> windows_core::Result; + fn GetPropertyAsync(&self, value: &windows_core::HSTRING) -> windows_core::Result>; + fn GetPropertiesAsync(&self, values: windows_core::Ref<'_, windows_collections::IVectorView>) -> windows_core::Result>; + fn GetPictureAsync(&self, desiredSize: UserPictureSize) -> windows_core::Result>; +} +#[cfg(all(feature = "Foundation_Collections", feature = "Storage_Streams"))] +impl IUser_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn NonRoamableId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUser_Impl::NonRoamableId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AuthenticationStatus(this: *mut core::ffi::c_void, result__: *mut UserAuthenticationStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUser_Impl::AuthenticationStatus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Type(this: *mut core::ffi::c_void, result__: *mut UserType) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUser_Impl::Type(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetPropertyAsync(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUser_Impl::GetPropertyAsync(this, core::mem::transmute(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetPropertiesAsync(this: *mut core::ffi::c_void, values: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUser_Impl::GetPropertiesAsync(this, core::mem::transmute_copy(&values)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetPictureAsync(this: *mut core::ffi::c_void, desiredsize: UserPictureSize, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUser_Impl::GetPictureAsync(this, desiredsize) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + NonRoamableId: NonRoamableId::, + AuthenticationStatus: AuthenticationStatus::, + Type: Type::, + GetPropertyAsync: GetPropertyAsync::, + GetPropertiesAsync: GetPropertiesAsync::, + GetPictureAsync: GetPictureAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IUser_Vtbl { @@ -17204,6 +91696,36 @@ windows_core::imp::define_interface!(IUser2, IUser2_Vtbl, 0x98ba5628_a6e3_518e_8 impl windows_core::RuntimeType for IUser2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IUser2 { + const NAME: &'static str = "Windows.System.IUser2"; +} +pub trait IUser2_Impl: windows_core::IUnknownImpl { + fn CheckUserAgeConsentGroupAsync(&self, consentGroup: UserAgeConsentGroup) -> windows_core::Result>; +} +impl IUser2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CheckUserAgeConsentGroupAsync(this: *mut core::ffi::c_void, consentgroup: UserAgeConsentGroup, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUser2_Impl::CheckUserAgeConsentGroupAsync(this, consentgroup) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CheckUserAgeConsentGroupAsync: CheckUserAgeConsentGroupAsync::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IUser2_Vtbl { @@ -17214,6 +91736,29 @@ windows_core::imp::define_interface!(IUserAuthenticationStatusChangeDeferral, IU impl windows_core::RuntimeType for IUserAuthenticationStatusChangeDeferral { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IUserAuthenticationStatusChangeDeferral { + const NAME: &'static str = "Windows.System.IUserAuthenticationStatusChangeDeferral"; +} +pub trait IUserAuthenticationStatusChangeDeferral_Impl: windows_core::IUnknownImpl { + fn Complete(&self) -> windows_core::Result<()>; +} +impl IUserAuthenticationStatusChangeDeferral_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Complete(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IUserAuthenticationStatusChangeDeferral_Impl::Complete(this).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Complete: Complete::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IUserAuthenticationStatusChangeDeferral_Vtbl { @@ -17224,6 +91769,79 @@ windows_core::imp::define_interface!(IUserAuthenticationStatusChangingEventArgs, impl windows_core::RuntimeType for IUserAuthenticationStatusChangingEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IUserAuthenticationStatusChangingEventArgs { + const NAME: &'static str = "Windows.System.IUserAuthenticationStatusChangingEventArgs"; +} +pub trait IUserAuthenticationStatusChangingEventArgs_Impl: windows_core::IUnknownImpl { + fn GetDeferral(&self) -> windows_core::Result; + fn User(&self) -> windows_core::Result; + fn NewStatus(&self) -> windows_core::Result; + fn CurrentStatus(&self) -> windows_core::Result; +} +impl IUserAuthenticationStatusChangingEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDeferral(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserAuthenticationStatusChangingEventArgs_Impl::GetDeferral(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn User(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserAuthenticationStatusChangingEventArgs_Impl::User(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn NewStatus(this: *mut core::ffi::c_void, result__: *mut UserAuthenticationStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserAuthenticationStatusChangingEventArgs_Impl::NewStatus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CurrentStatus(this: *mut core::ffi::c_void, result__: *mut UserAuthenticationStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserAuthenticationStatusChangingEventArgs_Impl::CurrentStatus(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + GetDeferral: GetDeferral::, + User: User::, + NewStatus: NewStatus::, + CurrentStatus: CurrentStatus::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IUserAuthenticationStatusChangingEventArgs_Vtbl { @@ -17237,6 +91855,33 @@ windows_core::imp::define_interface!(IUserChangedEventArgs, IUserChangedEventArg impl windows_core::RuntimeType for IUserChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IUserChangedEventArgs { + const NAME: &'static str = "Windows.System.IUserChangedEventArgs"; +} +pub trait IUserChangedEventArgs_Impl: windows_core::IUnknownImpl { + fn User(&self) -> windows_core::Result; +} +impl IUserChangedEventArgs_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn User(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserChangedEventArgs_Impl::User(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), User: User:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IUserChangedEventArgs_Vtbl { @@ -17247,6 +91892,36 @@ windows_core::imp::define_interface!(IUserChangedEventArgs2, IUserChangedEventAr impl windows_core::RuntimeType for IUserChangedEventArgs2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IUserChangedEventArgs2 { + const NAME: &'static str = "Windows.System.IUserChangedEventArgs2"; +} +pub trait IUserChangedEventArgs2_Impl: windows_core::IUnknownImpl { + fn ChangedPropertyKinds(&self) -> windows_core::Result>; +} +impl IUserChangedEventArgs2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ChangedPropertyKinds(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserChangedEventArgs2_Impl::ChangedPropertyKinds(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ChangedPropertyKinds: ChangedPropertyKinds::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IUserChangedEventArgs2_Vtbl { @@ -17257,20 +91932,143 @@ windows_core::imp::define_interface!(IUserStatics, IUserStatics_Vtbl, 0x155eb23b impl windows_core::RuntimeType for IUserStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IUserStatics { + const NAME: &'static str = "Windows.System.IUserStatics"; +} +pub trait IUserStatics_Impl: windows_core::IUnknownImpl { + fn CreateWatcher(&self) -> windows_core::Result; + fn FindAllAsync(&self) -> windows_core::Result>>; + fn FindAllAsyncByType(&self, r#type: UserType) -> windows_core::Result>>; + fn FindAllAsyncByTypeAndStatus(&self, r#type: UserType, status: UserAuthenticationStatus) -> windows_core::Result>>; + fn GetFromId(&self, nonRoamableId: &windows_core::HSTRING) -> windows_core::Result; +} +impl IUserStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateWatcher(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserStatics_Impl::CreateWatcher(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FindAllAsync(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserStatics_Impl::FindAllAsync(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FindAllAsyncByType(this: *mut core::ffi::c_void, r#type: UserType, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserStatics_Impl::FindAllAsyncByType(this, r#type) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FindAllAsyncByTypeAndStatus(this: *mut core::ffi::c_void, r#type: UserType, status: UserAuthenticationStatus, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserStatics_Impl::FindAllAsyncByTypeAndStatus(this, r#type, status) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetFromId(this: *mut core::ffi::c_void, nonroamableid: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserStatics_Impl::GetFromId(this, core::mem::transmute(&nonroamableid)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateWatcher: CreateWatcher::, + FindAllAsync: FindAllAsync::, + FindAllAsyncByType: FindAllAsyncByType::, + FindAllAsyncByTypeAndStatus: FindAllAsyncByTypeAndStatus::, + GetFromId: GetFromId::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IUserStatics_Vtbl { pub base__: windows_core::IInspectable_Vtbl, pub CreateWatcher: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, pub FindAllAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(feature = "deprecated")] pub FindAllAsyncByType: unsafe extern "system" fn(*mut core::ffi::c_void, UserType, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + FindAllAsyncByType: usize, + #[cfg(feature = "deprecated")] pub FindAllAsyncByTypeAndStatus: unsafe extern "system" fn(*mut core::ffi::c_void, UserType, UserAuthenticationStatus, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "deprecated"))] + FindAllAsyncByTypeAndStatus: usize, pub GetFromId: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, } windows_core::imp::define_interface!(IUserStatics2, IUserStatics2_Vtbl, 0x74a37e11_2eb5_4487_b0d5_2c6790e013e9); impl windows_core::RuntimeType for IUserStatics2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IUserStatics2 { + const NAME: &'static str = "Windows.System.IUserStatics2"; +} +pub trait IUserStatics2_Impl: windows_core::IUnknownImpl { + fn GetDefault(&self) -> windows_core::Result; +} +impl IUserStatics2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetDefault(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserStatics2_Impl::GetDefault(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), GetDefault: GetDefault:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IUserStatics2_Vtbl { @@ -17281,6 +92079,205 @@ windows_core::imp::define_interface!(IUserWatcher, IUserWatcher_Vtbl, 0x155eb23b impl windows_core::RuntimeType for IUserWatcher { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IUserWatcher { + const NAME: &'static str = "Windows.System.IUserWatcher"; +} +pub trait IUserWatcher_Impl: windows_core::IUnknownImpl { + fn Status(&self) -> windows_core::Result; + fn Start(&self) -> windows_core::Result<()>; + fn Stop(&self) -> windows_core::Result<()>; + fn Added(&self, handler: windows_core::Ref<'_, super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveAdded(&self, token: i64) -> windows_core::Result<()>; + fn Removed(&self, handler: windows_core::Ref<'_, super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveRemoved(&self, token: i64) -> windows_core::Result<()>; + fn Updated(&self, handler: windows_core::Ref<'_, super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveUpdated(&self, token: i64) -> windows_core::Result<()>; + fn AuthenticationStatusChanged(&self, handler: windows_core::Ref<'_, super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveAuthenticationStatusChanged(&self, token: i64) -> windows_core::Result<()>; + fn AuthenticationStatusChanging(&self, handler: windows_core::Ref<'_, super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveAuthenticationStatusChanging(&self, token: i64) -> windows_core::Result<()>; + fn EnumerationCompleted(&self, handler: windows_core::Ref<'_, super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveEnumerationCompleted(&self, token: i64) -> windows_core::Result<()>; + fn Stopped(&self, handler: windows_core::Ref<'_, super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveStopped(&self, token: i64) -> windows_core::Result<()>; +} +impl IUserWatcher_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Status(this: *mut core::ffi::c_void, result__: *mut UserWatcherStatus) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserWatcher_Impl::Status(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Start(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IUserWatcher_Impl::Start(this).into() + } + } + unsafe extern "system" fn Stop(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IUserWatcher_Impl::Stop(this).into() + } + } + unsafe extern "system" fn Added(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserWatcher_Impl::Added(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveAdded(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IUserWatcher_Impl::RemoveAdded(this, token).into() + } + } + unsafe extern "system" fn Removed(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserWatcher_Impl::Removed(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveRemoved(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IUserWatcher_Impl::RemoveRemoved(this, token).into() + } + } + unsafe extern "system" fn Updated(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserWatcher_Impl::Updated(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveUpdated(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IUserWatcher_Impl::RemoveUpdated(this, token).into() + } + } + unsafe extern "system" fn AuthenticationStatusChanged(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserWatcher_Impl::AuthenticationStatusChanged(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveAuthenticationStatusChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IUserWatcher_Impl::RemoveAuthenticationStatusChanged(this, token).into() + } + } + unsafe extern "system" fn AuthenticationStatusChanging(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserWatcher_Impl::AuthenticationStatusChanging(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveAuthenticationStatusChanging(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IUserWatcher_Impl::RemoveAuthenticationStatusChanging(this, token).into() + } + } + unsafe extern "system" fn EnumerationCompleted(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserWatcher_Impl::EnumerationCompleted(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveEnumerationCompleted(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IUserWatcher_Impl::RemoveEnumerationCompleted(this, token).into() + } + } + unsafe extern "system" fn Stopped(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IUserWatcher_Impl::Stopped(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveStopped(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IUserWatcher_Impl::RemoveStopped(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Status: Status::, + Start: Start::, + Stop: Stop::, + Added: Added::, + RemoveAdded: RemoveAdded::, + Removed: Removed::, + RemoveRemoved: RemoveRemoved::, + Updated: Updated::, + RemoveUpdated: RemoveUpdated::, + AuthenticationStatusChanged: AuthenticationStatusChanged::, + RemoveAuthenticationStatusChanged: RemoveAuthenticationStatusChanged::, + AuthenticationStatusChanging: AuthenticationStatusChanging::, + RemoveAuthenticationStatusChanging: RemoveAuthenticationStatusChanging::, + EnumerationCompleted: EnumerationCompleted::, + RemoveEnumerationCompleted: RemoveEnumerationCompleted::, + Stopped: Stopped::, + RemoveStopped: RemoveStopped::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IUserWatcher_Vtbl { @@ -17308,6 +92305,98 @@ pub struct IUserWatcher_Vtbl { pub struct User(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(User, windows_core::IUnknown, windows_core::IInspectable); impl User { + pub fn NonRoamableId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NonRoamableId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn AuthenticationStatus(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AuthenticationStatus)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Type(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Type)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetPropertyAsync(&self, value: &windows_core::HSTRING) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetPropertyAsync)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Foundation_Collections")] + pub fn GetPropertiesAsync(&self, values: P0) -> windows_core::Result> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetPropertiesAsync)(windows_core::Interface::as_raw(this), values.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetPictureAsync(&self, desiredsize: UserPictureSize) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetPictureAsync)(windows_core::Interface::as_raw(this), desiredsize, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CheckUserAgeConsentGroupAsync(&self, consentgroup: UserAgeConsentGroup) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CheckUserAgeConsentGroupAsync)(windows_core::Interface::as_raw(this), consentgroup, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateWatcher() -> windows_core::Result { + Self::IUserStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWatcher)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn FindAllAsync() -> windows_core::Result>> { + Self::IUserStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindAllAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "deprecated")] + pub fn FindAllAsyncByType(r#type: UserType) -> windows_core::Result>> { + Self::IUserStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindAllAsyncByType)(windows_core::Interface::as_raw(this), r#type, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "deprecated")] + pub fn FindAllAsyncByTypeAndStatus(r#type: UserType, status: UserAuthenticationStatus) -> windows_core::Result>> { + Self::IUserStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindAllAsyncByTypeAndStatus)(windows_core::Interface::as_raw(this), r#type, status, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetFromId(nonroamableid: &windows_core::HSTRING) -> windows_core::Result { + Self::IUserStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetFromId)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(nonroamableid), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn GetDefault() -> windows_core::Result { + Self::IUserStatics2(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDefault)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } fn IUserStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -17377,6 +92466,12 @@ impl windows_core::RuntimeType for UserAuthenticationStatus { #[derive(Clone, Debug, Eq, PartialEq)] pub struct UserAuthenticationStatusChangeDeferral(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(UserAuthenticationStatusChangeDeferral, windows_core::IUnknown, windows_core::IInspectable); +impl UserAuthenticationStatusChangeDeferral { + pub fn Complete(&self) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).Complete)(windows_core::Interface::as_raw(this)).ok() } + } +} impl windows_core::RuntimeType for UserAuthenticationStatusChangeDeferral { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -17393,6 +92488,36 @@ unsafe impl Sync for UserAuthenticationStatusChangeDeferral {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct UserAuthenticationStatusChangingEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(UserAuthenticationStatusChangingEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl UserAuthenticationStatusChangingEventArgs { + pub fn GetDeferral(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDeferral)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn User(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).User)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn NewStatus(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).NewStatus)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn CurrentStatus(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CurrentStatus)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } +} impl windows_core::RuntimeType for UserAuthenticationStatusChangingEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -17409,6 +92534,22 @@ unsafe impl Sync for UserAuthenticationStatusChangingEventArgs {} #[derive(Clone, Debug, Eq, PartialEq)] pub struct UserChangedEventArgs(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(UserChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl UserChangedEventArgs { + pub fn User(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).User)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ChangedPropertyKinds(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ChangedPropertyKinds)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} impl windows_core::RuntimeType for UserChangedEventArgs { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -17457,6 +92598,13 @@ impl windows_core::RuntimeType for UserType { pub struct UserWatcher(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(UserWatcher, windows_core::IUnknown, windows_core::IInspectable); impl UserWatcher { + pub fn Status(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Status)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn Start(&self) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).Start)(windows_core::Interface::as_raw(this)).ok() } @@ -17475,6 +92623,10 @@ impl UserWatcher { (windows_core::Interface::vtable(this).Added)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) } } + pub fn RemoveAdded(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveAdded)(windows_core::Interface::as_raw(this), token).ok() } + } pub fn Removed(&self, handler: P0) -> windows_core::Result where P0: windows_core::Param>, @@ -17485,6 +92637,10 @@ impl UserWatcher { (windows_core::Interface::vtable(this).Removed)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) } } + pub fn RemoveRemoved(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveRemoved)(windows_core::Interface::as_raw(this), token).ok() } + } pub fn Updated(&self, handler: P0) -> windows_core::Result where P0: windows_core::Param>, @@ -17495,6 +92651,38 @@ impl UserWatcher { (windows_core::Interface::vtable(this).Updated)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) } } + pub fn RemoveUpdated(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveUpdated)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn AuthenticationStatusChanged(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AuthenticationStatusChanged)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveAuthenticationStatusChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveAuthenticationStatusChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn AuthenticationStatusChanging(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AuthenticationStatusChanging)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveAuthenticationStatusChanging(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveAuthenticationStatusChanging)(windows_core::Interface::as_raw(this), token).ok() } + } pub fn EnumerationCompleted(&self, handler: P0) -> windows_core::Result where P0: windows_core::Param>, @@ -17505,7 +92693,25 @@ impl UserWatcher { (windows_core::Interface::vtable(this).EnumerationCompleted)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) } } + pub fn RemoveEnumerationCompleted(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveEnumerationCompleted)(windows_core::Interface::as_raw(this), token).ok() } } + pub fn Stopped(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Stopped)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveStopped(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveStopped)(windows_core::Interface::as_raw(this), token).ok() } + } +} impl windows_core::RuntimeType for UserWatcher { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -17549,7 +92755,9 @@ impl windows_core::RuntimeType for UserWatcherUpdateKind { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.System.UserWatcherUpdateKind;i4)"); } } +#[cfg(feature = "UI")] pub mod UI{ +#[cfg(feature = "UI_Notifications")] pub mod Notifications{ #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -17598,8 +92806,542 @@ impl core::ops::Not for NotificationKinds { } } } +#[cfg(feature = "UI_WindowManagement")] +pub mod WindowManagement{ +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct DisplayRegion(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(DisplayRegion, windows_core::IUnknown, windows_core::IInspectable); +impl DisplayRegion { + pub fn DisplayMonitorDeviceId(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DisplayMonitorDeviceId)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn IsVisible(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsVisible)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn WorkAreaOffset(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WorkAreaOffset)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn WorkAreaSize(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WorkAreaSize)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn WindowingEnvironment(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WindowingEnvironment)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Changed(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Changed)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveChanged)(windows_core::Interface::as_raw(this), token).ok() } + } } +impl windows_core::RuntimeType for DisplayRegion { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for DisplayRegion { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for DisplayRegion { + const NAME: &'static str = "Windows.UI.WindowManagement.DisplayRegion"; +} +unsafe impl Send for DisplayRegion {} +unsafe impl Sync for DisplayRegion {} +windows_core::imp::define_interface!(IDisplayRegion, IDisplayRegion_Vtbl, 0xdb50c3a2_4094_5f47_8cb1_ea01ddafaa94); +impl windows_core::RuntimeType for IDisplayRegion { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IDisplayRegion { + const NAME: &'static str = "Windows.UI.WindowManagement.IDisplayRegion"; +} +pub trait IDisplayRegion_Impl: windows_core::IUnknownImpl { + fn DisplayMonitorDeviceId(&self) -> windows_core::Result; + fn IsVisible(&self) -> windows_core::Result; + fn WorkAreaOffset(&self) -> windows_core::Result; + fn WorkAreaSize(&self) -> windows_core::Result; + fn WindowingEnvironment(&self) -> windows_core::Result; + fn Changed(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveChanged(&self, token: i64) -> windows_core::Result<()>; +} +impl IDisplayRegion_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DisplayMonitorDeviceId(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDisplayRegion_Impl::DisplayMonitorDeviceId(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsVisible(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDisplayRegion_Impl::IsVisible(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WorkAreaOffset(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::Point) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDisplayRegion_Impl::WorkAreaOffset(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WorkAreaSize(this: *mut core::ffi::c_void, result__: *mut super::super::Foundation::Size) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDisplayRegion_Impl::WorkAreaSize(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WindowingEnvironment(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDisplayRegion_Impl::WindowingEnvironment(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Changed(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IDisplayRegion_Impl::Changed(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IDisplayRegion_Impl::RemoveChanged(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DisplayMonitorDeviceId: DisplayMonitorDeviceId::, + IsVisible: IsVisible::, + WorkAreaOffset: WorkAreaOffset::, + WorkAreaSize: WorkAreaSize::, + WindowingEnvironment: WindowingEnvironment::, + Changed: Changed::, + RemoveChanged: RemoveChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IDisplayRegion_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub DisplayMonitorDeviceId: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub IsVisible: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub WorkAreaOffset: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::Point) -> windows_core::HRESULT, + pub WorkAreaSize: unsafe extern "system" fn(*mut core::ffi::c_void, *mut super::super::Foundation::Size) -> windows_core::HRESULT, + pub WindowingEnvironment: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Changed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IWindowingEnvironment, IWindowingEnvironment_Vtbl, 0x264363c0_2a49_5417_b3ae_48a71c63a3bd); +impl windows_core::RuntimeType for IWindowingEnvironment { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IWindowingEnvironment { + const NAME: &'static str = "Windows.UI.WindowManagement.IWindowingEnvironment"; +} +pub trait IWindowingEnvironment_Impl: windows_core::IUnknownImpl { + fn IsEnabled(&self) -> windows_core::Result; + fn Kind(&self) -> windows_core::Result; + fn GetDisplayRegions(&self) -> windows_core::Result>; + fn Changed(&self, handler: windows_core::Ref<'_, super::super::Foundation::TypedEventHandler>) -> windows_core::Result; + fn RemoveChanged(&self, token: i64) -> windows_core::Result<()>; +} +impl IWindowingEnvironment_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsEnabled(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWindowingEnvironment_Impl::IsEnabled(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Kind(this: *mut core::ffi::c_void, result__: *mut WindowingEnvironmentKind) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWindowingEnvironment_Impl::Kind(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetDisplayRegions(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWindowingEnvironment_Impl::GetDisplayRegions(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Changed(this: *mut core::ffi::c_void, handler: *mut core::ffi::c_void, result__: *mut i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWindowingEnvironment_Impl::Changed(this, core::mem::transmute_copy(&handler)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RemoveChanged(this: *mut core::ffi::c_void, token: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IWindowingEnvironment_Impl::RemoveChanged(this, token).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + IsEnabled: IsEnabled::, + Kind: Kind::, + GetDisplayRegions: GetDisplayRegions::, + Changed: Changed::, + RemoveChanged: RemoveChanged::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IWindowingEnvironment_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub IsEnabled: unsafe extern "system" fn(*mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, + pub Kind: unsafe extern "system" fn(*mut core::ffi::c_void, *mut WindowingEnvironmentKind) -> windows_core::HRESULT, + pub GetDisplayRegions: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub Changed: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut i64) -> windows_core::HRESULT, + pub RemoveChanged: unsafe extern "system" fn(*mut core::ffi::c_void, i64) -> windows_core::HRESULT, +} +windows_core::imp::define_interface!(IWindowingEnvironmentChangedEventArgs, IWindowingEnvironmentChangedEventArgs_Vtbl, 0x4160cfc6_023d_5e9a_b431_350e67dc978a); +impl windows_core::RuntimeType for IWindowingEnvironmentChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IWindowingEnvironmentChangedEventArgs { + const NAME: &'static str = "Windows.UI.WindowManagement.IWindowingEnvironmentChangedEventArgs"; +} +pub trait IWindowingEnvironmentChangedEventArgs_Impl: windows_core::IUnknownImpl {} +impl IWindowingEnvironmentChangedEventArgs_Vtbl { + pub const fn new() -> Self { + Self { base__: windows_core::IInspectable_Vtbl::new::() } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IWindowingEnvironmentChangedEventArgs_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, +} +windows_core::imp::define_interface!(IWindowingEnvironmentStatics, IWindowingEnvironmentStatics_Vtbl, 0x874e9fb7_c642_55ab_8aa2_162f734a9a72); +impl windows_core::RuntimeType for IWindowingEnvironmentStatics { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IWindowingEnvironmentStatics { + const NAME: &'static str = "Windows.UI.WindowManagement.IWindowingEnvironmentStatics"; +} +pub trait IWindowingEnvironmentStatics_Impl: windows_core::IUnknownImpl { + fn FindAll(&self) -> windows_core::Result>; + fn FindAllWithKind(&self, kind: WindowingEnvironmentKind) -> windows_core::Result>; +} +impl IWindowingEnvironmentStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FindAll(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWindowingEnvironmentStatics_Impl::FindAll(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn FindAllWithKind(this: *mut core::ffi::c_void, kind: WindowingEnvironmentKind, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IWindowingEnvironmentStatics_Impl::FindAllWithKind(this, kind) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FindAll: FindAll::, + FindAllWithKind: FindAllWithKind::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IWindowingEnvironmentStatics_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub FindAll: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub FindAllWithKind: unsafe extern "system" fn(*mut core::ffi::c_void, WindowingEnvironmentKind, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct WindowingEnvironment(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(WindowingEnvironment, windows_core::IUnknown, windows_core::IInspectable); +impl WindowingEnvironment { + pub fn IsEnabled(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsEnabled)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Kind(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Kind)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetDisplayRegions(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetDisplayRegions)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Changed(&self, handler: P0) -> windows_core::Result + where + P0: windows_core::Param>, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Changed)(windows_core::Interface::as_raw(this), handler.param().abi(), &mut result__).map(|| result__) + } + } + pub fn RemoveChanged(&self, token: i64) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).RemoveChanged)(windows_core::Interface::as_raw(this), token).ok() } + } + pub fn FindAll() -> windows_core::Result> { + Self::IWindowingEnvironmentStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindAll)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn FindAllWithKind(kind: WindowingEnvironmentKind) -> windows_core::Result> { + Self::IWindowingEnvironmentStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FindAllWithKind)(windows_core::Interface::as_raw(this), kind, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + fn IWindowingEnvironmentStatics windows_core::Result>(callback: F) -> windows_core::Result { + static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); + SHARED.call(callback) + } +} +impl windows_core::RuntimeType for WindowingEnvironment { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for WindowingEnvironment { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for WindowingEnvironment { + const NAME: &'static str = "Windows.UI.WindowManagement.WindowingEnvironment"; +} +unsafe impl Send for WindowingEnvironment {} +unsafe impl Sync for WindowingEnvironment {} +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct WindowingEnvironmentChangedEventArgs(windows_core::IUnknown); +windows_core::imp::interface_hierarchy!(WindowingEnvironmentChangedEventArgs, windows_core::IUnknown, windows_core::IInspectable); +impl WindowingEnvironmentChangedEventArgs {} +impl windows_core::RuntimeType for WindowingEnvironmentChangedEventArgs { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +unsafe impl windows_core::Interface for WindowingEnvironmentChangedEventArgs { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +impl windows_core::RuntimeName for WindowingEnvironmentChangedEventArgs { + const NAME: &'static str = "Windows.UI.WindowManagement.WindowingEnvironmentChangedEventArgs"; +} +unsafe impl Send for WindowingEnvironmentChangedEventArgs {} +unsafe impl Sync for WindowingEnvironmentChangedEventArgs {} +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct WindowingEnvironmentKind(pub i32); +impl WindowingEnvironmentKind { + pub const Unknown: Self = Self(0i32); + pub const Overlapped: Self = Self(1i32); + pub const Tiled: Self = Self(2i32); +} +impl windows_core::TypeKind for WindowingEnvironmentKind { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for WindowingEnvironmentKind { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.UI.WindowManagement.WindowingEnvironmentKind;i4)"); +} +} +} +#[cfg(feature = "Web")] pub mod Web{ +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct WebErrorStatus(pub i32); +impl WebErrorStatus { + pub const Unknown: Self = Self(0i32); + pub const CertificateCommonNameIsIncorrect: Self = Self(1i32); + pub const CertificateExpired: Self = Self(2i32); + pub const CertificateContainsErrors: Self = Self(3i32); + pub const CertificateRevoked: Self = Self(4i32); + pub const CertificateIsInvalid: Self = Self(5i32); + pub const ServerUnreachable: Self = Self(6i32); + pub const Timeout: Self = Self(7i32); + pub const ErrorHttpInvalidServerResponse: Self = Self(8i32); + pub const ConnectionAborted: Self = Self(9i32); + pub const ConnectionReset: Self = Self(10i32); + pub const Disconnected: Self = Self(11i32); + pub const HttpToHttpsOnRedirection: Self = Self(12i32); + pub const HttpsToHttpOnRedirection: Self = Self(13i32); + pub const CannotConnect: Self = Self(14i32); + pub const HostNameNotResolved: Self = Self(15i32); + pub const OperationCanceled: Self = Self(16i32); + pub const RedirectFailed: Self = Self(17i32); + pub const UnexpectedStatusCode: Self = Self(18i32); + pub const UnexpectedRedirection: Self = Self(19i32); + pub const UnexpectedClientError: Self = Self(20i32); + pub const UnexpectedServerError: Self = Self(21i32); + pub const InsufficientRangeSupport: Self = Self(22i32); + pub const MissingContentLengthSupport: Self = Self(23i32); + pub const MultipleChoices: Self = Self(300i32); + pub const MovedPermanently: Self = Self(301i32); + pub const Found: Self = Self(302i32); + pub const SeeOther: Self = Self(303i32); + pub const NotModified: Self = Self(304i32); + pub const UseProxy: Self = Self(305i32); + pub const TemporaryRedirect: Self = Self(307i32); + pub const BadRequest: Self = Self(400i32); + pub const Unauthorized: Self = Self(401i32); + pub const PaymentRequired: Self = Self(402i32); + pub const Forbidden: Self = Self(403i32); + pub const NotFound: Self = Self(404i32); + pub const MethodNotAllowed: Self = Self(405i32); + pub const NotAcceptable: Self = Self(406i32); + pub const ProxyAuthenticationRequired: Self = Self(407i32); + pub const RequestTimeout: Self = Self(408i32); + pub const Conflict: Self = Self(409i32); + pub const Gone: Self = Self(410i32); + pub const LengthRequired: Self = Self(411i32); + pub const PreconditionFailed: Self = Self(412i32); + pub const RequestEntityTooLarge: Self = Self(413i32); + pub const RequestUriTooLong: Self = Self(414i32); + pub const UnsupportedMediaType: Self = Self(415i32); + pub const RequestedRangeNotSatisfiable: Self = Self(416i32); + pub const ExpectationFailed: Self = Self(417i32); + pub const InternalServerError: Self = Self(500i32); + pub const NotImplemented: Self = Self(501i32); + pub const BadGateway: Self = Self(502i32); + pub const ServiceUnavailable: Self = Self(503i32); + pub const GatewayTimeout: Self = Self(504i32); + pub const HttpVersionNotSupported: Self = Self(505i32); +} +impl windows_core::TypeKind for WebErrorStatus { + type TypeKind = windows_core::CopyType; +} +impl windows_core::RuntimeType for WebErrorStatus { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(b"enum(Windows.Web.WebErrorStatus;i4)"); +} +#[cfg(feature = "Web_Http")] pub mod Http{ #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] @@ -17611,6 +93353,26 @@ impl HttpBufferContent { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFromBuffer(content: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IHttpBufferContentFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromBuffer)(windows_core::Interface::as_raw(this), content.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFromBufferWithOffset(content: P0, offset: u32, count: u32) -> windows_core::Result + where + P0: windows_core::Param, + { + Self::IHttpBufferContentFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromBufferWithOffset)(windows_core::Interface::as_raw(this), content.param().abi(), offset, count, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } #[cfg(feature = "Web_Http_Headers")] pub fn Headers(&self) -> windows_core::Result { let this = self; @@ -17619,6 +93381,13 @@ impl HttpBufferContent { (windows_core::Interface::vtable(this).Headers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn BufferAllAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BufferAllAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } #[cfg(feature = "Storage_Streams")] pub fn ReadAsBufferAsync(&self) -> windows_core::Result> { let this = self; @@ -17635,6 +93404,38 @@ impl HttpBufferContent { (windows_core::Interface::vtable(this).ReadAsInputStreamAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ReadAsStringAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadAsStringAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryComputeLength(&self, length: &mut u64) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryComputeLength)(windows_core::Interface::as_raw(this), length, &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn WriteToStreamAsync(&self, outputstream: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteToStreamAsync)(windows_core::Interface::as_raw(this), outputstream.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpBufferContentFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -17669,6 +93470,100 @@ impl HttpClient { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn DeleteAsync(&self, uri: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DeleteAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetAsync(&self, uri: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetWithOptionAsync(&self, uri: P0, completionoption: HttpCompletionOption) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetWithOptionAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), completionoption, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetBufferAsync(&self, uri: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetBufferAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn GetInputStreamAsync(&self, uri: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetInputStreamAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn GetStringAsync(&self, uri: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetStringAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PostAsync(&self, uri: P0, content: P1) -> windows_core::Result> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PostAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), content.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PutAsync(&self, uri: P0, content: P1) -> windows_core::Result> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PutAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), content.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SendRequestAsync(&self, request: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SendRequestAsync)(windows_core::Interface::as_raw(this), request.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn SendRequestWithOptionAsync(&self, request: P0, completionoption: HttpCompletionOption) -> windows_core::Result> where P0: windows_core::Param, @@ -17679,6 +93574,127 @@ impl HttpClient { (windows_core::Interface::vtable(this).SendRequestWithOptionAsync)(windows_core::Interface::as_raw(this), request.param().abi(), completionoption, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + #[cfg(feature = "Web_Http_Headers")] + pub fn DefaultRequestHeaders(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DefaultRequestHeaders)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryDeleteAsync(&self, uri: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryDeleteAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryGetAsync(&self, uri: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryGetAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryGetAsync2(&self, uri: P0, completionoption: HttpCompletionOption) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryGetAsync2)(windows_core::Interface::as_raw(this), uri.param().abi(), completionoption, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryGetBufferAsync(&self, uri: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryGetBufferAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryGetInputStreamAsync(&self, uri: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryGetInputStreamAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryGetStringAsync(&self, uri: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryGetStringAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryPostAsync(&self, uri: P0, content: P1) -> windows_core::Result> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryPostAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), content.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryPutAsync(&self, uri: P0, content: P1) -> windows_core::Result> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryPutAsync)(windows_core::Interface::as_raw(this), uri.param().abi(), content.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TrySendRequestAsync(&self, request: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrySendRequestAsync)(windows_core::Interface::as_raw(this), request.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TrySendRequestAsync2(&self, request: P0, completionoption: HttpCompletionOption) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TrySendRequestAsync2)(windows_core::Interface::as_raw(this), request.param().abi(), completionoption, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn DefaultPrivacyAnnotation(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DefaultPrivacyAnnotation)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetDefaultPrivacyAnnotation(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetDefaultPrivacyAnnotation)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } #[cfg(feature = "Web_Http_Filters")] pub fn Create(filter: P0) -> windows_core::Result where @@ -17689,6 +93705,13 @@ impl HttpClient { (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), filter.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpClientFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -17737,6 +93760,13 @@ impl HttpFormUrlEncodedContent { (windows_core::Interface::vtable(this).Headers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn BufferAllAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BufferAllAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } #[cfg(feature = "Storage_Streams")] pub fn ReadAsBufferAsync(&self) -> windows_core::Result> { let this = self; @@ -17753,6 +93783,31 @@ impl HttpFormUrlEncodedContent { (windows_core::Interface::vtable(this).ReadAsInputStreamAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ReadAsStringAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadAsStringAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryComputeLength(&self, length: &mut u64) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryComputeLength)(windows_core::Interface::as_raw(this), length, &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn WriteToStreamAsync(&self, outputstream: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteToStreamAsync)(windows_core::Interface::as_raw(this), outputstream.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Create(content: P0) -> windows_core::Result where P0: windows_core::Param>>, @@ -17762,6 +93817,13 @@ impl HttpFormUrlEncodedContent { (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), content.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpFormUrlEncodedContentFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -17789,7 +93851,50 @@ impl HttpGetBufferResult { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn ExtendedError(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExtendedError)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } + pub fn RequestMessage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestMessage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResponseMessage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResponseMessage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Succeeded(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Succeeded)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} impl windows_core::RuntimeType for HttpGetBufferResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -17812,7 +93917,50 @@ impl HttpGetInputStreamResult { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn ExtendedError(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExtendedError)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } + pub fn RequestMessage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestMessage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResponseMessage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResponseMessage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Succeeded(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Succeeded)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} impl windows_core::RuntimeType for HttpGetInputStreamResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -17835,7 +93983,49 @@ impl HttpGetStringResult { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn ExtendedError(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExtendedError)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } + pub fn RequestMessage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestMessage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResponseMessage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResponseMessage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Succeeded(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Succeeded)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} impl windows_core::RuntimeType for HttpGetStringResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -17854,12 +94044,68 @@ pub struct HttpMethod(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpMethod, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpMethod, super::super::Foundation::IStringable); impl HttpMethod { + pub fn Method(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Method)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } pub fn Create(method: &windows_core::HSTRING) -> windows_core::Result { Self::IHttpMethodFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(method), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn Delete() -> windows_core::Result { + Self::IHttpMethodStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Delete)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Get() -> windows_core::Result { + Self::IHttpMethodStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Get)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Head() -> windows_core::Result { + Self::IHttpMethodStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Head)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Options() -> windows_core::Result { + Self::IHttpMethodStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Options)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Patch() -> windows_core::Result { + Self::IHttpMethodStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Patch)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Post() -> windows_core::Result { + Self::IHttpMethodStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Post)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Put() -> windows_core::Result { + Self::IHttpMethodStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Put)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpMethodFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -17906,6 +94152,13 @@ impl HttpMultipartContent { (windows_core::Interface::vtable(this).Headers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn BufferAllAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BufferAllAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } #[cfg(feature = "Storage_Streams")] pub fn ReadAsBufferAsync(&self) -> windows_core::Result> { let this = self; @@ -17922,6 +94175,50 @@ impl HttpMultipartContent { (windows_core::Interface::vtable(this).ReadAsInputStreamAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ReadAsStringAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadAsStringAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryComputeLength(&self, length: &mut u64) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryComputeLength)(windows_core::Interface::as_raw(this), length, &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn WriteToStreamAsync(&self, outputstream: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteToStreamAsync)(windows_core::Interface::as_raw(this), outputstream.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Add(&self, content: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Add)(windows_core::Interface::as_raw(this), content.param().abi()).ok() } + } + pub fn CreateWithSubtype(subtype: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpMultipartContentFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWithSubtype)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(subtype), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateWithSubtypeAndBoundary(subtype: &windows_core::HSTRING, boundary: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpMultipartContentFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWithSubtypeAndBoundary)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(subtype), core::mem::transmute_copy(boundary), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn First(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::>(self)?; unsafe { @@ -17929,6 +94226,13 @@ impl HttpMultipartContent { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpMultipartContentFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -17985,6 +94289,13 @@ impl HttpMultipartFormDataContent { (windows_core::Interface::vtable(this).Headers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn BufferAllAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BufferAllAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } #[cfg(feature = "Storage_Streams")] pub fn ReadAsBufferAsync(&self) -> windows_core::Result> { let this = self; @@ -18001,6 +94312,58 @@ impl HttpMultipartFormDataContent { (windows_core::Interface::vtable(this).ReadAsInputStreamAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ReadAsStringAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadAsStringAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryComputeLength(&self, length: &mut u64) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryComputeLength)(windows_core::Interface::as_raw(this), length, &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn WriteToStreamAsync(&self, outputstream: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteToStreamAsync)(windows_core::Interface::as_raw(this), outputstream.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Add(&self, content: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Add)(windows_core::Interface::as_raw(this), content.param().abi()).ok() } + } + pub fn AddWithName(&self, content: P0, name: &windows_core::HSTRING) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).AddWithName)(windows_core::Interface::as_raw(this), content.param().abi(), core::mem::transmute_copy(name)).ok() } + } + pub fn AddWithNameAndFileName(&self, content: P0, name: &windows_core::HSTRING, filename: &windows_core::HSTRING) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).AddWithNameAndFileName)(windows_core::Interface::as_raw(this), content.param().abi(), core::mem::transmute_copy(name), core::mem::transmute_copy(filename)).ok() } + } + pub fn CreateWithBoundary(boundary: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpMultipartFormDataContentFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateWithBoundary)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(boundary), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } pub fn First(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::>(self)?; unsafe { @@ -18008,6 +94371,13 @@ impl HttpMultipartFormDataContent { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpMultipartFormDataContentFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -18115,6 +94485,59 @@ impl HttpRequestMessage { (windows_core::Interface::vtable(this).Headers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Method(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Method)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetMethod(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMethod)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn Properties(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Properties)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RequestUri(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestUri)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetRequestUri(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetRequestUri)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn TransportInformation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TransportInformation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn PrivacyAnnotation(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).PrivacyAnnotation)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetPrivacyAnnotation(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).SetPrivacyAnnotation)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } pub fn Create(method: P0, uri: P1) -> windows_core::Result where P0: windows_core::Param, @@ -18125,6 +94548,13 @@ impl HttpRequestMessage { (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), method.param().abi(), uri.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpRequestMessageFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -18152,7 +94582,42 @@ impl HttpRequestResult { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } } + pub fn ExtendedError(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ExtendedError)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } } + pub fn RequestMessage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestMessage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ResponseMessage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ResponseMessage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Succeeded(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Succeeded)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} impl windows_core::RuntimeType for HttpRequestResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -18204,16 +94669,91 @@ impl HttpResponseMessage { (windows_core::Interface::vtable(this).Headers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn IsSuccessStatusCode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IsSuccessStatusCode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn ReasonPhrase(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReasonPhrase)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetReasonPhrase(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetReasonPhrase)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn RequestMessage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RequestMessage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetRequestMessage(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetRequestMessage)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn Source(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Source)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } pub fn SetSource(&self, value: HttpResponseMessageSource) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).SetSource)(windows_core::Interface::as_raw(this), value).ok() } } + pub fn StatusCode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).StatusCode)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetStatusCode(&self, value: HttpStatusCode) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetStatusCode)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn Version(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Version)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn SetVersion(&self, value: HttpVersion) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetVersion)(windows_core::Interface::as_raw(this), value).ok() } + } + pub fn EnsureSuccessStatusCode(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).EnsureSuccessStatusCode)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Create(statuscode: HttpStatusCode) -> windows_core::Result { Self::IHttpResponseMessageFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), statuscode, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpResponseMessageFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -18332,6 +94872,13 @@ impl HttpStreamContent { (windows_core::Interface::vtable(this).Headers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn BufferAllAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BufferAllAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } #[cfg(feature = "Storage_Streams")] pub fn ReadAsBufferAsync(&self) -> windows_core::Result> { let this = self; @@ -18348,6 +94895,31 @@ impl HttpStreamContent { (windows_core::Interface::vtable(this).ReadAsInputStreamAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ReadAsStringAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadAsStringAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryComputeLength(&self, length: &mut u64) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryComputeLength)(windows_core::Interface::as_raw(this), length, &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn WriteToStreamAsync(&self, outputstream: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteToStreamAsync)(windows_core::Interface::as_raw(this), outputstream.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } #[cfg(feature = "Storage_Streams")] pub fn CreateFromInputStream(content: P0) -> windows_core::Result where @@ -18358,6 +94930,13 @@ impl HttpStreamContent { (windows_core::Interface::vtable(this).CreateFromInputStream)(windows_core::Interface::as_raw(this), content.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpStreamContentFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -18393,6 +94972,13 @@ impl HttpStringContent { (windows_core::Interface::vtable(this).Headers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn BufferAllAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BufferAllAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } #[cfg(feature = "Storage_Streams")] pub fn ReadAsBufferAsync(&self) -> windows_core::Result> { let this = self; @@ -18409,6 +94995,58 @@ impl HttpStringContent { (windows_core::Interface::vtable(this).ReadAsInputStreamAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ReadAsStringAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadAsStringAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryComputeLength(&self, length: &mut u64) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryComputeLength)(windows_core::Interface::as_raw(this), length, &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn WriteToStreamAsync(&self, outputstream: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteToStreamAsync)(windows_core::Interface::as_raw(this), outputstream.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFromString(content: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpStringContentFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromString)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(content), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFromStringWithEncoding(content: &windows_core::HSTRING, encoding: super::super::Storage::Streams::UnicodeEncoding) -> windows_core::Result { + Self::IHttpStringContentFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromStringWithEncoding)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(content), encoding, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + #[cfg(feature = "Storage_Streams")] + pub fn CreateFromStringWithEncodingAndMediaType(content: &windows_core::HSTRING, encoding: super::super::Storage::Streams::UnicodeEncoding, mediatype: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpStringContentFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromStringWithEncodingAndMediaType)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(content), encoding, core::mem::transmute_copy(mediatype), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpStringContentFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -18431,6 +95069,47 @@ unsafe impl Sync for HttpStringContent {} pub struct HttpTransportInformation(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpTransportInformation, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpTransportInformation, super::super::Foundation::IStringable); +impl HttpTransportInformation { + #[cfg(feature = "Security_Cryptography_Certificates")] + pub fn ServerCertificate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ServerCertificate)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Networking_Sockets")] + pub fn ServerCertificateErrorSeverity(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ServerCertificateErrorSeverity)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Security_Cryptography_Certificates")] + pub fn ServerCertificateErrors(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ServerCertificateErrors)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Security_Cryptography_Certificates")] + pub fn ServerIntermediateCertificates(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ServerIntermediateCertificates)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} impl windows_core::RuntimeType for HttpTransportInformation { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -18462,6 +95141,54 @@ windows_core::imp::define_interface!(IHttpBufferContentFactory, IHttpBufferConte impl windows_core::RuntimeType for IHttpBufferContentFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IHttpBufferContentFactory { + const NAME: &'static str = "Windows.Web.Http.IHttpBufferContentFactory"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IHttpBufferContentFactory_Impl: windows_core::IUnknownImpl { + fn CreateFromBuffer(&self, content: windows_core::Ref<'_, super::super::Storage::Streams::IBuffer>) -> windows_core::Result; + fn CreateFromBufferWithOffset(&self, content: windows_core::Ref<'_, super::super::Storage::Streams::IBuffer>, offset: u32, count: u32) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IHttpBufferContentFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromBuffer(this: *mut core::ffi::c_void, content: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpBufferContentFactory_Impl::CreateFromBuffer(this, core::mem::transmute_copy(&content)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromBufferWithOffset(this: *mut core::ffi::c_void, content: *mut core::ffi::c_void, offset: u32, count: u32, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpBufferContentFactory_Impl::CreateFromBufferWithOffset(this, core::mem::transmute_copy(&content), offset, count) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromBuffer: CreateFromBuffer::, + CreateFromBufferWithOffset: CreateFromBufferWithOffset::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpBufferContentFactory_Vtbl { @@ -18479,6 +95206,189 @@ windows_core::imp::define_interface!(IHttpClient, IHttpClient_Vtbl, 0x7fda1151_3 impl windows_core::RuntimeType for IHttpClient { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(all(feature = "Storage_Streams", feature = "Web_Http_Headers"))] +impl windows_core::RuntimeName for IHttpClient { + const NAME: &'static str = "Windows.Web.Http.IHttpClient"; +} +#[cfg(all(feature = "Storage_Streams", feature = "Web_Http_Headers"))] +pub trait IHttpClient_Impl: windows_core::IUnknownImpl { + fn DeleteAsync(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result>; + fn GetAsync(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result>; + fn GetWithOptionAsync(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>, completionOption: HttpCompletionOption) -> windows_core::Result>; + fn GetBufferAsync(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result>; + fn GetInputStreamAsync(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result>; + fn GetStringAsync(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result>; + fn PostAsync(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>, content: windows_core::Ref<'_, IHttpContent>) -> windows_core::Result>; + fn PutAsync(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>, content: windows_core::Ref<'_, IHttpContent>) -> windows_core::Result>; + fn SendRequestAsync(&self, request: windows_core::Ref<'_, HttpRequestMessage>) -> windows_core::Result>; + fn SendRequestWithOptionAsync(&self, request: windows_core::Ref<'_, HttpRequestMessage>, completionOption: HttpCompletionOption) -> windows_core::Result>; + fn DefaultRequestHeaders(&self) -> windows_core::Result; +} +#[cfg(all(feature = "Storage_Streams", feature = "Web_Http_Headers"))] +impl IHttpClient_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DeleteAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient_Impl::DeleteAsync(this, core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient_Impl::GetAsync(this, core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetWithOptionAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, completionoption: HttpCompletionOption, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient_Impl::GetWithOptionAsync(this, core::mem::transmute_copy(&uri), completionoption) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetBufferAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient_Impl::GetBufferAsync(this, core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetInputStreamAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient_Impl::GetInputStreamAsync(this, core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetStringAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient_Impl::GetStringAsync(this, core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PostAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, content: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient_Impl::PostAsync(this, core::mem::transmute_copy(&uri), core::mem::transmute_copy(&content)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn PutAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, content: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient_Impl::PutAsync(this, core::mem::transmute_copy(&uri), core::mem::transmute_copy(&content)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SendRequestAsync(this: *mut core::ffi::c_void, request: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient_Impl::SendRequestAsync(this, core::mem::transmute_copy(&request)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SendRequestWithOptionAsync(this: *mut core::ffi::c_void, request: *mut core::ffi::c_void, completionoption: HttpCompletionOption, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient_Impl::SendRequestWithOptionAsync(this, core::mem::transmute_copy(&request), completionoption) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn DefaultRequestHeaders(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient_Impl::DefaultRequestHeaders(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DeleteAsync: DeleteAsync::, + GetAsync: GetAsync::, + GetWithOptionAsync: GetWithOptionAsync::, + GetBufferAsync: GetBufferAsync::, + GetInputStreamAsync: GetInputStreamAsync::, + GetStringAsync: GetStringAsync::, + PostAsync: PostAsync::, + PutAsync: PutAsync::, + SendRequestAsync: SendRequestAsync::, + SendRequestWithOptionAsync: SendRequestWithOptionAsync::, + DefaultRequestHeaders: DefaultRequestHeaders::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpClient_Vtbl { @@ -18508,6 +95418,171 @@ windows_core::imp::define_interface!(IHttpClient2, IHttpClient2_Vtbl, 0xcdd83348 impl windows_core::RuntimeType for IHttpClient2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpClient2 { + const NAME: &'static str = "Windows.Web.Http.IHttpClient2"; +} +pub trait IHttpClient2_Impl: windows_core::IUnknownImpl { + fn TryDeleteAsync(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result>; + fn TryGetAsync(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result>; + fn TryGetAsync2(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>, completionOption: HttpCompletionOption) -> windows_core::Result>; + fn TryGetBufferAsync(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result>; + fn TryGetInputStreamAsync(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result>; + fn TryGetStringAsync(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result>; + fn TryPostAsync(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>, content: windows_core::Ref<'_, IHttpContent>) -> windows_core::Result>; + fn TryPutAsync(&self, uri: windows_core::Ref<'_, super::super::Foundation::Uri>, content: windows_core::Ref<'_, IHttpContent>) -> windows_core::Result>; + fn TrySendRequestAsync(&self, request: windows_core::Ref<'_, HttpRequestMessage>) -> windows_core::Result>; + fn TrySendRequestAsync2(&self, request: windows_core::Ref<'_, HttpRequestMessage>, completionOption: HttpCompletionOption) -> windows_core::Result>; +} +impl IHttpClient2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn TryDeleteAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient2_Impl::TryDeleteAsync(this, core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryGetAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient2_Impl::TryGetAsync(this, core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryGetAsync2(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, completionoption: HttpCompletionOption, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient2_Impl::TryGetAsync2(this, core::mem::transmute_copy(&uri), completionoption) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryGetBufferAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient2_Impl::TryGetBufferAsync(this, core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryGetInputStreamAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient2_Impl::TryGetInputStreamAsync(this, core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryGetStringAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient2_Impl::TryGetStringAsync(this, core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryPostAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, content: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient2_Impl::TryPostAsync(this, core::mem::transmute_copy(&uri), core::mem::transmute_copy(&content)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryPutAsync(this: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, content: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient2_Impl::TryPutAsync(this, core::mem::transmute_copy(&uri), core::mem::transmute_copy(&content)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TrySendRequestAsync(this: *mut core::ffi::c_void, request: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient2_Impl::TrySendRequestAsync(this, core::mem::transmute_copy(&request)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TrySendRequestAsync2(this: *mut core::ffi::c_void, request: *mut core::ffi::c_void, completionoption: HttpCompletionOption, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient2_Impl::TrySendRequestAsync2(this, core::mem::transmute_copy(&request), completionoption) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + TryDeleteAsync: TryDeleteAsync::, + TryGetAsync: TryGetAsync::, + TryGetAsync2: TryGetAsync2::, + TryGetBufferAsync: TryGetBufferAsync::, + TryGetInputStreamAsync: TryGetInputStreamAsync::, + TryGetStringAsync: TryGetStringAsync::, + TryPostAsync: TryPostAsync::, + TryPutAsync: TryPutAsync::, + TrySendRequestAsync: TrySendRequestAsync::, + TrySendRequestAsync2: TrySendRequestAsync2::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpClient2_Vtbl { @@ -18527,6 +95602,44 @@ windows_core::imp::define_interface!(IHttpClient3, IHttpClient3_Vtbl, 0x1172fd01 impl windows_core::RuntimeType for IHttpClient3 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpClient3 { + const NAME: &'static str = "Windows.Web.Http.IHttpClient3"; +} +pub trait IHttpClient3_Impl: windows_core::IUnknownImpl { + fn DefaultPrivacyAnnotation(&self) -> windows_core::Result; + fn SetDefaultPrivacyAnnotation(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; +} +impl IHttpClient3_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DefaultPrivacyAnnotation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClient3_Impl::DefaultPrivacyAnnotation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDefaultPrivacyAnnotation(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpClient3_Impl::SetDefaultPrivacyAnnotation(this, core::mem::transmute(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DefaultPrivacyAnnotation: DefaultPrivacyAnnotation::, + SetDefaultPrivacyAnnotation: SetDefaultPrivacyAnnotation::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpClient3_Vtbl { @@ -18538,6 +95651,36 @@ windows_core::imp::define_interface!(IHttpClientFactory, IHttpClientFactory_Vtbl impl windows_core::RuntimeType for IHttpClientFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Web_Http_Filters")] +impl windows_core::RuntimeName for IHttpClientFactory { + const NAME: &'static str = "Windows.Web.Http.IHttpClientFactory"; +} +#[cfg(feature = "Web_Http_Filters")] +pub trait IHttpClientFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, filter: windows_core::Ref<'_, Filters::IHttpFilter>) -> windows_core::Result; +} +#[cfg(feature = "Web_Http_Filters")] +impl IHttpClientFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, filter: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpClientFactory_Impl::Create(this, core::mem::transmute_copy(&filter)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpClientFactory_Vtbl { @@ -18562,6 +95705,13 @@ impl IHttpContent { (windows_core::Interface::vtable(this).Headers)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn BufferAllAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).BufferAllAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } #[cfg(feature = "Storage_Streams")] pub fn ReadAsBufferAsync(&self) -> windows_core::Result> { let this = self; @@ -18578,6 +95728,31 @@ impl IHttpContent { (windows_core::Interface::vtable(this).ReadAsInputStreamAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ReadAsStringAsync(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ReadAsStringAsync)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn TryComputeLength(&self, length: &mut u64) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryComputeLength)(windows_core::Interface::as_raw(this), length, &mut result__).map(|| result__) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn WriteToStreamAsync(&self, outputstream: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WriteToStreamAsync)(windows_core::Interface::as_raw(this), outputstream.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Close(&self) -> windows_core::Result<()> { let this = &windows_core::Interface::cast::(self)?; unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } @@ -18595,7 +95770,7 @@ pub trait IHttpContent_Impl: super::super::Foundation::IClosable_Impl { fn ReadAsInputStreamAsync(&self) -> windows_core::Result>; fn ReadAsStringAsync(&self) -> windows_core::Result>; fn TryComputeLength(&self, length: &mut u64) -> windows_core::Result; - fn WriteToStreamAsync(&self, outputStream: windows_core::Ref) -> windows_core::Result>; + fn WriteToStreamAsync(&self, outputStream: windows_core::Ref<'_, super::super::Storage::Streams::IOutputStream>) -> windows_core::Result>; } #[cfg(all(feature = "Storage_Streams", feature = "Web_Http_Headers"))] impl IHttpContent_Vtbl { @@ -18733,6 +95908,33 @@ windows_core::imp::define_interface!(IHttpFormUrlEncodedContentFactory, IHttpFor impl windows_core::RuntimeType for IHttpFormUrlEncodedContentFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpFormUrlEncodedContentFactory { + const NAME: &'static str = "Windows.Web.Http.IHttpFormUrlEncodedContentFactory"; +} +pub trait IHttpFormUrlEncodedContentFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, content: windows_core::Ref<'_, windows_collections::IIterable>>) -> windows_core::Result; +} +impl IHttpFormUrlEncodedContentFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, content: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpFormUrlEncodedContentFactory_Impl::Create(this, core::mem::transmute_copy(&content)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpFormUrlEncodedContentFactory_Vtbl { @@ -18743,6 +95945,97 @@ windows_core::imp::define_interface!(IHttpGetBufferResult, IHttpGetBufferResult_ impl windows_core::RuntimeType for IHttpGetBufferResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IHttpGetBufferResult { + const NAME: &'static str = "Windows.Web.Http.IHttpGetBufferResult"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IHttpGetBufferResult_Impl: windows_core::IUnknownImpl { + fn ExtendedError(&self) -> windows_core::Result; + fn RequestMessage(&self) -> windows_core::Result; + fn ResponseMessage(&self) -> windows_core::Result; + fn Succeeded(&self) -> windows_core::Result; + fn Value(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IHttpGetBufferResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ExtendedError(this: *mut core::ffi::c_void, result__: *mut windows_core::HRESULT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpGetBufferResult_Impl::ExtendedError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RequestMessage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpGetBufferResult_Impl::RequestMessage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResponseMessage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpGetBufferResult_Impl::ResponseMessage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Succeeded(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpGetBufferResult_Impl::Succeeded(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpGetBufferResult_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ExtendedError: ExtendedError::, + RequestMessage: RequestMessage::, + ResponseMessage: ResponseMessage::, + Succeeded: Succeeded::, + Value: Value::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpGetBufferResult_Vtbl { @@ -18760,6 +96053,97 @@ windows_core::imp::define_interface!(IHttpGetInputStreamResult, IHttpGetInputStr impl windows_core::RuntimeType for IHttpGetInputStreamResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IHttpGetInputStreamResult { + const NAME: &'static str = "Windows.Web.Http.IHttpGetInputStreamResult"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IHttpGetInputStreamResult_Impl: windows_core::IUnknownImpl { + fn ExtendedError(&self) -> windows_core::Result; + fn RequestMessage(&self) -> windows_core::Result; + fn ResponseMessage(&self) -> windows_core::Result; + fn Succeeded(&self) -> windows_core::Result; + fn Value(&self) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IHttpGetInputStreamResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ExtendedError(this: *mut core::ffi::c_void, result__: *mut windows_core::HRESULT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpGetInputStreamResult_Impl::ExtendedError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RequestMessage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpGetInputStreamResult_Impl::RequestMessage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResponseMessage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpGetInputStreamResult_Impl::ResponseMessage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Succeeded(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpGetInputStreamResult_Impl::Succeeded(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpGetInputStreamResult_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ExtendedError: ExtendedError::, + RequestMessage: RequestMessage::, + ResponseMessage: ResponseMessage::, + Succeeded: Succeeded::, + Value: Value::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpGetInputStreamResult_Vtbl { @@ -18777,6 +96161,94 @@ windows_core::imp::define_interface!(IHttpGetStringResult, IHttpGetStringResult_ impl windows_core::RuntimeType for IHttpGetStringResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpGetStringResult { + const NAME: &'static str = "Windows.Web.Http.IHttpGetStringResult"; +} +pub trait IHttpGetStringResult_Impl: windows_core::IUnknownImpl { + fn ExtendedError(&self) -> windows_core::Result; + fn RequestMessage(&self) -> windows_core::Result; + fn ResponseMessage(&self) -> windows_core::Result; + fn Succeeded(&self) -> windows_core::Result; + fn Value(&self) -> windows_core::Result; +} +impl IHttpGetStringResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ExtendedError(this: *mut core::ffi::c_void, result__: *mut windows_core::HRESULT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpGetStringResult_Impl::ExtendedError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RequestMessage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpGetStringResult_Impl::RequestMessage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResponseMessage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpGetStringResult_Impl::ResponseMessage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Succeeded(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpGetStringResult_Impl::Succeeded(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpGetStringResult_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ExtendedError: ExtendedError::, + RequestMessage: RequestMessage::, + ResponseMessage: ResponseMessage::, + Succeeded: Succeeded::, + Value: Value::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpGetStringResult_Vtbl { @@ -18791,6 +96263,33 @@ windows_core::imp::define_interface!(IHttpMethod, IHttpMethod_Vtbl, 0x728d4022_7 impl windows_core::RuntimeType for IHttpMethod { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpMethod { + const NAME: &'static str = "Windows.Web.Http.IHttpMethod"; +} +pub trait IHttpMethod_Impl: windows_core::IUnknownImpl { + fn Method(&self) -> windows_core::Result; +} +impl IHttpMethod_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Method(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMethod_Impl::Method(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Method: Method:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpMethod_Vtbl { @@ -18801,6 +96300,33 @@ windows_core::imp::define_interface!(IHttpMethodFactory, IHttpMethodFactory_Vtbl impl windows_core::RuntimeType for IHttpMethodFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpMethodFactory { + const NAME: &'static str = "Windows.Web.Http.IHttpMethodFactory"; +} +pub trait IHttpMethodFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, method: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpMethodFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, method: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMethodFactory_Impl::Create(this, core::mem::transmute(&method)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpMethodFactory_Vtbl { @@ -18811,6 +96337,126 @@ windows_core::imp::define_interface!(IHttpMethodStatics, IHttpMethodStatics_Vtbl impl windows_core::RuntimeType for IHttpMethodStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpMethodStatics { + const NAME: &'static str = "Windows.Web.Http.IHttpMethodStatics"; +} +pub trait IHttpMethodStatics_Impl: windows_core::IUnknownImpl { + fn Delete(&self) -> windows_core::Result; + fn Get(&self) -> windows_core::Result; + fn Head(&self) -> windows_core::Result; + fn Options(&self) -> windows_core::Result; + fn Patch(&self) -> windows_core::Result; + fn Post(&self) -> windows_core::Result; + fn Put(&self) -> windows_core::Result; +} +impl IHttpMethodStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Delete(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMethodStatics_Impl::Delete(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Get(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMethodStatics_Impl::Get(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Head(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMethodStatics_Impl::Head(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Options(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMethodStatics_Impl::Options(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Patch(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMethodStatics_Impl::Patch(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Post(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMethodStatics_Impl::Post(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Put(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMethodStatics_Impl::Put(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Delete: Delete::, + Get: Get::, + Head: Head::, + Options: Options::, + Patch: Patch::, + Post: Post::, + Put: Put::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpMethodStatics_Vtbl { @@ -18827,6 +96473,26 @@ windows_core::imp::define_interface!(IHttpMultipartContent, IHttpMultipartConten impl windows_core::RuntimeType for IHttpMultipartContent { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpMultipartContent { + const NAME: &'static str = "Windows.Web.Http.IHttpMultipartContent"; +} +pub trait IHttpMultipartContent_Impl: windows_core::IUnknownImpl { + fn Add(&self, content: windows_core::Ref<'_, IHttpContent>) -> windows_core::Result<()>; +} +impl IHttpMultipartContent_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Add(this: *mut core::ffi::c_void, content: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpMultipartContent_Impl::Add(this, core::mem::transmute_copy(&content)).into() + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Add: Add:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpMultipartContent_Vtbl { @@ -18837,6 +96503,51 @@ windows_core::imp::define_interface!(IHttpMultipartContentFactory, IHttpMultipar impl windows_core::RuntimeType for IHttpMultipartContentFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpMultipartContentFactory { + const NAME: &'static str = "Windows.Web.Http.IHttpMultipartContentFactory"; +} +pub trait IHttpMultipartContentFactory_Impl: windows_core::IUnknownImpl { + fn CreateWithSubtype(&self, subtype: &windows_core::HSTRING) -> windows_core::Result; + fn CreateWithSubtypeAndBoundary(&self, subtype: &windows_core::HSTRING, boundary: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpMultipartContentFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateWithSubtype(this: *mut core::ffi::c_void, subtype: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMultipartContentFactory_Impl::CreateWithSubtype(this, core::mem::transmute(&subtype)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateWithSubtypeAndBoundary(this: *mut core::ffi::c_void, subtype: *mut core::ffi::c_void, boundary: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMultipartContentFactory_Impl::CreateWithSubtypeAndBoundary(this, core::mem::transmute(&subtype), core::mem::transmute(&boundary)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateWithSubtype: CreateWithSubtype::, + CreateWithSubtypeAndBoundary: CreateWithSubtypeAndBoundary::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpMultipartContentFactory_Vtbl { @@ -18848,6 +96559,45 @@ windows_core::imp::define_interface!(IHttpMultipartFormDataContent, IHttpMultipa impl windows_core::RuntimeType for IHttpMultipartFormDataContent { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpMultipartFormDataContent { + const NAME: &'static str = "Windows.Web.Http.IHttpMultipartFormDataContent"; +} +pub trait IHttpMultipartFormDataContent_Impl: windows_core::IUnknownImpl { + fn Add(&self, content: windows_core::Ref<'_, IHttpContent>) -> windows_core::Result<()>; + fn AddWithName(&self, content: windows_core::Ref<'_, IHttpContent>, name: &windows_core::HSTRING) -> windows_core::Result<()>; + fn AddWithNameAndFileName(&self, content: windows_core::Ref<'_, IHttpContent>, name: &windows_core::HSTRING, fileName: &windows_core::HSTRING) -> windows_core::Result<()>; +} +impl IHttpMultipartFormDataContent_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Add(this: *mut core::ffi::c_void, content: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpMultipartFormDataContent_Impl::Add(this, core::mem::transmute_copy(&content)).into() + } + } + unsafe extern "system" fn AddWithName(this: *mut core::ffi::c_void, content: *mut core::ffi::c_void, name: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpMultipartFormDataContent_Impl::AddWithName(this, core::mem::transmute_copy(&content), core::mem::transmute(&name)).into() + } + } + unsafe extern "system" fn AddWithNameAndFileName(this: *mut core::ffi::c_void, content: *mut core::ffi::c_void, name: *mut core::ffi::c_void, filename: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpMultipartFormDataContent_Impl::AddWithNameAndFileName(this, core::mem::transmute_copy(&content), core::mem::transmute(&name), core::mem::transmute(&filename)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Add: Add::, + AddWithName: AddWithName::, + AddWithNameAndFileName: AddWithNameAndFileName::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpMultipartFormDataContent_Vtbl { @@ -18860,6 +96610,36 @@ windows_core::imp::define_interface!(IHttpMultipartFormDataContentFactory, IHttp impl windows_core::RuntimeType for IHttpMultipartFormDataContentFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpMultipartFormDataContentFactory { + const NAME: &'static str = "Windows.Web.Http.IHttpMultipartFormDataContentFactory"; +} +pub trait IHttpMultipartFormDataContentFactory_Impl: windows_core::IUnknownImpl { + fn CreateWithBoundary(&self, boundary: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpMultipartFormDataContentFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateWithBoundary(this: *mut core::ffi::c_void, boundary: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMultipartFormDataContentFactory_Impl::CreateWithBoundary(this, core::mem::transmute(&boundary)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateWithBoundary: CreateWithBoundary::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpMultipartFormDataContentFactory_Vtbl { @@ -18870,6 +96650,138 @@ windows_core::imp::define_interface!(IHttpRequestMessage, IHttpRequestMessage_Vt impl windows_core::RuntimeType for IHttpRequestMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Web_Http_Headers")] +impl windows_core::RuntimeName for IHttpRequestMessage { + const NAME: &'static str = "Windows.Web.Http.IHttpRequestMessage"; +} +#[cfg(feature = "Web_Http_Headers")] +pub trait IHttpRequestMessage_Impl: windows_core::IUnknownImpl { + fn Content(&self) -> windows_core::Result; + fn SetContent(&self, value: windows_core::Ref<'_, IHttpContent>) -> windows_core::Result<()>; + fn Headers(&self) -> windows_core::Result; + fn Method(&self) -> windows_core::Result; + fn SetMethod(&self, value: windows_core::Ref<'_, HttpMethod>) -> windows_core::Result<()>; + fn Properties(&self) -> windows_core::Result>; + fn RequestUri(&self) -> windows_core::Result; + fn SetRequestUri(&self, value: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result<()>; + fn TransportInformation(&self) -> windows_core::Result; +} +#[cfg(feature = "Web_Http_Headers")] +impl IHttpRequestMessage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Content(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestMessage_Impl::Content(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetContent(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpRequestMessage_Impl::SetContent(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Headers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestMessage_Impl::Headers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Method(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestMessage_Impl::Method(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMethod(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpRequestMessage_Impl::SetMethod(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Properties(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestMessage_Impl::Properties(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RequestUri(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestMessage_Impl::RequestUri(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRequestUri(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpRequestMessage_Impl::SetRequestUri(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn TransportInformation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestMessage_Impl::TransportInformation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Content: Content::, + SetContent: SetContent::, + Headers: Headers::, + Method: Method::, + SetMethod: SetMethod::, + Properties: Properties::, + RequestUri: RequestUri::, + SetRequestUri: SetRequestUri::, + TransportInformation: TransportInformation::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpRequestMessage_Vtbl { @@ -18891,6 +96803,44 @@ windows_core::imp::define_interface!(IHttpRequestMessage2, IHttpRequestMessage2_ impl windows_core::RuntimeType for IHttpRequestMessage2 { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpRequestMessage2 { + const NAME: &'static str = "Windows.Web.Http.IHttpRequestMessage2"; +} +pub trait IHttpRequestMessage2_Impl: windows_core::IUnknownImpl { + fn PrivacyAnnotation(&self) -> windows_core::Result; + fn SetPrivacyAnnotation(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; +} +impl IHttpRequestMessage2_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn PrivacyAnnotation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestMessage2_Impl::PrivacyAnnotation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetPrivacyAnnotation(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpRequestMessage2_Impl::SetPrivacyAnnotation(this, core::mem::transmute(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + PrivacyAnnotation: PrivacyAnnotation::, + SetPrivacyAnnotation: SetPrivacyAnnotation::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpRequestMessage2_Vtbl { @@ -18902,6 +96852,33 @@ windows_core::imp::define_interface!(IHttpRequestMessageFactory, IHttpRequestMes impl windows_core::RuntimeType for IHttpRequestMessageFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpRequestMessageFactory { + const NAME: &'static str = "Windows.Web.Http.IHttpRequestMessageFactory"; +} +pub trait IHttpRequestMessageFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, method: windows_core::Ref<'_, HttpMethod>, uri: windows_core::Ref<'_, super::super::Foundation::Uri>) -> windows_core::Result; +} +impl IHttpRequestMessageFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, method: *mut core::ffi::c_void, uri: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestMessageFactory_Impl::Create(this, core::mem::transmute_copy(&method), core::mem::transmute_copy(&uri)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpRequestMessageFactory_Vtbl { @@ -18912,6 +96889,79 @@ windows_core::imp::define_interface!(IHttpRequestResult, IHttpRequestResult_Vtbl impl windows_core::RuntimeType for IHttpRequestResult { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpRequestResult { + const NAME: &'static str = "Windows.Web.Http.IHttpRequestResult"; +} +pub trait IHttpRequestResult_Impl: windows_core::IUnknownImpl { + fn ExtendedError(&self) -> windows_core::Result; + fn RequestMessage(&self) -> windows_core::Result; + fn ResponseMessage(&self) -> windows_core::Result; + fn Succeeded(&self) -> windows_core::Result; +} +impl IHttpRequestResult_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ExtendedError(this: *mut core::ffi::c_void, result__: *mut windows_core::HRESULT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestResult_Impl::ExtendedError(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RequestMessage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestResult_Impl::RequestMessage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ResponseMessage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestResult_Impl::ResponseMessage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Succeeded(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestResult_Impl::Succeeded(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ExtendedError: ExtendedError::, + RequestMessage: RequestMessage::, + ResponseMessage: ResponseMessage::, + Succeeded: Succeeded::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpRequestResult_Vtbl { @@ -18925,6 +96975,203 @@ windows_core::imp::define_interface!(IHttpResponseMessage, IHttpResponseMessage_ impl windows_core::RuntimeType for IHttpResponseMessage { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Web_Http_Headers")] +impl windows_core::RuntimeName for IHttpResponseMessage { + const NAME: &'static str = "Windows.Web.Http.IHttpResponseMessage"; +} +#[cfg(feature = "Web_Http_Headers")] +pub trait IHttpResponseMessage_Impl: windows_core::IUnknownImpl { + fn Content(&self) -> windows_core::Result; + fn SetContent(&self, value: windows_core::Ref<'_, IHttpContent>) -> windows_core::Result<()>; + fn Headers(&self) -> windows_core::Result; + fn IsSuccessStatusCode(&self) -> windows_core::Result; + fn ReasonPhrase(&self) -> windows_core::Result; + fn SetReasonPhrase(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn RequestMessage(&self) -> windows_core::Result; + fn SetRequestMessage(&self, value: windows_core::Ref<'_, HttpRequestMessage>) -> windows_core::Result<()>; + fn Source(&self) -> windows_core::Result; + fn SetSource(&self, value: HttpResponseMessageSource) -> windows_core::Result<()>; + fn StatusCode(&self) -> windows_core::Result; + fn SetStatusCode(&self, value: HttpStatusCode) -> windows_core::Result<()>; + fn Version(&self) -> windows_core::Result; + fn SetVersion(&self, value: HttpVersion) -> windows_core::Result<()>; + fn EnsureSuccessStatusCode(&self) -> windows_core::Result; +} +#[cfg(feature = "Web_Http_Headers")] +impl IHttpResponseMessage_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Content(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseMessage_Impl::Content(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetContent(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpResponseMessage_Impl::SetContent(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Headers(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseMessage_Impl::Headers(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn IsSuccessStatusCode(this: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseMessage_Impl::IsSuccessStatusCode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ReasonPhrase(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseMessage_Impl::ReasonPhrase(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetReasonPhrase(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpResponseMessage_Impl::SetReasonPhrase(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn RequestMessage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseMessage_Impl::RequestMessage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRequestMessage(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpResponseMessage_Impl::SetRequestMessage(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Source(this: *mut core::ffi::c_void, result__: *mut HttpResponseMessageSource) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseMessage_Impl::Source(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetSource(this: *mut core::ffi::c_void, value: HttpResponseMessageSource) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpResponseMessage_Impl::SetSource(this, value).into() + } + } + unsafe extern "system" fn StatusCode(this: *mut core::ffi::c_void, result__: *mut HttpStatusCode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseMessage_Impl::StatusCode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetStatusCode(this: *mut core::ffi::c_void, value: HttpStatusCode) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpResponseMessage_Impl::SetStatusCode(this, value).into() + } + } + unsafe extern "system" fn Version(this: *mut core::ffi::c_void, result__: *mut HttpVersion) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseMessage_Impl::Version(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetVersion(this: *mut core::ffi::c_void, value: HttpVersion) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpResponseMessage_Impl::SetVersion(this, value).into() + } + } + unsafe extern "system" fn EnsureSuccessStatusCode(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseMessage_Impl::EnsureSuccessStatusCode(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Content: Content::, + SetContent: SetContent::, + Headers: Headers::, + IsSuccessStatusCode: IsSuccessStatusCode::, + ReasonPhrase: ReasonPhrase::, + SetReasonPhrase: SetReasonPhrase::, + RequestMessage: RequestMessage::, + SetRequestMessage: SetRequestMessage::, + Source: Source::, + SetSource: SetSource::, + StatusCode: StatusCode::, + SetStatusCode: SetStatusCode::, + Version: Version::, + SetVersion: SetVersion::, + EnsureSuccessStatusCode: EnsureSuccessStatusCode::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpResponseMessage_Vtbl { @@ -18952,6 +97199,33 @@ windows_core::imp::define_interface!(IHttpResponseMessageFactory, IHttpResponseM impl windows_core::RuntimeType for IHttpResponseMessageFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpResponseMessageFactory { + const NAME: &'static str = "Windows.Web.Http.IHttpResponseMessageFactory"; +} +pub trait IHttpResponseMessageFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, statusCode: HttpStatusCode) -> windows_core::Result; +} +impl IHttpResponseMessageFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, statuscode: HttpStatusCode, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseMessageFactory_Impl::Create(this, statuscode) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpResponseMessageFactory_Vtbl { @@ -18962,6 +97236,39 @@ windows_core::imp::define_interface!(IHttpStreamContentFactory, IHttpStreamConte impl windows_core::RuntimeType for IHttpStreamContentFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IHttpStreamContentFactory { + const NAME: &'static str = "Windows.Web.Http.IHttpStreamContentFactory"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IHttpStreamContentFactory_Impl: windows_core::IUnknownImpl { + fn CreateFromInputStream(&self, content: windows_core::Ref<'_, super::super::Storage::Streams::IInputStream>) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IHttpStreamContentFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromInputStream(this: *mut core::ffi::c_void, content: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpStreamContentFactory_Impl::CreateFromInputStream(this, core::mem::transmute_copy(&content)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromInputStream: CreateFromInputStream::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpStreamContentFactory_Vtbl { @@ -18975,6 +97282,69 @@ windows_core::imp::define_interface!(IHttpStringContentFactory, IHttpStringConte impl windows_core::RuntimeType for IHttpStringContentFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Storage_Streams")] +impl windows_core::RuntimeName for IHttpStringContentFactory { + const NAME: &'static str = "Windows.Web.Http.IHttpStringContentFactory"; +} +#[cfg(feature = "Storage_Streams")] +pub trait IHttpStringContentFactory_Impl: windows_core::IUnknownImpl { + fn CreateFromString(&self, content: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromStringWithEncoding(&self, content: &windows_core::HSTRING, encoding: super::super::Storage::Streams::UnicodeEncoding) -> windows_core::Result; + fn CreateFromStringWithEncodingAndMediaType(&self, content: &windows_core::HSTRING, encoding: super::super::Storage::Streams::UnicodeEncoding, mediaType: &windows_core::HSTRING) -> windows_core::Result; +} +#[cfg(feature = "Storage_Streams")] +impl IHttpStringContentFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromString(this: *mut core::ffi::c_void, content: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpStringContentFactory_Impl::CreateFromString(this, core::mem::transmute(&content)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromStringWithEncoding(this: *mut core::ffi::c_void, content: *mut core::ffi::c_void, encoding: super::super::Storage::Streams::UnicodeEncoding, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpStringContentFactory_Impl::CreateFromStringWithEncoding(this, core::mem::transmute(&content), encoding) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromStringWithEncodingAndMediaType(this: *mut core::ffi::c_void, content: *mut core::ffi::c_void, encoding: super::super::Storage::Streams::UnicodeEncoding, mediatype: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpStringContentFactory_Impl::CreateFromStringWithEncodingAndMediaType(this, core::mem::transmute(&content), encoding, core::mem::transmute(&mediatype)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromString: CreateFromString::, + CreateFromStringWithEncoding: CreateFromStringWithEncoding::, + CreateFromStringWithEncodingAndMediaType: CreateFromStringWithEncodingAndMediaType::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpStringContentFactory_Vtbl { @@ -18993,6 +97363,83 @@ windows_core::imp::define_interface!(IHttpTransportInformation, IHttpTransportIn impl windows_core::RuntimeType for IHttpTransportInformation { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(all(feature = "Networking_Sockets", feature = "Security_Cryptography_Certificates"))] +impl windows_core::RuntimeName for IHttpTransportInformation { + const NAME: &'static str = "Windows.Web.Http.IHttpTransportInformation"; +} +#[cfg(all(feature = "Networking_Sockets", feature = "Security_Cryptography_Certificates"))] +pub trait IHttpTransportInformation_Impl: windows_core::IUnknownImpl { + fn ServerCertificate(&self) -> windows_core::Result; + fn ServerCertificateErrorSeverity(&self) -> windows_core::Result; + fn ServerCertificateErrors(&self) -> windows_core::Result>; + fn ServerIntermediateCertificates(&self) -> windows_core::Result>; +} +#[cfg(all(feature = "Networking_Sockets", feature = "Security_Cryptography_Certificates"))] +impl IHttpTransportInformation_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ServerCertificate(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpTransportInformation_Impl::ServerCertificate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ServerCertificateErrorSeverity(this: *mut core::ffi::c_void, result__: *mut super::super::Networking::Sockets::SocketSslErrorSeverity) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpTransportInformation_Impl::ServerCertificateErrorSeverity(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ServerCertificateErrors(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpTransportInformation_Impl::ServerCertificateErrors(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ServerIntermediateCertificates(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpTransportInformation_Impl::ServerIntermediateCertificates(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ServerCertificate: ServerCertificate::, + ServerCertificateErrorSeverity: ServerCertificateErrorSeverity::, + ServerCertificateErrors: ServerCertificateErrors::, + ServerIntermediateCertificates: ServerIntermediateCertificates::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpTransportInformation_Vtbl { @@ -19014,6 +97461,65 @@ pub struct IHttpTransportInformation_Vtbl { #[cfg(not(feature = "Security_Cryptography_Certificates"))] ServerIntermediateCertificates: usize, } +#[cfg(feature = "Web_Http_Filters")] +pub mod Filters{ +windows_core::imp::define_interface!(IHttpFilter, IHttpFilter_Vtbl, 0xa4cb6dd5_0902_439e_bfd7_e12552b165ce); +impl windows_core::RuntimeType for IHttpFilter { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +windows_core::imp::interface_hierarchy!(IHttpFilter, windows_core::IUnknown, windows_core::IInspectable); +windows_core::imp::required_hierarchy!(IHttpFilter, super::super::super::Foundation::IClosable); +impl IHttpFilter { + pub fn SendRequestAsync(&self, request: P0) -> windows_core::Result> + where + P0: windows_core::Param, + { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SendRequestAsync)(windows_core::Interface::as_raw(this), request.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Close(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::(self)?; + unsafe { (windows_core::Interface::vtable(this).Close)(windows_core::Interface::as_raw(this)).ok() } + } +} +impl windows_core::RuntimeName for IHttpFilter { + const NAME: &'static str = "Windows.Web.Http.Filters.IHttpFilter"; +} +pub trait IHttpFilter_Impl: super::super::super::Foundation::IClosable_Impl { + fn SendRequestAsync(&self, request: windows_core::Ref<'_, super::HttpRequestMessage>) -> windows_core::Result>; +} +impl IHttpFilter_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn SendRequestAsync(this: *mut core::ffi::c_void, request: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpFilter_Impl::SendRequestAsync(this, core::mem::transmute_copy(&request)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), SendRequestAsync: SendRequestAsync:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IHttpFilter_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub SendRequestAsync: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +} +#[cfg(feature = "Web_Http_Headers")] pub mod Headers{ #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] @@ -19021,6 +97527,73 @@ pub struct HttpCacheDirectiveHeaderValueCollection(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpCacheDirectiveHeaderValueCollection, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpCacheDirectiveHeaderValueCollection, windows_collections::IIterable, super::super::super::Foundation::IStringable, windows_collections::IVector); impl HttpCacheDirectiveHeaderValueCollection { + pub fn MaxAge(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxAge)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetMaxAge(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMaxAge)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn MaxStale(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxStale)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetMaxStale(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMaxStale)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn MinFresh(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MinFresh)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetMinFresh(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMinFresh)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn SharedMaxAge(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).SharedMaxAge)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetSharedMaxAge(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSharedMaxAge)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input)).ok() } + } + pub fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).map(|| result__) + } + } pub fn First(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::>(self)?; unsafe { @@ -19028,6 +97601,62 @@ impl HttpCacheDirectiveHeaderValueCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn SetAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn InsertAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).InsertAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn RemoveAt(&self, index: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAt)(windows_core::Interface::as_raw(this), index).ok() } + } pub fn Append(&self, value: P0) -> windows_core::Result<()> where P0: windows_core::Param, @@ -19035,7 +97664,26 @@ impl HttpCacheDirectiveHeaderValueCollection { let this = &windows_core::Interface::cast::>(self)?; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } } + pub fn RemoveAtEnd(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAtEnd)(windows_core::Interface::as_raw(this)).ok() } } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } + pub fn ReplaceAll(&self, items: &[Option]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).ReplaceAll)(windows_core::Interface::as_raw(this), items.len().try_into().unwrap(), core::mem::transmute(items.as_ptr())).ok() } + } +} impl windows_core::RuntimeType for HttpCacheDirectiveHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -19068,6 +97716,58 @@ pub struct HttpChallengeHeaderValue(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpChallengeHeaderValue, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpChallengeHeaderValue, super::super::super::Foundation::IStringable); impl HttpChallengeHeaderValue { + pub fn Parameters(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parameters)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Scheme(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Scheme)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Token(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Token)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn CreateFromScheme(scheme: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpChallengeHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromScheme)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(scheme), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromSchemeWithToken(scheme: &windows_core::HSTRING, token: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpChallengeHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromSchemeWithToken)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(scheme), core::mem::transmute_copy(token), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpChallengeHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, challengeheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpChallengeHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), challengeheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpChallengeHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -19095,6 +97795,17 @@ pub struct HttpChallengeHeaderValueCollection(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpChallengeHeaderValueCollection, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpChallengeHeaderValueCollection, windows_collections::IIterable, super::super::super::Foundation::IStringable, windows_collections::IVector); impl HttpChallengeHeaderValueCollection { + pub fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input)).ok() } + } + pub fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).map(|| result__) + } + } pub fn First(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::>(self)?; unsafe { @@ -19102,6 +97813,62 @@ impl HttpChallengeHeaderValueCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn SetAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn InsertAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).InsertAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn RemoveAt(&self, index: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAt)(windows_core::Interface::as_raw(this), index).ok() } + } pub fn Append(&self, value: P0) -> windows_core::Result<()> where P0: windows_core::Param, @@ -19109,7 +97876,26 @@ impl HttpChallengeHeaderValueCollection { let this = &windows_core::Interface::cast::>(self)?; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } } + pub fn RemoveAtEnd(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAtEnd)(windows_core::Interface::as_raw(this)).ok() } } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } + pub fn ReplaceAll(&self, items: &[Option]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).ReplaceAll)(windows_core::Interface::as_raw(this), items.len().try_into().unwrap(), core::mem::transmute(items.as_ptr())).ok() } + } +} impl windows_core::RuntimeType for HttpChallengeHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -19142,12 +97928,38 @@ pub struct HttpConnectionOptionHeaderValue(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpConnectionOptionHeaderValue, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpConnectionOptionHeaderValue, super::super::super::Foundation::IStringable); impl HttpConnectionOptionHeaderValue { + pub fn Token(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Token)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } pub fn Create(token: &windows_core::HSTRING) -> windows_core::Result { Self::IHttpConnectionOptionHeaderValueFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(token), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpConnectionOptionHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, connectionoptionheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpConnectionOptionHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), connectionoptionheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpConnectionOptionHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -19175,6 +97987,17 @@ pub struct HttpConnectionOptionHeaderValueCollection(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpConnectionOptionHeaderValueCollection, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpConnectionOptionHeaderValueCollection, windows_collections::IIterable, super::super::super::Foundation::IStringable, windows_collections::IVector); impl HttpConnectionOptionHeaderValueCollection { + pub fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input)).ok() } + } + pub fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).map(|| result__) + } + } pub fn First(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::>(self)?; unsafe { @@ -19182,6 +98005,62 @@ impl HttpConnectionOptionHeaderValueCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn SetAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn InsertAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).InsertAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn RemoveAt(&self, index: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAt)(windows_core::Interface::as_raw(this), index).ok() } + } pub fn Append(&self, value: P0) -> windows_core::Result<()> where P0: windows_core::Param, @@ -19189,7 +98068,26 @@ impl HttpConnectionOptionHeaderValueCollection { let this = &windows_core::Interface::cast::>(self)?; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } } + pub fn RemoveAtEnd(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAtEnd)(windows_core::Interface::as_raw(this)).ok() } } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } + pub fn ReplaceAll(&self, items: &[Option]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).ReplaceAll)(windows_core::Interface::as_raw(this), items.len().try_into().unwrap(), core::mem::transmute(items.as_ptr())).ok() } + } +} impl windows_core::RuntimeType for HttpConnectionOptionHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -19222,12 +98120,38 @@ pub struct HttpContentCodingHeaderValue(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpContentCodingHeaderValue, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpContentCodingHeaderValue, super::super::super::Foundation::IStringable); impl HttpContentCodingHeaderValue { + pub fn ContentCoding(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentCoding)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } pub fn Create(contentcoding: &windows_core::HSTRING) -> windows_core::Result { Self::IHttpContentCodingHeaderValueFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(contentcoding), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpContentCodingHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, contentcodingheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpContentCodingHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), contentcodingheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpContentCodingHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -19255,6 +98179,17 @@ pub struct HttpContentCodingHeaderValueCollection(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpContentCodingHeaderValueCollection, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpContentCodingHeaderValueCollection, windows_collections::IIterable, super::super::super::Foundation::IStringable, windows_collections::IVector); impl HttpContentCodingHeaderValueCollection { + pub fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input)).ok() } + } + pub fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).map(|| result__) + } + } pub fn First(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::>(self)?; unsafe { @@ -19262,6 +98197,62 @@ impl HttpContentCodingHeaderValueCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn SetAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn InsertAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).InsertAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn RemoveAt(&self, index: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAt)(windows_core::Interface::as_raw(this), index).ok() } + } pub fn Append(&self, value: P0) -> windows_core::Result<()> where P0: windows_core::Param, @@ -19269,7 +98260,26 @@ impl HttpContentCodingHeaderValueCollection { let this = &windows_core::Interface::cast::>(self)?; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } } + pub fn RemoveAtEnd(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAtEnd)(windows_core::Interface::as_raw(this)).ok() } } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } + pub fn ReplaceAll(&self, items: &[Option]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).ReplaceAll)(windows_core::Interface::as_raw(this), items.len().try_into().unwrap(), core::mem::transmute(items.as_ptr())).ok() } + } +} impl windows_core::RuntimeType for HttpContentCodingHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -19302,6 +98312,51 @@ pub struct HttpContentCodingWithQualityHeaderValue(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpContentCodingWithQualityHeaderValue, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpContentCodingWithQualityHeaderValue, super::super::super::Foundation::IStringable); impl HttpContentCodingWithQualityHeaderValue { + pub fn ContentCoding(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentCoding)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Quality(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Quality)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFromValue(contentcoding: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpContentCodingWithQualityHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromValue)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(contentcoding), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromValueWithQuality(contentcoding: &windows_core::HSTRING, quality: f64) -> windows_core::Result { + Self::IHttpContentCodingWithQualityHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromValueWithQuality)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(contentcoding), quality, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpContentCodingWithQualityHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, contentcodingwithqualityheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpContentCodingWithQualityHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), contentcodingwithqualityheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpContentCodingWithQualityHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -19329,6 +98384,17 @@ pub struct HttpContentCodingWithQualityHeaderValueCollection(windows_core::IUnkn windows_core::imp::interface_hierarchy!(HttpContentCodingWithQualityHeaderValueCollection, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpContentCodingWithQualityHeaderValueCollection, windows_collections::IIterable, super::super::super::Foundation::IStringable, windows_collections::IVector); impl HttpContentCodingWithQualityHeaderValueCollection { + pub fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input)).ok() } + } + pub fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).map(|| result__) + } + } pub fn First(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::>(self)?; unsafe { @@ -19336,6 +98402,62 @@ impl HttpContentCodingWithQualityHeaderValueCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn SetAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn InsertAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).InsertAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn RemoveAt(&self, index: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAt)(windows_core::Interface::as_raw(this), index).ok() } + } pub fn Append(&self, value: P0) -> windows_core::Result<()> where P0: windows_core::Param, @@ -19343,7 +98465,26 @@ impl HttpContentCodingWithQualityHeaderValueCollection { let this = &windows_core::Interface::cast::>(self)?; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } } + pub fn RemoveAtEnd(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAtEnd)(windows_core::Interface::as_raw(this)).ok() } } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } + pub fn ReplaceAll(&self, items: &[Option]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).ReplaceAll)(windows_core::Interface::as_raw(this), items.len().try_into().unwrap(), core::mem::transmute(items.as_ptr())).ok() } + } +} impl windows_core::RuntimeType for HttpContentCodingWithQualityHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -19376,6 +98517,39 @@ pub struct HttpContentDispositionHeaderValue(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpContentDispositionHeaderValue, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpContentDispositionHeaderValue, super::super::super::Foundation::IStringable); impl HttpContentDispositionHeaderValue { + pub fn DispositionType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).DispositionType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetDispositionType(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDispositionType)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn FileName(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FileName)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetFileName(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetFileName)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn FileNameStar(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FileNameStar)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetFileNameStar(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetFileNameStar)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } pub fn Name(&self) -> windows_core::Result { let this = self; unsafe { @@ -19383,12 +98557,56 @@ impl HttpContentDispositionHeaderValue { (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn SetName(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetName)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Parameters(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parameters)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetSize(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetSize)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } pub fn Create(dispositiontype: &windows_core::HSTRING) -> windows_core::Result { Self::IHttpContentDispositionHeaderValueFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(dispositiontype), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpContentDispositionHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, contentdispositionheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpContentDispositionHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), contentdispositionheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpContentDispositionHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -19423,10 +98641,146 @@ impl HttpContentHeaderCollection { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) } + pub fn ContentDisposition(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentDisposition)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetContentDisposition(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetContentDisposition)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn ContentEncoding(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentEncoding)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Globalization")] + pub fn ContentLanguage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentLanguage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ContentLength(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentLength)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetContentLength(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetContentLength)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn ContentLocation(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentLocation)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetContentLocation(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetContentLocation)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + #[cfg(feature = "Storage_Streams")] + pub fn ContentMD5(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentMD5)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Storage_Streams")] + pub fn SetContentMD5(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetContentMD5)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn ContentRange(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentRange)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetContentRange(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetContentRange)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn ContentType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ContentType)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetContentType(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetContentType)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn Expires(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Expires)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetExpires(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetExpires)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn LastModified(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LastModified)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetLastModified(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetLastModified)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } pub fn Append(&self, name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), core::mem::transmute_copy(value)).ok() } } + pub fn TryAppendWithoutValidation(&self, name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryAppendWithoutValidation)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), core::mem::transmute_copy(value), &mut result__).map(|| result__) + } + } pub fn First(&self) -> windows_core::Result>> { let this = &windows_core::Interface::cast::>>(self)?; unsafe { @@ -19434,7 +98788,57 @@ impl HttpContentHeaderCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Lookup(&self, key: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Lookup)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), &mut result__).map(|| core::mem::transmute(result__)) + } } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn HasKey(&self, key: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HasKey)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Insert(&self, key: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Insert)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), core::mem::transmute_copy(value), &mut result__).map(|| result__) + } + } + pub fn Remove(&self, key: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Remove)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key)).ok() } + } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} impl windows_core::RuntimeType for HttpContentHeaderCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -19467,6 +98871,20 @@ pub struct HttpContentRangeHeaderValue(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpContentRangeHeaderValue, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpContentRangeHeaderValue, super::super::super::Foundation::IStringable); impl HttpContentRangeHeaderValue { + pub fn FirstBytePosition(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).FirstBytePosition)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn LastBytePosition(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LastBytePosition)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Length(&self) -> windows_core::Result> { let this = self; unsafe { @@ -19474,6 +98892,54 @@ impl HttpContentRangeHeaderValue { (windows_core::Interface::vtable(this).Length)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Unit(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Unit)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetUnit(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetUnit)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn CreateFromLength(length: u64) -> windows_core::Result { + Self::IHttpContentRangeHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromLength)(windows_core::Interface::as_raw(this), length, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromRange(from: u64, to: u64) -> windows_core::Result { + Self::IHttpContentRangeHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromRange)(windows_core::Interface::as_raw(this), from, to, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromRangeWithLength(from: u64, to: u64, length: u64) -> windows_core::Result { + Self::IHttpContentRangeHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromRangeWithLength)(windows_core::Interface::as_raw(this), from, to, length, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpContentRangeHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, contentrangeheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpContentRangeHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), contentrangeheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpContentRangeHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -19508,6 +98974,48 @@ impl HttpCookiePairHeaderValue { (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetValue(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetValue)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn CreateFromName(name: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpCookiePairHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromName)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromNameWithValue(name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpCookiePairHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromNameWithValue)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), core::mem::transmute_copy(value), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpCookiePairHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, cookiepairheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpCookiePairHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), cookiepairheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpCookiePairHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -19535,6 +99043,17 @@ pub struct HttpCookiePairHeaderValueCollection(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpCookiePairHeaderValueCollection, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpCookiePairHeaderValueCollection, windows_collections::IIterable, super::super::super::Foundation::IStringable, windows_collections::IVector); impl HttpCookiePairHeaderValueCollection { + pub fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input)).ok() } + } + pub fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).map(|| result__) + } + } pub fn First(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::>(self)?; unsafe { @@ -19542,6 +99061,62 @@ impl HttpCookiePairHeaderValueCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn SetAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn InsertAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).InsertAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn RemoveAt(&self, index: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAt)(windows_core::Interface::as_raw(this), index).ok() } + } pub fn Append(&self, value: P0) -> windows_core::Result<()> where P0: windows_core::Param, @@ -19549,7 +99124,26 @@ impl HttpCookiePairHeaderValueCollection { let this = &windows_core::Interface::cast::>(self)?; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } } + pub fn RemoveAtEnd(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAtEnd)(windows_core::Interface::as_raw(this)).ok() } } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } + pub fn ReplaceAll(&self, items: &[Option]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).ReplaceAll)(windows_core::Interface::as_raw(this), items.len().try_into().unwrap(), core::mem::transmute(items.as_ptr())).ok() } + } +} impl windows_core::RuntimeType for HttpCookiePairHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -19582,6 +99176,58 @@ pub struct HttpCredentialsHeaderValue(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpCredentialsHeaderValue, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpCredentialsHeaderValue, super::super::super::Foundation::IStringable); impl HttpCredentialsHeaderValue { + pub fn Parameters(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parameters)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Scheme(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Scheme)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Token(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Token)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn CreateFromScheme(scheme: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpCredentialsHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromScheme)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(scheme), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromSchemeWithToken(scheme: &windows_core::HSTRING, token: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpCredentialsHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromSchemeWithToken)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(scheme), core::mem::transmute_copy(token), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpCredentialsHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, credentialsheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpCredentialsHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), credentialsheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpCredentialsHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -19609,6 +99255,39 @@ pub struct HttpDateOrDeltaHeaderValue(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpDateOrDeltaHeaderValue, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpDateOrDeltaHeaderValue, super::super::super::Foundation::IStringable); impl HttpDateOrDeltaHeaderValue { + pub fn Date(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Date)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Delta(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Delta)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpDateOrDeltaHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, dateordeltaheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpDateOrDeltaHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), dateordeltaheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpDateOrDeltaHeaderValueStatics windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -19639,6 +99318,55 @@ impl HttpExpectationHeaderValue { (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetValue(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetValue)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Parameters(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parameters)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFromName(name: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpExpectationHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromName)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromNameWithValue(name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpExpectationHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromNameWithValue)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), core::mem::transmute_copy(value), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpExpectationHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, expectationheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpExpectationHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), expectationheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpExpectationHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -19666,6 +99394,17 @@ pub struct HttpExpectationHeaderValueCollection(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpExpectationHeaderValueCollection, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpExpectationHeaderValueCollection, windows_collections::IIterable, super::super::super::Foundation::IStringable, windows_collections::IVector); impl HttpExpectationHeaderValueCollection { + pub fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input)).ok() } + } + pub fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).map(|| result__) + } + } pub fn First(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::>(self)?; unsafe { @@ -19673,6 +99412,62 @@ impl HttpExpectationHeaderValueCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn SetAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn InsertAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).InsertAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn RemoveAt(&self, index: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAt)(windows_core::Interface::as_raw(this), index).ok() } + } pub fn Append(&self, value: P0) -> windows_core::Result<()> where P0: windows_core::Param, @@ -19680,7 +99475,26 @@ impl HttpExpectationHeaderValueCollection { let this = &windows_core::Interface::cast::>(self)?; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } } + pub fn RemoveAtEnd(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAtEnd)(windows_core::Interface::as_raw(this)).ok() } } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } + pub fn ReplaceAll(&self, items: &[Option]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).ReplaceAll)(windows_core::Interface::as_raw(this), items.len().try_into().unwrap(), core::mem::transmute(items.as_ptr())).ok() } + } +} impl windows_core::RuntimeType for HttpExpectationHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -19707,12 +99521,201 @@ impl IntoIterator for &HttpExpectationHeaderValueCollection { self.First().unwrap() } } +#[cfg(feature = "Globalization")] +#[repr(transparent)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct HttpLanguageHeaderValueCollection(windows_core::IUnknown); +#[cfg(feature = "Globalization")] +windows_core::imp::interface_hierarchy!(HttpLanguageHeaderValueCollection, windows_core::IUnknown, windows_core::IInspectable); +#[cfg(feature = "Globalization")] +windows_core::imp::required_hierarchy!(HttpLanguageHeaderValueCollection, windows_collections::IIterable, super::super::super::Foundation::IStringable, windows_collections::IVector); +#[cfg(feature = "Globalization")] +impl HttpLanguageHeaderValueCollection { + pub fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input)).ok() } + } + pub fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).map(|| result__) + } + } + pub fn First(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn SetAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn InsertAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).InsertAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn RemoveAt(&self, index: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAt)(windows_core::Interface::as_raw(this), index).ok() } + } + pub fn Append(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn RemoveAtEnd(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAtEnd)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } + pub fn ReplaceAll(&self, items: &[Option]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).ReplaceAll)(windows_core::Interface::as_raw(this), items.len().try_into().unwrap(), core::mem::transmute(items.as_ptr())).ok() } + } +} +#[cfg(feature = "Globalization")] +impl windows_core::RuntimeType for HttpLanguageHeaderValueCollection { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); +} +#[cfg(feature = "Globalization")] +unsafe impl windows_core::Interface for HttpLanguageHeaderValueCollection { + type Vtable = ::Vtable; + const IID: windows_core::GUID = ::IID; +} +#[cfg(feature = "Globalization")] +impl windows_core::RuntimeName for HttpLanguageHeaderValueCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.HttpLanguageHeaderValueCollection"; +} +#[cfg(feature = "Globalization")] +unsafe impl Send for HttpLanguageHeaderValueCollection {} +#[cfg(feature = "Globalization")] +unsafe impl Sync for HttpLanguageHeaderValueCollection {} +#[cfg(feature = "Globalization")] +impl IntoIterator for HttpLanguageHeaderValueCollection { + type Item = super::super::super::Globalization::Language; + type IntoIter = windows_collections::IIterator; + fn into_iter(self) -> Self::IntoIter { + IntoIterator::into_iter(&self) + } +} +#[cfg(feature = "Globalization")] +impl IntoIterator for &HttpLanguageHeaderValueCollection { + type Item = super::super::super::Globalization::Language; + type IntoIter = windows_collections::IIterator; + fn into_iter(self) -> Self::IntoIter { + self.First().unwrap() + } +} #[repr(transparent)] #[derive(Clone, Debug, Eq, PartialEq)] pub struct HttpLanguageRangeWithQualityHeaderValue(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpLanguageRangeWithQualityHeaderValue, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpLanguageRangeWithQualityHeaderValue, super::super::super::Foundation::IStringable); impl HttpLanguageRangeWithQualityHeaderValue { + pub fn LanguageRange(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).LanguageRange)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn Quality(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Quality)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CreateFromLanguageRange(languagerange: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpLanguageRangeWithQualityHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromLanguageRange)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(languagerange), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromLanguageRangeWithQuality(languagerange: &windows_core::HSTRING, quality: f64) -> windows_core::Result { + Self::IHttpLanguageRangeWithQualityHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromLanguageRangeWithQuality)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(languagerange), quality, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpLanguageRangeWithQualityHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, languagerangewithqualityheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpLanguageRangeWithQualityHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), languagerangewithqualityheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpLanguageRangeWithQualityHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -19740,6 +99743,17 @@ pub struct HttpLanguageRangeWithQualityHeaderValueCollection(windows_core::IUnkn windows_core::imp::interface_hierarchy!(HttpLanguageRangeWithQualityHeaderValueCollection, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpLanguageRangeWithQualityHeaderValueCollection, windows_collections::IIterable, super::super::super::Foundation::IStringable, windows_collections::IVector); impl HttpLanguageRangeWithQualityHeaderValueCollection { + pub fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input)).ok() } + } + pub fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).map(|| result__) + } + } pub fn First(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::>(self)?; unsafe { @@ -19747,6 +99761,62 @@ impl HttpLanguageRangeWithQualityHeaderValueCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn SetAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn InsertAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).InsertAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn RemoveAt(&self, index: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAt)(windows_core::Interface::as_raw(this), index).ok() } + } pub fn Append(&self, value: P0) -> windows_core::Result<()> where P0: windows_core::Param, @@ -19754,7 +99824,26 @@ impl HttpLanguageRangeWithQualityHeaderValueCollection { let this = &windows_core::Interface::cast::>(self)?; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } } + pub fn RemoveAtEnd(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAtEnd)(windows_core::Interface::as_raw(this)).ok() } } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } + pub fn ReplaceAll(&self, items: &[Option]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).ReplaceAll)(windows_core::Interface::as_raw(this), items.len().try_into().unwrap(), core::mem::transmute(items.as_ptr())).ok() } + } +} impl windows_core::RuntimeType for HttpLanguageRangeWithQualityHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -19787,12 +99876,60 @@ pub struct HttpMediaTypeHeaderValue(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpMediaTypeHeaderValue, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpMediaTypeHeaderValue, super::super::super::Foundation::IStringable); impl HttpMediaTypeHeaderValue { + pub fn CharSet(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CharSet)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetCharSet(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetCharSet)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn MediaType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MediaType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetMediaType(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMediaType)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Parameters(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parameters)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Create(mediatype: &windows_core::HSTRING) -> windows_core::Result { Self::IHttpMediaTypeHeaderValueFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(mediatype), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpMediaTypeHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, mediatypeheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpMediaTypeHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), mediatypeheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpMediaTypeHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -19820,6 +99957,80 @@ pub struct HttpMediaTypeWithQualityHeaderValue(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpMediaTypeWithQualityHeaderValue, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpMediaTypeWithQualityHeaderValue, super::super::super::Foundation::IStringable); impl HttpMediaTypeWithQualityHeaderValue { + pub fn CharSet(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CharSet)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetCharSet(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetCharSet)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn MediaType(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MediaType)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetMediaType(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMediaType)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn Parameters(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parameters)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Quality(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Quality)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetQuality(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetQuality)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn CreateFromMediaType(mediatype: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpMediaTypeWithQualityHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromMediaType)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(mediatype), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromMediaTypeWithQuality(mediatype: &windows_core::HSTRING, quality: f64) -> windows_core::Result { + Self::IHttpMediaTypeWithQualityHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromMediaTypeWithQuality)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(mediatype), quality, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpMediaTypeWithQualityHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, mediatypewithqualityheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpMediaTypeWithQualityHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), mediatypewithqualityheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpMediaTypeWithQualityHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -19847,6 +100058,17 @@ pub struct HttpMediaTypeWithQualityHeaderValueCollection(windows_core::IUnknown) windows_core::imp::interface_hierarchy!(HttpMediaTypeWithQualityHeaderValueCollection, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpMediaTypeWithQualityHeaderValueCollection, windows_collections::IIterable, super::super::super::Foundation::IStringable, windows_collections::IVector); impl HttpMediaTypeWithQualityHeaderValueCollection { + pub fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input)).ok() } + } + pub fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).map(|| result__) + } + } pub fn First(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::>(self)?; unsafe { @@ -19854,6 +100076,62 @@ impl HttpMediaTypeWithQualityHeaderValueCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn SetAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn InsertAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).InsertAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn RemoveAt(&self, index: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAt)(windows_core::Interface::as_raw(this), index).ok() } + } pub fn Append(&self, value: P0) -> windows_core::Result<()> where P0: windows_core::Param, @@ -19861,7 +100139,26 @@ impl HttpMediaTypeWithQualityHeaderValueCollection { let this = &windows_core::Interface::cast::>(self)?; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } } + pub fn RemoveAtEnd(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAtEnd)(windows_core::Interface::as_raw(this)).ok() } } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } + pub fn ReplaceAll(&self, items: &[Option]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).ReplaceAll)(windows_core::Interface::as_raw(this), items.len().try_into().unwrap(), core::mem::transmute(items.as_ptr())).ok() } + } +} impl windows_core::RuntimeType for HttpMediaTypeWithQualityHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -19894,6 +100191,17 @@ pub struct HttpMethodHeaderValueCollection(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpMethodHeaderValueCollection, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpMethodHeaderValueCollection, windows_collections::IIterable, super::super::super::Foundation::IStringable, windows_collections::IVector); impl HttpMethodHeaderValueCollection { + pub fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input)).ok() } + } + pub fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).map(|| result__) + } + } pub fn First(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::>(self)?; unsafe { @@ -19901,6 +100209,62 @@ impl HttpMethodHeaderValueCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn SetAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn InsertAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).InsertAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn RemoveAt(&self, index: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAt)(windows_core::Interface::as_raw(this), index).ok() } + } pub fn Append(&self, value: P0) -> windows_core::Result<()> where P0: windows_core::Param, @@ -19908,7 +100272,26 @@ impl HttpMethodHeaderValueCollection { let this = &windows_core::Interface::cast::>(self)?; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } } + pub fn RemoveAtEnd(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAtEnd)(windows_core::Interface::as_raw(this)).ok() } } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } + pub fn ReplaceAll(&self, items: &[Option]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).ReplaceAll)(windows_core::Interface::as_raw(this), items.len().try_into().unwrap(), core::mem::transmute(items.as_ptr())).ok() } + } +} impl windows_core::RuntimeType for HttpMethodHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -19948,6 +100331,48 @@ impl HttpNameValueHeaderValue { (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn SetValue(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetValue)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + pub fn CreateFromName(name: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpNameValueHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromName)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromNameWithValue(name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpNameValueHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromNameWithValue)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), core::mem::transmute_copy(value), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpNameValueHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, namevalueheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpNameValueHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), namevalueheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpNameValueHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -19982,6 +100407,44 @@ impl HttpProductHeaderValue { (windows_core::Interface::vtable(this).Name)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn Version(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Version)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn CreateFromName(productname: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpProductHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromName)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(productname), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromNameWithVersion(productname: &windows_core::HSTRING, productversion: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpProductHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromNameWithVersion)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(productname), core::mem::transmute_copy(productversion), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpProductHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, productheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpProductHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), productheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpProductHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -20009,6 +100472,51 @@ pub struct HttpProductInfoHeaderValue(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpProductInfoHeaderValue, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpProductInfoHeaderValue, super::super::super::Foundation::IStringable); impl HttpProductInfoHeaderValue { + pub fn Product(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Product)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Comment(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Comment)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn CreateFromComment(productcomment: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpProductInfoHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromComment)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(productcomment), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn CreateFromNameWithVersion(productname: &windows_core::HSTRING, productversion: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpProductInfoHeaderValueFactory(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CreateFromNameWithVersion)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(productname), core::mem::transmute_copy(productversion), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpProductInfoHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, productinfoheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpProductInfoHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), productinfoheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpProductInfoHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -20036,6 +100544,17 @@ pub struct HttpProductInfoHeaderValueCollection(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpProductInfoHeaderValueCollection, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpProductInfoHeaderValueCollection, windows_collections::IIterable, super::super::super::Foundation::IStringable, windows_collections::IVector); impl HttpProductInfoHeaderValueCollection { + pub fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input)).ok() } + } + pub fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).map(|| result__) + } + } pub fn First(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::>(self)?; unsafe { @@ -20043,6 +100562,62 @@ impl HttpProductInfoHeaderValueCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn SetAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn InsertAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).InsertAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn RemoveAt(&self, index: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAt)(windows_core::Interface::as_raw(this), index).ok() } + } pub fn Append(&self, value: P0) -> windows_core::Result<()> where P0: windows_core::Param, @@ -20050,7 +100625,26 @@ impl HttpProductInfoHeaderValueCollection { let this = &windows_core::Interface::cast::>(self)?; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } } + pub fn RemoveAtEnd(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAtEnd)(windows_core::Interface::as_raw(this)).ok() } } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } + pub fn ReplaceAll(&self, items: &[Option]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).ReplaceAll)(windows_core::Interface::as_raw(this), items.len().try_into().unwrap(), core::mem::transmute(items.as_ptr())).ok() } + } +} impl windows_core::RuntimeType for HttpProductInfoHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -20083,6 +100677,83 @@ pub struct HttpRequestHeaderCollection(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpRequestHeaderCollection, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy ! ( HttpRequestHeaderCollection , windows_collections:: IIterable < windows_collections:: IKeyValuePair < windows_core::HSTRING , windows_core::HSTRING > > , windows_collections:: IMap < windows_core::HSTRING , windows_core::HSTRING > , super::super::super::Foundation:: IStringable ); impl HttpRequestHeaderCollection { + pub fn Accept(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Accept)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn AcceptEncoding(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AcceptEncoding)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn AcceptLanguage(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).AcceptLanguage)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Authorization(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Authorization)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetAuthorization(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAuthorization)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn CacheControl(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CacheControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Connection(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Connection)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Cookie(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Cookie)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Date(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Date)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetDate(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDate)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn Expect(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Expect)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn From(&self) -> windows_core::Result { let this = self; unsafe { @@ -20090,10 +100761,121 @@ impl HttpRequestHeaderCollection { (windows_core::Interface::vtable(this).From)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) } } + pub fn SetFrom(&self, value: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetFrom)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(value)).ok() } + } + #[cfg(feature = "Networking")] + pub fn Host(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Host)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Networking")] + pub fn SetHost(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetHost)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn IfModifiedSince(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IfModifiedSince)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetIfModifiedSince(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetIfModifiedSince)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn IfUnmodifiedSince(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IfUnmodifiedSince)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetIfUnmodifiedSince(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetIfUnmodifiedSince)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn MaxForwards(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).MaxForwards)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetMaxForwards(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetMaxForwards)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn ProxyAuthorization(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProxyAuthorization)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetProxyAuthorization(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetProxyAuthorization)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn Referer(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Referer)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetReferer(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetReferer)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn TransferEncoding(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TransferEncoding)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn UserAgent(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).UserAgent)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Append(&self, name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), core::mem::transmute_copy(value)).ok() } } + pub fn TryAppendWithoutValidation(&self, name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryAppendWithoutValidation)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), core::mem::transmute_copy(value), &mut result__).map(|| result__) + } + } pub fn First(&self) -> windows_core::Result>> { let this = &windows_core::Interface::cast::>>(self)?; unsafe { @@ -20101,7 +100883,57 @@ impl HttpRequestHeaderCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Lookup(&self, key: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Lookup)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), &mut result__).map(|| core::mem::transmute(result__)) + } } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn HasKey(&self, key: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HasKey)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Insert(&self, key: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Insert)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), core::mem::transmute_copy(value), &mut result__).map(|| result__) + } + } + pub fn Remove(&self, key: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Remove)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key)).ok() } + } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} impl windows_core::RuntimeType for HttpRequestHeaderCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -20134,10 +100966,115 @@ pub struct HttpResponseHeaderCollection(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpResponseHeaderCollection, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy ! ( HttpResponseHeaderCollection , windows_collections:: IIterable < windows_collections:: IKeyValuePair < windows_core::HSTRING , windows_core::HSTRING > > , windows_collections:: IMap < windows_core::HSTRING , windows_core::HSTRING > , super::super::super::Foundation:: IStringable ); impl HttpResponseHeaderCollection { + pub fn Age(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Age)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetAge(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetAge)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn Allow(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Allow)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn CacheControl(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).CacheControl)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Connection(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Connection)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Date(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Date)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetDate(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param>, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetDate)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn Location(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Location)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetLocation(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetLocation)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn ProxyAuthenticate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ProxyAuthenticate)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn RetryAfter(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).RetryAfter)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn SetRetryAfter(&self, value: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + let this = self; + unsafe { (windows_core::Interface::vtable(this).SetRetryAfter)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } + } + pub fn TransferEncoding(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TransferEncoding)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn WwwAuthenticate(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).WwwAuthenticate)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub fn Append(&self, name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result<()> { let this = self; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), core::mem::transmute_copy(value)).ok() } } + pub fn TryAppendWithoutValidation(&self, name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryAppendWithoutValidation)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(name), core::mem::transmute_copy(value), &mut result__).map(|| result__) + } + } pub fn First(&self) -> windows_core::Result>> { let this = &windows_core::Interface::cast::>>(self)?; unsafe { @@ -20145,7 +101082,57 @@ impl HttpResponseHeaderCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn Lookup(&self, key: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Lookup)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), &mut result__).map(|| core::mem::transmute(result__)) + } } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn HasKey(&self, key: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).HasKey)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Insert(&self, key: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Insert)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key), core::mem::transmute_copy(value), &mut result__).map(|| result__) + } + } + pub fn Remove(&self, key: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Remove)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(key)).ok() } + } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } +} impl windows_core::RuntimeType for HttpResponseHeaderCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -20178,12 +101165,45 @@ pub struct HttpTransferCodingHeaderValue(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpTransferCodingHeaderValue, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpTransferCodingHeaderValue, super::super::super::Foundation::IStringable); impl HttpTransferCodingHeaderValue { + pub fn Parameters(&self) -> windows_core::Result> { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parameters)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Value(&self) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Value)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } pub fn Create(input: &windows_core::HSTRING) -> windows_core::Result { Self::IHttpTransferCodingHeaderValueFactory(|this| unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(this).Create)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) }) } + pub fn Parse(input: &windows_core::HSTRING) -> windows_core::Result { + Self::IHttpTransferCodingHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Parse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + }) + } + pub fn TryParse(input: &windows_core::HSTRING, transfercodingheadervalue: &mut Option) -> windows_core::Result { + Self::IHttpTransferCodingHeaderValueStatics(|this| unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParse)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), transfercodingheadervalue as *mut _ as _, &mut result__).map(|| result__) + }) + } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } fn IHttpTransferCodingHeaderValueFactory windows_core::Result>(callback: F) -> windows_core::Result { static SHARED: windows_core::imp::FactoryCache = windows_core::imp::FactoryCache::new(); SHARED.call(callback) @@ -20211,6 +101231,17 @@ pub struct HttpTransferCodingHeaderValueCollection(windows_core::IUnknown); windows_core::imp::interface_hierarchy!(HttpTransferCodingHeaderValueCollection, windows_core::IUnknown, windows_core::IInspectable); windows_core::imp::required_hierarchy!(HttpTransferCodingHeaderValueCollection, windows_collections::IIterable, super::super::super::Foundation::IStringable, windows_collections::IVector); impl HttpTransferCodingHeaderValueCollection { + pub fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()> { + let this = self; + unsafe { (windows_core::Interface::vtable(this).ParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input)).ok() } + } + pub fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result { + let this = self; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).TryParseAdd)(windows_core::Interface::as_raw(this), core::mem::transmute_copy(input), &mut result__).map(|| result__) + } + } pub fn First(&self) -> windows_core::Result> { let this = &windows_core::Interface::cast::>(self)?; unsafe { @@ -20218,6 +101249,62 @@ impl HttpTransferCodingHeaderValueCollection { (windows_core::Interface::vtable(this).First)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub fn ToString(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).ToString)(windows_core::Interface::as_raw(this), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub fn GetAt(&self, index: u32) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetAt)(windows_core::Interface::as_raw(this), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn Size(&self) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).Size)(windows_core::Interface::as_raw(this), &mut result__).map(|| result__) + } + } + pub fn GetView(&self) -> windows_core::Result> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetView)(windows_core::Interface::as_raw(this), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub fn IndexOf(&self, value: P0, index: &mut u32) -> windows_core::Result + where + P0: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).IndexOf)(windows_core::Interface::as_raw(this), value.param().abi(), index, &mut result__).map(|| result__) + } + } + pub fn SetAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).SetAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn InsertAt(&self, index: u32, value: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).InsertAt)(windows_core::Interface::as_raw(this), index, value.param().abi()).ok() } + } + pub fn RemoveAt(&self, index: u32) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAt)(windows_core::Interface::as_raw(this), index).ok() } + } pub fn Append(&self, value: P0) -> windows_core::Result<()> where P0: windows_core::Param, @@ -20225,7 +101312,26 @@ impl HttpTransferCodingHeaderValueCollection { let this = &windows_core::Interface::cast::>(self)?; unsafe { (windows_core::Interface::vtable(this).Append)(windows_core::Interface::as_raw(this), value.param().abi()).ok() } } + pub fn RemoveAtEnd(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).RemoveAtEnd)(windows_core::Interface::as_raw(this)).ok() } } + pub fn Clear(&self) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).Clear)(windows_core::Interface::as_raw(this)).ok() } + } + pub fn GetMany(&self, startindex: u32, items: &mut [Option]) -> windows_core::Result { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(this).GetMany)(windows_core::Interface::as_raw(this), startindex, items.len().try_into().unwrap(), core::mem::transmute_copy(&items), &mut result__).map(|| result__) + } + } + pub fn ReplaceAll(&self, items: &[Option]) -> windows_core::Result<()> { + let this = &windows_core::Interface::cast::>(self)?; + unsafe { (windows_core::Interface::vtable(this).ReplaceAll)(windows_core::Interface::as_raw(this), items.len().try_into().unwrap(), core::mem::transmute(items.as_ptr())).ok() } + } +} impl windows_core::RuntimeType for HttpTransferCodingHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_class::(); } @@ -20256,6 +101362,135 @@ windows_core::imp::define_interface!(IHttpCacheDirectiveHeaderValueCollection, I impl windows_core::RuntimeType for IHttpCacheDirectiveHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpCacheDirectiveHeaderValueCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpCacheDirectiveHeaderValueCollection"; +} +pub trait IHttpCacheDirectiveHeaderValueCollection_Impl: windows_core::IUnknownImpl { + fn MaxAge(&self) -> windows_core::Result>; + fn SetMaxAge(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn MaxStale(&self) -> windows_core::Result>; + fn SetMaxStale(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn MinFresh(&self) -> windows_core::Result>; + fn SetMinFresh(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn SharedMaxAge(&self) -> windows_core::Result>; + fn SetSharedMaxAge(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpCacheDirectiveHeaderValueCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn MaxAge(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCacheDirectiveHeaderValueCollection_Impl::MaxAge(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMaxAge(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpCacheDirectiveHeaderValueCollection_Impl::SetMaxAge(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn MaxStale(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCacheDirectiveHeaderValueCollection_Impl::MaxStale(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMaxStale(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpCacheDirectiveHeaderValueCollection_Impl::SetMaxStale(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn MinFresh(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCacheDirectiveHeaderValueCollection_Impl::MinFresh(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMinFresh(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpCacheDirectiveHeaderValueCollection_Impl::SetMinFresh(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn SharedMaxAge(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCacheDirectiveHeaderValueCollection_Impl::SharedMaxAge(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetSharedMaxAge(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpCacheDirectiveHeaderValueCollection_Impl::SetSharedMaxAge(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn ParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpCacheDirectiveHeaderValueCollection_Impl::ParseAdd(this, core::mem::transmute(&input)).into() + } + } + unsafe extern "system" fn TryParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCacheDirectiveHeaderValueCollection_Impl::TryParseAdd(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + MaxAge: MaxAge::, + SetMaxAge: SetMaxAge::, + MaxStale: MaxStale::, + SetMaxStale: SetMaxStale::, + MinFresh: MinFresh::, + SetMinFresh: SetMinFresh::, + SharedMaxAge: SharedMaxAge::, + SetSharedMaxAge: SetSharedMaxAge::, + ParseAdd: ParseAdd::, + TryParseAdd: TryParseAdd::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpCacheDirectiveHeaderValueCollection_Vtbl { @@ -20275,6 +101510,66 @@ windows_core::imp::define_interface!(IHttpChallengeHeaderValue, IHttpChallengeHe impl windows_core::RuntimeType for IHttpChallengeHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpChallengeHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpChallengeHeaderValue"; +} +pub trait IHttpChallengeHeaderValue_Impl: windows_core::IUnknownImpl { + fn Parameters(&self) -> windows_core::Result>; + fn Scheme(&self) -> windows_core::Result; + fn Token(&self) -> windows_core::Result; +} +impl IHttpChallengeHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parameters(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpChallengeHeaderValue_Impl::Parameters(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Scheme(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpChallengeHeaderValue_Impl::Scheme(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Token(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpChallengeHeaderValue_Impl::Token(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parameters: Parameters::, + Scheme: Scheme::, + Token: Token::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpChallengeHeaderValue_Vtbl { @@ -20287,6 +101582,43 @@ windows_core::imp::define_interface!(IHttpChallengeHeaderValueCollection, IHttpC impl windows_core::RuntimeType for IHttpChallengeHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpChallengeHeaderValueCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpChallengeHeaderValueCollection"; +} +pub trait IHttpChallengeHeaderValueCollection_Impl: windows_core::IUnknownImpl { + fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpChallengeHeaderValueCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpChallengeHeaderValueCollection_Impl::ParseAdd(this, core::mem::transmute(&input)).into() + } + } + unsafe extern "system" fn TryParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpChallengeHeaderValueCollection_Impl::TryParseAdd(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ParseAdd: ParseAdd::, + TryParseAdd: TryParseAdd::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpChallengeHeaderValueCollection_Vtbl { @@ -20298,6 +101630,51 @@ windows_core::imp::define_interface!(IHttpChallengeHeaderValueFactory, IHttpChal impl windows_core::RuntimeType for IHttpChallengeHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpChallengeHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpChallengeHeaderValueFactory"; +} +pub trait IHttpChallengeHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn CreateFromScheme(&self, scheme: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromSchemeWithToken(&self, scheme: &windows_core::HSTRING, token: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpChallengeHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromScheme(this: *mut core::ffi::c_void, scheme: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpChallengeHeaderValueFactory_Impl::CreateFromScheme(this, core::mem::transmute(&scheme)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromSchemeWithToken(this: *mut core::ffi::c_void, scheme: *mut core::ffi::c_void, token: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpChallengeHeaderValueFactory_Impl::CreateFromSchemeWithToken(this, core::mem::transmute(&scheme), core::mem::transmute(&token)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromScheme: CreateFromScheme::, + CreateFromSchemeWithToken: CreateFromSchemeWithToken::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpChallengeHeaderValueFactory_Vtbl { @@ -20309,6 +101686,50 @@ windows_core::imp::define_interface!(IHttpChallengeHeaderValueStatics, IHttpChal impl windows_core::RuntimeType for IHttpChallengeHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpChallengeHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpChallengeHeaderValueStatics"; +} +pub trait IHttpChallengeHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, challengeHeaderValue: windows_core::OutRef<'_, HttpChallengeHeaderValue>) -> windows_core::Result; +} +impl IHttpChallengeHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpChallengeHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, challengeheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpChallengeHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&challengeheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpChallengeHeaderValueStatics_Vtbl { @@ -20320,6 +101741,33 @@ windows_core::imp::define_interface!(IHttpConnectionOptionHeaderValue, IHttpConn impl windows_core::RuntimeType for IHttpConnectionOptionHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpConnectionOptionHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpConnectionOptionHeaderValue"; +} +pub trait IHttpConnectionOptionHeaderValue_Impl: windows_core::IUnknownImpl { + fn Token(&self) -> windows_core::Result; +} +impl IHttpConnectionOptionHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Token(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpConnectionOptionHeaderValue_Impl::Token(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Token: Token:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpConnectionOptionHeaderValue_Vtbl { @@ -20330,6 +101778,43 @@ windows_core::imp::define_interface!(IHttpConnectionOptionHeaderValueCollection, impl windows_core::RuntimeType for IHttpConnectionOptionHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpConnectionOptionHeaderValueCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpConnectionOptionHeaderValueCollection"; +} +pub trait IHttpConnectionOptionHeaderValueCollection_Impl: windows_core::IUnknownImpl { + fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpConnectionOptionHeaderValueCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpConnectionOptionHeaderValueCollection_Impl::ParseAdd(this, core::mem::transmute(&input)).into() + } + } + unsafe extern "system" fn TryParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpConnectionOptionHeaderValueCollection_Impl::TryParseAdd(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ParseAdd: ParseAdd::, + TryParseAdd: TryParseAdd::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpConnectionOptionHeaderValueCollection_Vtbl { @@ -20341,6 +101826,33 @@ windows_core::imp::define_interface!(IHttpConnectionOptionHeaderValueFactory, IH impl windows_core::RuntimeType for IHttpConnectionOptionHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpConnectionOptionHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpConnectionOptionHeaderValueFactory"; +} +pub trait IHttpConnectionOptionHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, token: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpConnectionOptionHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, token: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpConnectionOptionHeaderValueFactory_Impl::Create(this, core::mem::transmute(&token)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpConnectionOptionHeaderValueFactory_Vtbl { @@ -20351,6 +101863,50 @@ windows_core::imp::define_interface!(IHttpConnectionOptionHeaderValueStatics, IH impl windows_core::RuntimeType for IHttpConnectionOptionHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpConnectionOptionHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpConnectionOptionHeaderValueStatics"; +} +pub trait IHttpConnectionOptionHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, connectionOptionHeaderValue: windows_core::OutRef<'_, HttpConnectionOptionHeaderValue>) -> windows_core::Result; +} +impl IHttpConnectionOptionHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpConnectionOptionHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, connectionoptionheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpConnectionOptionHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&connectionoptionheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpConnectionOptionHeaderValueStatics_Vtbl { @@ -20362,6 +101918,36 @@ windows_core::imp::define_interface!(IHttpContentCodingHeaderValue, IHttpContent impl windows_core::RuntimeType for IHttpContentCodingHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpContentCodingHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpContentCodingHeaderValue"; +} +pub trait IHttpContentCodingHeaderValue_Impl: windows_core::IUnknownImpl { + fn ContentCoding(&self) -> windows_core::Result; +} +impl IHttpContentCodingHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ContentCoding(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentCodingHeaderValue_Impl::ContentCoding(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ContentCoding: ContentCoding::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpContentCodingHeaderValue_Vtbl { @@ -20372,6 +101958,43 @@ windows_core::imp::define_interface!(IHttpContentCodingHeaderValueCollection, IH impl windows_core::RuntimeType for IHttpContentCodingHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpContentCodingHeaderValueCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpContentCodingHeaderValueCollection"; +} +pub trait IHttpContentCodingHeaderValueCollection_Impl: windows_core::IUnknownImpl { + fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpContentCodingHeaderValueCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentCodingHeaderValueCollection_Impl::ParseAdd(this, core::mem::transmute(&input)).into() + } + } + unsafe extern "system" fn TryParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentCodingHeaderValueCollection_Impl::TryParseAdd(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ParseAdd: ParseAdd::, + TryParseAdd: TryParseAdd::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpContentCodingHeaderValueCollection_Vtbl { @@ -20383,6 +102006,33 @@ windows_core::imp::define_interface!(IHttpContentCodingHeaderValueFactory, IHttp impl windows_core::RuntimeType for IHttpContentCodingHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpContentCodingHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpContentCodingHeaderValueFactory"; +} +pub trait IHttpContentCodingHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, contentCoding: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpContentCodingHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, contentcoding: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentCodingHeaderValueFactory_Impl::Create(this, core::mem::transmute(&contentcoding)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpContentCodingHeaderValueFactory_Vtbl { @@ -20393,6 +102043,50 @@ windows_core::imp::define_interface!(IHttpContentCodingHeaderValueStatics, IHttp impl windows_core::RuntimeType for IHttpContentCodingHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpContentCodingHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpContentCodingHeaderValueStatics"; +} +pub trait IHttpContentCodingHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, contentCodingHeaderValue: windows_core::OutRef<'_, HttpContentCodingHeaderValue>) -> windows_core::Result; +} +impl IHttpContentCodingHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentCodingHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, contentcodingheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentCodingHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&contentcodingheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpContentCodingHeaderValueStatics_Vtbl { @@ -20404,6 +102098,51 @@ windows_core::imp::define_interface!(IHttpContentCodingWithQualityHeaderValue, I impl windows_core::RuntimeType for IHttpContentCodingWithQualityHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpContentCodingWithQualityHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpContentCodingWithQualityHeaderValue"; +} +pub trait IHttpContentCodingWithQualityHeaderValue_Impl: windows_core::IUnknownImpl { + fn ContentCoding(&self) -> windows_core::Result; + fn Quality(&self) -> windows_core::Result>; +} +impl IHttpContentCodingWithQualityHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ContentCoding(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentCodingWithQualityHeaderValue_Impl::ContentCoding(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Quality(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentCodingWithQualityHeaderValue_Impl::Quality(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ContentCoding: ContentCoding::, + Quality: Quality::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpContentCodingWithQualityHeaderValue_Vtbl { @@ -20415,6 +102154,43 @@ windows_core::imp::define_interface!(IHttpContentCodingWithQualityHeaderValueCol impl windows_core::RuntimeType for IHttpContentCodingWithQualityHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpContentCodingWithQualityHeaderValueCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpContentCodingWithQualityHeaderValueCollection"; +} +pub trait IHttpContentCodingWithQualityHeaderValueCollection_Impl: windows_core::IUnknownImpl { + fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpContentCodingWithQualityHeaderValueCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentCodingWithQualityHeaderValueCollection_Impl::ParseAdd(this, core::mem::transmute(&input)).into() + } + } + unsafe extern "system" fn TryParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentCodingWithQualityHeaderValueCollection_Impl::TryParseAdd(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ParseAdd: ParseAdd::, + TryParseAdd: TryParseAdd::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpContentCodingWithQualityHeaderValueCollection_Vtbl { @@ -20426,6 +102202,51 @@ windows_core::imp::define_interface!(IHttpContentCodingWithQualityHeaderValueFac impl windows_core::RuntimeType for IHttpContentCodingWithQualityHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpContentCodingWithQualityHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpContentCodingWithQualityHeaderValueFactory"; +} +pub trait IHttpContentCodingWithQualityHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn CreateFromValue(&self, contentCoding: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromValueWithQuality(&self, contentCoding: &windows_core::HSTRING, quality: f64) -> windows_core::Result; +} +impl IHttpContentCodingWithQualityHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromValue(this: *mut core::ffi::c_void, contentcoding: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentCodingWithQualityHeaderValueFactory_Impl::CreateFromValue(this, core::mem::transmute(&contentcoding)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromValueWithQuality(this: *mut core::ffi::c_void, contentcoding: *mut core::ffi::c_void, quality: f64, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentCodingWithQualityHeaderValueFactory_Impl::CreateFromValueWithQuality(this, core::mem::transmute(&contentcoding), quality) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromValue: CreateFromValue::, + CreateFromValueWithQuality: CreateFromValueWithQuality::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpContentCodingWithQualityHeaderValueFactory_Vtbl { @@ -20437,6 +102258,50 @@ windows_core::imp::define_interface!(IHttpContentCodingWithQualityHeaderValueSta impl windows_core::RuntimeType for IHttpContentCodingWithQualityHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpContentCodingWithQualityHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpContentCodingWithQualityHeaderValueStatics"; +} +pub trait IHttpContentCodingWithQualityHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, contentCodingWithQualityHeaderValue: windows_core::OutRef<'_, HttpContentCodingWithQualityHeaderValue>) -> windows_core::Result; +} +impl IHttpContentCodingWithQualityHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentCodingWithQualityHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, contentcodingwithqualityheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentCodingWithQualityHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&contentcodingwithqualityheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpContentCodingWithQualityHeaderValueStatics_Vtbl { @@ -20448,6 +102313,151 @@ windows_core::imp::define_interface!(IHttpContentDispositionHeaderValue, IHttpCo impl windows_core::RuntimeType for IHttpContentDispositionHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpContentDispositionHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpContentDispositionHeaderValue"; +} +pub trait IHttpContentDispositionHeaderValue_Impl: windows_core::IUnknownImpl { + fn DispositionType(&self) -> windows_core::Result; + fn SetDispositionType(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn FileName(&self) -> windows_core::Result; + fn SetFileName(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn FileNameStar(&self) -> windows_core::Result; + fn SetFileNameStar(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Name(&self) -> windows_core::Result; + fn SetName(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Parameters(&self) -> windows_core::Result>; + fn Size(&self) -> windows_core::Result>; + fn SetSize(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; +} +impl IHttpContentDispositionHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn DispositionType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentDispositionHeaderValue_Impl::DispositionType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDispositionType(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentDispositionHeaderValue_Impl::SetDispositionType(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn FileName(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentDispositionHeaderValue_Impl::FileName(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetFileName(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentDispositionHeaderValue_Impl::SetFileName(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn FileNameStar(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentDispositionHeaderValue_Impl::FileNameStar(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetFileNameStar(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentDispositionHeaderValue_Impl::SetFileNameStar(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Name(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentDispositionHeaderValue_Impl::Name(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetName(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentDispositionHeaderValue_Impl::SetName(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Parameters(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentDispositionHeaderValue_Impl::Parameters(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Size(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentDispositionHeaderValue_Impl::Size(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetSize(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentDispositionHeaderValue_Impl::SetSize(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + DispositionType: DispositionType::, + SetDispositionType: SetDispositionType::, + FileName: FileName::, + SetFileName: SetFileName::, + FileNameStar: FileNameStar::, + SetFileNameStar: SetFileNameStar::, + Name: Name::, + SetName: SetName::, + Parameters: Parameters::, + Size: Size::, + SetSize: SetSize::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpContentDispositionHeaderValue_Vtbl { @@ -20468,6 +102478,36 @@ windows_core::imp::define_interface!(IHttpContentDispositionHeaderValueFactory, impl windows_core::RuntimeType for IHttpContentDispositionHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpContentDispositionHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpContentDispositionHeaderValueFactory"; +} +pub trait IHttpContentDispositionHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, dispositionType: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpContentDispositionHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, dispositiontype: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentDispositionHeaderValueFactory_Impl::Create(this, core::mem::transmute(&dispositiontype)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Create: Create::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpContentDispositionHeaderValueFactory_Vtbl { @@ -20478,6 +102518,50 @@ windows_core::imp::define_interface!(IHttpContentDispositionHeaderValueStatics, impl windows_core::RuntimeType for IHttpContentDispositionHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpContentDispositionHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpContentDispositionHeaderValueStatics"; +} +pub trait IHttpContentDispositionHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, contentDispositionHeaderValue: windows_core::OutRef<'_, HttpContentDispositionHeaderValue>) -> windows_core::Result; +} +impl IHttpContentDispositionHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentDispositionHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, contentdispositionheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentDispositionHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&contentdispositionheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpContentDispositionHeaderValueStatics_Vtbl { @@ -20489,6 +102573,260 @@ windows_core::imp::define_interface!(IHttpContentHeaderCollection, IHttpContentH impl windows_core::RuntimeType for IHttpContentHeaderCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(all(feature = "Globalization", feature = "Storage_Streams"))] +impl windows_core::RuntimeName for IHttpContentHeaderCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpContentHeaderCollection"; +} +#[cfg(all(feature = "Globalization", feature = "Storage_Streams"))] +pub trait IHttpContentHeaderCollection_Impl: windows_core::IUnknownImpl { + fn ContentDisposition(&self) -> windows_core::Result; + fn SetContentDisposition(&self, value: windows_core::Ref<'_, HttpContentDispositionHeaderValue>) -> windows_core::Result<()>; + fn ContentEncoding(&self) -> windows_core::Result; + fn ContentLanguage(&self) -> windows_core::Result; + fn ContentLength(&self) -> windows_core::Result>; + fn SetContentLength(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn ContentLocation(&self) -> windows_core::Result; + fn SetContentLocation(&self, value: windows_core::Ref<'_, super::super::super::Foundation::Uri>) -> windows_core::Result<()>; + fn ContentMD5(&self) -> windows_core::Result; + fn SetContentMD5(&self, value: windows_core::Ref<'_, super::super::super::Storage::Streams::IBuffer>) -> windows_core::Result<()>; + fn ContentRange(&self) -> windows_core::Result; + fn SetContentRange(&self, value: windows_core::Ref<'_, HttpContentRangeHeaderValue>) -> windows_core::Result<()>; + fn ContentType(&self) -> windows_core::Result; + fn SetContentType(&self, value: windows_core::Ref<'_, HttpMediaTypeHeaderValue>) -> windows_core::Result<()>; + fn Expires(&self) -> windows_core::Result>; + fn SetExpires(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn LastModified(&self) -> windows_core::Result>; + fn SetLastModified(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn Append(&self, name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryAppendWithoutValidation(&self, name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result; +} +#[cfg(all(feature = "Globalization", feature = "Storage_Streams"))] +impl IHttpContentHeaderCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ContentDisposition(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentHeaderCollection_Impl::ContentDisposition(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetContentDisposition(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentHeaderCollection_Impl::SetContentDisposition(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn ContentEncoding(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentHeaderCollection_Impl::ContentEncoding(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ContentLanguage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentHeaderCollection_Impl::ContentLanguage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn ContentLength(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentHeaderCollection_Impl::ContentLength(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetContentLength(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentHeaderCollection_Impl::SetContentLength(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn ContentLocation(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentHeaderCollection_Impl::ContentLocation(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetContentLocation(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentHeaderCollection_Impl::SetContentLocation(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn ContentMD5(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentHeaderCollection_Impl::ContentMD5(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetContentMD5(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentHeaderCollection_Impl::SetContentMD5(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn ContentRange(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentHeaderCollection_Impl::ContentRange(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetContentRange(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentHeaderCollection_Impl::SetContentRange(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn ContentType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentHeaderCollection_Impl::ContentType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetContentType(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentHeaderCollection_Impl::SetContentType(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Expires(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentHeaderCollection_Impl::Expires(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetExpires(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentHeaderCollection_Impl::SetExpires(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn LastModified(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentHeaderCollection_Impl::LastModified(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetLastModified(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentHeaderCollection_Impl::SetLastModified(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Append(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentHeaderCollection_Impl::Append(this, core::mem::transmute(&name), core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn TryAppendWithoutValidation(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentHeaderCollection_Impl::TryAppendWithoutValidation(this, core::mem::transmute(&name), core::mem::transmute(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ContentDisposition: ContentDisposition::, + SetContentDisposition: SetContentDisposition::, + ContentEncoding: ContentEncoding::, + ContentLanguage: ContentLanguage::, + ContentLength: ContentLength::, + SetContentLength: SetContentLength::, + ContentLocation: ContentLocation::, + SetContentLocation: SetContentLocation::, + ContentMD5: ContentMD5::, + SetContentMD5: SetContentMD5::, + ContentRange: ContentRange::, + SetContentRange: SetContentRange::, + ContentType: ContentType::, + SetContentType: SetContentType::, + Expires: Expires::, + SetExpires: SetExpires::, + LastModified: LastModified::, + SetLastModified: SetLastModified::, + Append: Append::, + TryAppendWithoutValidation: TryAppendWithoutValidation::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpContentHeaderCollection_Vtbl { @@ -20527,6 +102865,89 @@ windows_core::imp::define_interface!(IHttpContentRangeHeaderValue, IHttpContentR impl windows_core::RuntimeType for IHttpContentRangeHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpContentRangeHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpContentRangeHeaderValue"; +} +pub trait IHttpContentRangeHeaderValue_Impl: windows_core::IUnknownImpl { + fn FirstBytePosition(&self) -> windows_core::Result>; + fn LastBytePosition(&self) -> windows_core::Result>; + fn Length(&self) -> windows_core::Result>; + fn Unit(&self) -> windows_core::Result; + fn SetUnit(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; +} +impl IHttpContentRangeHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn FirstBytePosition(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentRangeHeaderValue_Impl::FirstBytePosition(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn LastBytePosition(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentRangeHeaderValue_Impl::LastBytePosition(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Length(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentRangeHeaderValue_Impl::Length(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Unit(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentRangeHeaderValue_Impl::Unit(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetUnit(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpContentRangeHeaderValue_Impl::SetUnit(this, core::mem::transmute(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + FirstBytePosition: FirstBytePosition::, + LastBytePosition: LastBytePosition::, + Length: Length::, + Unit: Unit::, + SetUnit: SetUnit::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpContentRangeHeaderValue_Vtbl { @@ -20541,6 +102962,66 @@ windows_core::imp::define_interface!(IHttpContentRangeHeaderValueFactory, IHttpC impl windows_core::RuntimeType for IHttpContentRangeHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpContentRangeHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpContentRangeHeaderValueFactory"; +} +pub trait IHttpContentRangeHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn CreateFromLength(&self, length: u64) -> windows_core::Result; + fn CreateFromRange(&self, from: u64, to: u64) -> windows_core::Result; + fn CreateFromRangeWithLength(&self, from: u64, to: u64, length: u64) -> windows_core::Result; +} +impl IHttpContentRangeHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromLength(this: *mut core::ffi::c_void, length: u64, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentRangeHeaderValueFactory_Impl::CreateFromLength(this, length) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromRange(this: *mut core::ffi::c_void, from: u64, to: u64, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentRangeHeaderValueFactory_Impl::CreateFromRange(this, from, to) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromRangeWithLength(this: *mut core::ffi::c_void, from: u64, to: u64, length: u64, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentRangeHeaderValueFactory_Impl::CreateFromRangeWithLength(this, from, to, length) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromLength: CreateFromLength::, + CreateFromRange: CreateFromRange::, + CreateFromRangeWithLength: CreateFromRangeWithLength::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpContentRangeHeaderValueFactory_Vtbl { @@ -20553,6 +103034,50 @@ windows_core::imp::define_interface!(IHttpContentRangeHeaderValueStatics, IHttpC impl windows_core::RuntimeType for IHttpContentRangeHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpContentRangeHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpContentRangeHeaderValueStatics"; +} +pub trait IHttpContentRangeHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, contentRangeHeaderValue: windows_core::OutRef<'_, HttpContentRangeHeaderValue>) -> windows_core::Result; +} +impl IHttpContentRangeHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentRangeHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, contentrangeheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpContentRangeHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&contentrangeheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpContentRangeHeaderValueStatics_Vtbl { @@ -20564,6 +103089,59 @@ windows_core::imp::define_interface!(IHttpCookiePairHeaderValue, IHttpCookiePair impl windows_core::RuntimeType for IHttpCookiePairHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpCookiePairHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpCookiePairHeaderValue"; +} +pub trait IHttpCookiePairHeaderValue_Impl: windows_core::IUnknownImpl { + fn Name(&self) -> windows_core::Result; + fn Value(&self) -> windows_core::Result; + fn SetValue(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; +} +impl IHttpCookiePairHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Name(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCookiePairHeaderValue_Impl::Name(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCookiePairHeaderValue_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValue(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpCookiePairHeaderValue_Impl::SetValue(this, core::mem::transmute(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Name: Name::, + Value: Value::, + SetValue: SetValue::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpCookiePairHeaderValue_Vtbl { @@ -20576,6 +103154,43 @@ windows_core::imp::define_interface!(IHttpCookiePairHeaderValueCollection, IHttp impl windows_core::RuntimeType for IHttpCookiePairHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpCookiePairHeaderValueCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpCookiePairHeaderValueCollection"; +} +pub trait IHttpCookiePairHeaderValueCollection_Impl: windows_core::IUnknownImpl { + fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpCookiePairHeaderValueCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpCookiePairHeaderValueCollection_Impl::ParseAdd(this, core::mem::transmute(&input)).into() + } + } + unsafe extern "system" fn TryParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCookiePairHeaderValueCollection_Impl::TryParseAdd(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ParseAdd: ParseAdd::, + TryParseAdd: TryParseAdd::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpCookiePairHeaderValueCollection_Vtbl { @@ -20587,6 +103202,51 @@ windows_core::imp::define_interface!(IHttpCookiePairHeaderValueFactory, IHttpCoo impl windows_core::RuntimeType for IHttpCookiePairHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpCookiePairHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpCookiePairHeaderValueFactory"; +} +pub trait IHttpCookiePairHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn CreateFromName(&self, name: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromNameWithValue(&self, name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpCookiePairHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromName(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCookiePairHeaderValueFactory_Impl::CreateFromName(this, core::mem::transmute(&name)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromNameWithValue(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCookiePairHeaderValueFactory_Impl::CreateFromNameWithValue(this, core::mem::transmute(&name), core::mem::transmute(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromName: CreateFromName::, + CreateFromNameWithValue: CreateFromNameWithValue::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpCookiePairHeaderValueFactory_Vtbl { @@ -20598,6 +103258,50 @@ windows_core::imp::define_interface!(IHttpCookiePairHeaderValueStatics, IHttpCoo impl windows_core::RuntimeType for IHttpCookiePairHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpCookiePairHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpCookiePairHeaderValueStatics"; +} +pub trait IHttpCookiePairHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, cookiePairHeaderValue: windows_core::OutRef<'_, HttpCookiePairHeaderValue>) -> windows_core::Result; +} +impl IHttpCookiePairHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCookiePairHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, cookiepairheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCookiePairHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&cookiepairheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpCookiePairHeaderValueStatics_Vtbl { @@ -20609,6 +103313,66 @@ windows_core::imp::define_interface!(IHttpCredentialsHeaderValue, IHttpCredentia impl windows_core::RuntimeType for IHttpCredentialsHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpCredentialsHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpCredentialsHeaderValue"; +} +pub trait IHttpCredentialsHeaderValue_Impl: windows_core::IUnknownImpl { + fn Parameters(&self) -> windows_core::Result>; + fn Scheme(&self) -> windows_core::Result; + fn Token(&self) -> windows_core::Result; +} +impl IHttpCredentialsHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parameters(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCredentialsHeaderValue_Impl::Parameters(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Scheme(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCredentialsHeaderValue_Impl::Scheme(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Token(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCredentialsHeaderValue_Impl::Token(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parameters: Parameters::, + Scheme: Scheme::, + Token: Token::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpCredentialsHeaderValue_Vtbl { @@ -20621,6 +103385,51 @@ windows_core::imp::define_interface!(IHttpCredentialsHeaderValueFactory, IHttpCr impl windows_core::RuntimeType for IHttpCredentialsHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpCredentialsHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpCredentialsHeaderValueFactory"; +} +pub trait IHttpCredentialsHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn CreateFromScheme(&self, scheme: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromSchemeWithToken(&self, scheme: &windows_core::HSTRING, token: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpCredentialsHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromScheme(this: *mut core::ffi::c_void, scheme: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCredentialsHeaderValueFactory_Impl::CreateFromScheme(this, core::mem::transmute(&scheme)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromSchemeWithToken(this: *mut core::ffi::c_void, scheme: *mut core::ffi::c_void, token: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCredentialsHeaderValueFactory_Impl::CreateFromSchemeWithToken(this, core::mem::transmute(&scheme), core::mem::transmute(&token)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromScheme: CreateFromScheme::, + CreateFromSchemeWithToken: CreateFromSchemeWithToken::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpCredentialsHeaderValueFactory_Vtbl { @@ -20632,6 +103441,50 @@ windows_core::imp::define_interface!(IHttpCredentialsHeaderValueStatics, IHttpCr impl windows_core::RuntimeType for IHttpCredentialsHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpCredentialsHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpCredentialsHeaderValueStatics"; +} +pub trait IHttpCredentialsHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, credentialsHeaderValue: windows_core::OutRef<'_, HttpCredentialsHeaderValue>) -> windows_core::Result; +} +impl IHttpCredentialsHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCredentialsHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, credentialsheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpCredentialsHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&credentialsheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpCredentialsHeaderValueStatics_Vtbl { @@ -20643,6 +103496,51 @@ windows_core::imp::define_interface!(IHttpDateOrDeltaHeaderValue, IHttpDateOrDel impl windows_core::RuntimeType for IHttpDateOrDeltaHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpDateOrDeltaHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpDateOrDeltaHeaderValue"; +} +pub trait IHttpDateOrDeltaHeaderValue_Impl: windows_core::IUnknownImpl { + fn Date(&self) -> windows_core::Result>; + fn Delta(&self) -> windows_core::Result>; +} +impl IHttpDateOrDeltaHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Date(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpDateOrDeltaHeaderValue_Impl::Date(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Delta(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpDateOrDeltaHeaderValue_Impl::Delta(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Date: Date::, + Delta: Delta::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpDateOrDeltaHeaderValue_Vtbl { @@ -20654,6 +103552,50 @@ windows_core::imp::define_interface!(IHttpDateOrDeltaHeaderValueStatics, IHttpDa impl windows_core::RuntimeType for IHttpDateOrDeltaHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpDateOrDeltaHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpDateOrDeltaHeaderValueStatics"; +} +pub trait IHttpDateOrDeltaHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, dateOrDeltaHeaderValue: windows_core::OutRef<'_, HttpDateOrDeltaHeaderValue>) -> windows_core::Result; +} +impl IHttpDateOrDeltaHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpDateOrDeltaHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, dateordeltaheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpDateOrDeltaHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&dateordeltaheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpDateOrDeltaHeaderValueStatics_Vtbl { @@ -20665,6 +103607,74 @@ windows_core::imp::define_interface!(IHttpExpectationHeaderValue, IHttpExpectati impl windows_core::RuntimeType for IHttpExpectationHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpExpectationHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpExpectationHeaderValue"; +} +pub trait IHttpExpectationHeaderValue_Impl: windows_core::IUnknownImpl { + fn Name(&self) -> windows_core::Result; + fn Value(&self) -> windows_core::Result; + fn SetValue(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Parameters(&self) -> windows_core::Result>; +} +impl IHttpExpectationHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Name(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpExpectationHeaderValue_Impl::Name(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpExpectationHeaderValue_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValue(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpExpectationHeaderValue_Impl::SetValue(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Parameters(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpExpectationHeaderValue_Impl::Parameters(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Name: Name::, + Value: Value::, + SetValue: SetValue::, + Parameters: Parameters::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpExpectationHeaderValue_Vtbl { @@ -20678,6 +103688,43 @@ windows_core::imp::define_interface!(IHttpExpectationHeaderValueCollection, IHtt impl windows_core::RuntimeType for IHttpExpectationHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpExpectationHeaderValueCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpExpectationHeaderValueCollection"; +} +pub trait IHttpExpectationHeaderValueCollection_Impl: windows_core::IUnknownImpl { + fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpExpectationHeaderValueCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpExpectationHeaderValueCollection_Impl::ParseAdd(this, core::mem::transmute(&input)).into() + } + } + unsafe extern "system" fn TryParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpExpectationHeaderValueCollection_Impl::TryParseAdd(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ParseAdd: ParseAdd::, + TryParseAdd: TryParseAdd::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpExpectationHeaderValueCollection_Vtbl { @@ -20689,6 +103736,51 @@ windows_core::imp::define_interface!(IHttpExpectationHeaderValueFactory, IHttpEx impl windows_core::RuntimeType for IHttpExpectationHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpExpectationHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpExpectationHeaderValueFactory"; +} +pub trait IHttpExpectationHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn CreateFromName(&self, name: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromNameWithValue(&self, name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpExpectationHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromName(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpExpectationHeaderValueFactory_Impl::CreateFromName(this, core::mem::transmute(&name)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromNameWithValue(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpExpectationHeaderValueFactory_Impl::CreateFromNameWithValue(this, core::mem::transmute(&name), core::mem::transmute(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromName: CreateFromName::, + CreateFromNameWithValue: CreateFromNameWithValue::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpExpectationHeaderValueFactory_Vtbl { @@ -20700,6 +103792,50 @@ windows_core::imp::define_interface!(IHttpExpectationHeaderValueStatics, IHttpEx impl windows_core::RuntimeType for IHttpExpectationHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpExpectationHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpExpectationHeaderValueStatics"; +} +pub trait IHttpExpectationHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, expectationHeaderValue: windows_core::OutRef<'_, HttpExpectationHeaderValue>) -> windows_core::Result; +} +impl IHttpExpectationHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpExpectationHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, expectationheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpExpectationHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&expectationheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpExpectationHeaderValueStatics_Vtbl { @@ -20707,10 +103843,103 @@ pub struct IHttpExpectationHeaderValueStatics_Vtbl { pub Parse: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, pub TryParse: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, } +windows_core::imp::define_interface!(IHttpLanguageHeaderValueCollection, IHttpLanguageHeaderValueCollection_Vtbl, 0x9ebd7ca3_8219_44f6_9902_8c56dfd3340c); +impl windows_core::RuntimeType for IHttpLanguageHeaderValueCollection { + const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); +} +impl windows_core::RuntimeName for IHttpLanguageHeaderValueCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpLanguageHeaderValueCollection"; +} +pub trait IHttpLanguageHeaderValueCollection_Impl: windows_core::IUnknownImpl { + fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpLanguageHeaderValueCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpLanguageHeaderValueCollection_Impl::ParseAdd(this, core::mem::transmute(&input)).into() + } + } + unsafe extern "system" fn TryParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpLanguageHeaderValueCollection_Impl::TryParseAdd(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ParseAdd: ParseAdd::, + TryParseAdd: TryParseAdd::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IHttpLanguageHeaderValueCollection_Vtbl { + pub base__: windows_core::IInspectable_Vtbl, + pub ParseAdd: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub TryParseAdd: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut bool) -> windows_core::HRESULT, +} windows_core::imp::define_interface!(IHttpLanguageRangeWithQualityHeaderValue, IHttpLanguageRangeWithQualityHeaderValue_Vtbl, 0x7256e102_0080_4db4_a083_7de7b2e5ba4c); impl windows_core::RuntimeType for IHttpLanguageRangeWithQualityHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpLanguageRangeWithQualityHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpLanguageRangeWithQualityHeaderValue"; +} +pub trait IHttpLanguageRangeWithQualityHeaderValue_Impl: windows_core::IUnknownImpl { + fn LanguageRange(&self) -> windows_core::Result; + fn Quality(&self) -> windows_core::Result>; +} +impl IHttpLanguageRangeWithQualityHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn LanguageRange(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpLanguageRangeWithQualityHeaderValue_Impl::LanguageRange(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Quality(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpLanguageRangeWithQualityHeaderValue_Impl::Quality(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + LanguageRange: LanguageRange::, + Quality: Quality::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpLanguageRangeWithQualityHeaderValue_Vtbl { @@ -20722,6 +103951,43 @@ windows_core::imp::define_interface!(IHttpLanguageRangeWithQualityHeaderValueCol impl windows_core::RuntimeType for IHttpLanguageRangeWithQualityHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpLanguageRangeWithQualityHeaderValueCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpLanguageRangeWithQualityHeaderValueCollection"; +} +pub trait IHttpLanguageRangeWithQualityHeaderValueCollection_Impl: windows_core::IUnknownImpl { + fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpLanguageRangeWithQualityHeaderValueCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpLanguageRangeWithQualityHeaderValueCollection_Impl::ParseAdd(this, core::mem::transmute(&input)).into() + } + } + unsafe extern "system" fn TryParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpLanguageRangeWithQualityHeaderValueCollection_Impl::TryParseAdd(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ParseAdd: ParseAdd::, + TryParseAdd: TryParseAdd::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpLanguageRangeWithQualityHeaderValueCollection_Vtbl { @@ -20733,6 +103999,51 @@ windows_core::imp::define_interface!(IHttpLanguageRangeWithQualityHeaderValueFac impl windows_core::RuntimeType for IHttpLanguageRangeWithQualityHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpLanguageRangeWithQualityHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpLanguageRangeWithQualityHeaderValueFactory"; +} +pub trait IHttpLanguageRangeWithQualityHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn CreateFromLanguageRange(&self, languageRange: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromLanguageRangeWithQuality(&self, languageRange: &windows_core::HSTRING, quality: f64) -> windows_core::Result; +} +impl IHttpLanguageRangeWithQualityHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromLanguageRange(this: *mut core::ffi::c_void, languagerange: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpLanguageRangeWithQualityHeaderValueFactory_Impl::CreateFromLanguageRange(this, core::mem::transmute(&languagerange)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromLanguageRangeWithQuality(this: *mut core::ffi::c_void, languagerange: *mut core::ffi::c_void, quality: f64, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpLanguageRangeWithQualityHeaderValueFactory_Impl::CreateFromLanguageRangeWithQuality(this, core::mem::transmute(&languagerange), quality) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromLanguageRange: CreateFromLanguageRange::, + CreateFromLanguageRangeWithQuality: CreateFromLanguageRangeWithQuality::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpLanguageRangeWithQualityHeaderValueFactory_Vtbl { @@ -20744,6 +104055,50 @@ windows_core::imp::define_interface!(IHttpLanguageRangeWithQualityHeaderValueSta impl windows_core::RuntimeType for IHttpLanguageRangeWithQualityHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpLanguageRangeWithQualityHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpLanguageRangeWithQualityHeaderValueStatics"; +} +pub trait IHttpLanguageRangeWithQualityHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, languageRangeWithQualityHeaderValue: windows_core::OutRef<'_, HttpLanguageRangeWithQualityHeaderValue>) -> windows_core::Result; +} +impl IHttpLanguageRangeWithQualityHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpLanguageRangeWithQualityHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, languagerangewithqualityheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpLanguageRangeWithQualityHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&languagerangewithqualityheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpLanguageRangeWithQualityHeaderValueStatics_Vtbl { @@ -20755,6 +104110,82 @@ windows_core::imp::define_interface!(IHttpMediaTypeHeaderValue, IHttpMediaTypeHe impl windows_core::RuntimeType for IHttpMediaTypeHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpMediaTypeHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpMediaTypeHeaderValue"; +} +pub trait IHttpMediaTypeHeaderValue_Impl: windows_core::IUnknownImpl { + fn CharSet(&self) -> windows_core::Result; + fn SetCharSet(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn MediaType(&self) -> windows_core::Result; + fn SetMediaType(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Parameters(&self) -> windows_core::Result>; +} +impl IHttpMediaTypeHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CharSet(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMediaTypeHeaderValue_Impl::CharSet(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetCharSet(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpMediaTypeHeaderValue_Impl::SetCharSet(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn MediaType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMediaTypeHeaderValue_Impl::MediaType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMediaType(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpMediaTypeHeaderValue_Impl::SetMediaType(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Parameters(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMediaTypeHeaderValue_Impl::Parameters(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CharSet: CharSet::, + SetCharSet: SetCharSet::, + MediaType: MediaType::, + SetMediaType: SetMediaType::, + Parameters: Parameters::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpMediaTypeHeaderValue_Vtbl { @@ -20769,6 +104200,33 @@ windows_core::imp::define_interface!(IHttpMediaTypeHeaderValueFactory, IHttpMedi impl windows_core::RuntimeType for IHttpMediaTypeHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpMediaTypeHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpMediaTypeHeaderValueFactory"; +} +pub trait IHttpMediaTypeHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, mediaType: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpMediaTypeHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, mediatype: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMediaTypeHeaderValueFactory_Impl::Create(this, core::mem::transmute(&mediatype)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpMediaTypeHeaderValueFactory_Vtbl { @@ -20779,6 +104237,50 @@ windows_core::imp::define_interface!(IHttpMediaTypeHeaderValueStatics, IHttpMedi impl windows_core::RuntimeType for IHttpMediaTypeHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpMediaTypeHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpMediaTypeHeaderValueStatics"; +} +pub trait IHttpMediaTypeHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, mediaTypeHeaderValue: windows_core::OutRef<'_, HttpMediaTypeHeaderValue>) -> windows_core::Result; +} +impl IHttpMediaTypeHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMediaTypeHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, mediatypeheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMediaTypeHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&mediatypeheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpMediaTypeHeaderValueStatics_Vtbl { @@ -20790,6 +104292,105 @@ windows_core::imp::define_interface!(IHttpMediaTypeWithQualityHeaderValue, IHttp impl windows_core::RuntimeType for IHttpMediaTypeWithQualityHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpMediaTypeWithQualityHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpMediaTypeWithQualityHeaderValue"; +} +pub trait IHttpMediaTypeWithQualityHeaderValue_Impl: windows_core::IUnknownImpl { + fn CharSet(&self) -> windows_core::Result; + fn SetCharSet(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn MediaType(&self) -> windows_core::Result; + fn SetMediaType(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Parameters(&self) -> windows_core::Result>; + fn Quality(&self) -> windows_core::Result>; + fn SetQuality(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; +} +impl IHttpMediaTypeWithQualityHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CharSet(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMediaTypeWithQualityHeaderValue_Impl::CharSet(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetCharSet(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpMediaTypeWithQualityHeaderValue_Impl::SetCharSet(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn MediaType(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMediaTypeWithQualityHeaderValue_Impl::MediaType(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMediaType(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpMediaTypeWithQualityHeaderValue_Impl::SetMediaType(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Parameters(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMediaTypeWithQualityHeaderValue_Impl::Parameters(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Quality(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMediaTypeWithQualityHeaderValue_Impl::Quality(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetQuality(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpMediaTypeWithQualityHeaderValue_Impl::SetQuality(this, core::mem::transmute_copy(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CharSet: CharSet::, + SetCharSet: SetCharSet::, + MediaType: MediaType::, + SetMediaType: SetMediaType::, + Parameters: Parameters::, + Quality: Quality::, + SetQuality: SetQuality::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpMediaTypeWithQualityHeaderValue_Vtbl { @@ -20806,6 +104407,43 @@ windows_core::imp::define_interface!(IHttpMediaTypeWithQualityHeaderValueCollect impl windows_core::RuntimeType for IHttpMediaTypeWithQualityHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpMediaTypeWithQualityHeaderValueCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpMediaTypeWithQualityHeaderValueCollection"; +} +pub trait IHttpMediaTypeWithQualityHeaderValueCollection_Impl: windows_core::IUnknownImpl { + fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpMediaTypeWithQualityHeaderValueCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpMediaTypeWithQualityHeaderValueCollection_Impl::ParseAdd(this, core::mem::transmute(&input)).into() + } + } + unsafe extern "system" fn TryParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMediaTypeWithQualityHeaderValueCollection_Impl::TryParseAdd(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ParseAdd: ParseAdd::, + TryParseAdd: TryParseAdd::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpMediaTypeWithQualityHeaderValueCollection_Vtbl { @@ -20817,6 +104455,51 @@ windows_core::imp::define_interface!(IHttpMediaTypeWithQualityHeaderValueFactory impl windows_core::RuntimeType for IHttpMediaTypeWithQualityHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpMediaTypeWithQualityHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpMediaTypeWithQualityHeaderValueFactory"; +} +pub trait IHttpMediaTypeWithQualityHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn CreateFromMediaType(&self, mediaType: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromMediaTypeWithQuality(&self, mediaType: &windows_core::HSTRING, quality: f64) -> windows_core::Result; +} +impl IHttpMediaTypeWithQualityHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromMediaType(this: *mut core::ffi::c_void, mediatype: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMediaTypeWithQualityHeaderValueFactory_Impl::CreateFromMediaType(this, core::mem::transmute(&mediatype)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromMediaTypeWithQuality(this: *mut core::ffi::c_void, mediatype: *mut core::ffi::c_void, quality: f64, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMediaTypeWithQualityHeaderValueFactory_Impl::CreateFromMediaTypeWithQuality(this, core::mem::transmute(&mediatype), quality) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromMediaType: CreateFromMediaType::, + CreateFromMediaTypeWithQuality: CreateFromMediaTypeWithQuality::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpMediaTypeWithQualityHeaderValueFactory_Vtbl { @@ -20828,6 +104511,50 @@ windows_core::imp::define_interface!(IHttpMediaTypeWithQualityHeaderValueStatics impl windows_core::RuntimeType for IHttpMediaTypeWithQualityHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpMediaTypeWithQualityHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpMediaTypeWithQualityHeaderValueStatics"; +} +pub trait IHttpMediaTypeWithQualityHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, mediaTypeWithQualityHeaderValue: windows_core::OutRef<'_, HttpMediaTypeWithQualityHeaderValue>) -> windows_core::Result; +} +impl IHttpMediaTypeWithQualityHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMediaTypeWithQualityHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, mediatypewithqualityheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMediaTypeWithQualityHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&mediatypewithqualityheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpMediaTypeWithQualityHeaderValueStatics_Vtbl { @@ -20839,6 +104566,43 @@ windows_core::imp::define_interface!(IHttpMethodHeaderValueCollection, IHttpMeth impl windows_core::RuntimeType for IHttpMethodHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpMethodHeaderValueCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpMethodHeaderValueCollection"; +} +pub trait IHttpMethodHeaderValueCollection_Impl: windows_core::IUnknownImpl { + fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpMethodHeaderValueCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpMethodHeaderValueCollection_Impl::ParseAdd(this, core::mem::transmute(&input)).into() + } + } + unsafe extern "system" fn TryParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpMethodHeaderValueCollection_Impl::TryParseAdd(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ParseAdd: ParseAdd::, + TryParseAdd: TryParseAdd::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpMethodHeaderValueCollection_Vtbl { @@ -20850,6 +104614,59 @@ windows_core::imp::define_interface!(IHttpNameValueHeaderValue, IHttpNameValueHe impl windows_core::RuntimeType for IHttpNameValueHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpNameValueHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpNameValueHeaderValue"; +} +pub trait IHttpNameValueHeaderValue_Impl: windows_core::IUnknownImpl { + fn Name(&self) -> windows_core::Result; + fn Value(&self) -> windows_core::Result; + fn SetValue(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; +} +impl IHttpNameValueHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Name(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpNameValueHeaderValue_Impl::Name(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpNameValueHeaderValue_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValue(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpNameValueHeaderValue_Impl::SetValue(this, core::mem::transmute(&value)).into() + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Name: Name::, + Value: Value::, + SetValue: SetValue::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpNameValueHeaderValue_Vtbl { @@ -20862,6 +104679,51 @@ windows_core::imp::define_interface!(IHttpNameValueHeaderValueFactory, IHttpName impl windows_core::RuntimeType for IHttpNameValueHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpNameValueHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpNameValueHeaderValueFactory"; +} +pub trait IHttpNameValueHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn CreateFromName(&self, name: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromNameWithValue(&self, name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpNameValueHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromName(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpNameValueHeaderValueFactory_Impl::CreateFromName(this, core::mem::transmute(&name)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromNameWithValue(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpNameValueHeaderValueFactory_Impl::CreateFromNameWithValue(this, core::mem::transmute(&name), core::mem::transmute(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromName: CreateFromName::, + CreateFromNameWithValue: CreateFromNameWithValue::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpNameValueHeaderValueFactory_Vtbl { @@ -20873,6 +104735,50 @@ windows_core::imp::define_interface!(IHttpNameValueHeaderValueStatics, IHttpName impl windows_core::RuntimeType for IHttpNameValueHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpNameValueHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpNameValueHeaderValueStatics"; +} +pub trait IHttpNameValueHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, nameValueHeaderValue: windows_core::OutRef<'_, HttpNameValueHeaderValue>) -> windows_core::Result; +} +impl IHttpNameValueHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpNameValueHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, namevalueheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpNameValueHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&namevalueheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpNameValueHeaderValueStatics_Vtbl { @@ -20884,6 +104790,51 @@ windows_core::imp::define_interface!(IHttpProductHeaderValue, IHttpProductHeader impl windows_core::RuntimeType for IHttpProductHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpProductHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpProductHeaderValue"; +} +pub trait IHttpProductHeaderValue_Impl: windows_core::IUnknownImpl { + fn Name(&self) -> windows_core::Result; + fn Version(&self) -> windows_core::Result; +} +impl IHttpProductHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Name(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpProductHeaderValue_Impl::Name(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Version(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpProductHeaderValue_Impl::Version(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Name: Name::, + Version: Version::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpProductHeaderValue_Vtbl { @@ -20895,6 +104846,51 @@ windows_core::imp::define_interface!(IHttpProductHeaderValueFactory, IHttpProduc impl windows_core::RuntimeType for IHttpProductHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpProductHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpProductHeaderValueFactory"; +} +pub trait IHttpProductHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn CreateFromName(&self, productName: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromNameWithVersion(&self, productName: &windows_core::HSTRING, productVersion: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpProductHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromName(this: *mut core::ffi::c_void, productname: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpProductHeaderValueFactory_Impl::CreateFromName(this, core::mem::transmute(&productname)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromNameWithVersion(this: *mut core::ffi::c_void, productname: *mut core::ffi::c_void, productversion: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpProductHeaderValueFactory_Impl::CreateFromNameWithVersion(this, core::mem::transmute(&productname), core::mem::transmute(&productversion)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromName: CreateFromName::, + CreateFromNameWithVersion: CreateFromNameWithVersion::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpProductHeaderValueFactory_Vtbl { @@ -20906,6 +104902,50 @@ windows_core::imp::define_interface!(IHttpProductHeaderValueStatics, IHttpProduc impl windows_core::RuntimeType for IHttpProductHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpProductHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpProductHeaderValueStatics"; +} +pub trait IHttpProductHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, productHeaderValue: windows_core::OutRef<'_, HttpProductHeaderValue>) -> windows_core::Result; +} +impl IHttpProductHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpProductHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, productheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpProductHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&productheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpProductHeaderValueStatics_Vtbl { @@ -20917,6 +104957,51 @@ windows_core::imp::define_interface!(IHttpProductInfoHeaderValue, IHttpProductIn impl windows_core::RuntimeType for IHttpProductInfoHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpProductInfoHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpProductInfoHeaderValue"; +} +pub trait IHttpProductInfoHeaderValue_Impl: windows_core::IUnknownImpl { + fn Product(&self) -> windows_core::Result; + fn Comment(&self) -> windows_core::Result; +} +impl IHttpProductInfoHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Product(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpProductInfoHeaderValue_Impl::Product(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Comment(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpProductInfoHeaderValue_Impl::Comment(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Product: Product::, + Comment: Comment::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpProductInfoHeaderValue_Vtbl { @@ -20928,6 +105013,43 @@ windows_core::imp::define_interface!(IHttpProductInfoHeaderValueCollection, IHtt impl windows_core::RuntimeType for IHttpProductInfoHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpProductInfoHeaderValueCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpProductInfoHeaderValueCollection"; +} +pub trait IHttpProductInfoHeaderValueCollection_Impl: windows_core::IUnknownImpl { + fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpProductInfoHeaderValueCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpProductInfoHeaderValueCollection_Impl::ParseAdd(this, core::mem::transmute(&input)).into() + } + } + unsafe extern "system" fn TryParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpProductInfoHeaderValueCollection_Impl::TryParseAdd(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ParseAdd: ParseAdd::, + TryParseAdd: TryParseAdd::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpProductInfoHeaderValueCollection_Vtbl { @@ -20939,6 +105061,51 @@ windows_core::imp::define_interface!(IHttpProductInfoHeaderValueFactory, IHttpPr impl windows_core::RuntimeType for IHttpProductInfoHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpProductInfoHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpProductInfoHeaderValueFactory"; +} +pub trait IHttpProductInfoHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn CreateFromComment(&self, productComment: &windows_core::HSTRING) -> windows_core::Result; + fn CreateFromNameWithVersion(&self, productName: &windows_core::HSTRING, productVersion: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpProductInfoHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn CreateFromComment(this: *mut core::ffi::c_void, productcomment: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpProductInfoHeaderValueFactory_Impl::CreateFromComment(this, core::mem::transmute(&productcomment)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateFromNameWithVersion(this: *mut core::ffi::c_void, productname: *mut core::ffi::c_void, productversion: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpProductInfoHeaderValueFactory_Impl::CreateFromNameWithVersion(this, core::mem::transmute(&productname), core::mem::transmute(&productversion)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + CreateFromComment: CreateFromComment::, + CreateFromNameWithVersion: CreateFromNameWithVersion::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpProductInfoHeaderValueFactory_Vtbl { @@ -20950,6 +105117,50 @@ windows_core::imp::define_interface!(IHttpProductInfoHeaderValueStatics, IHttpPr impl windows_core::RuntimeType for IHttpProductInfoHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpProductInfoHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpProductInfoHeaderValueStatics"; +} +pub trait IHttpProductInfoHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, productInfoHeaderValue: windows_core::OutRef<'_, HttpProductInfoHeaderValue>) -> windows_core::Result; +} +impl IHttpProductInfoHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpProductInfoHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, productinfoheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpProductInfoHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&productinfoheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpProductInfoHeaderValueStatics_Vtbl { @@ -20961,6 +105172,388 @@ windows_core::imp::define_interface!(IHttpRequestHeaderCollection, IHttpRequestH impl windows_core::RuntimeType for IHttpRequestHeaderCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +#[cfg(feature = "Networking")] +impl windows_core::RuntimeName for IHttpRequestHeaderCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpRequestHeaderCollection"; +} +#[cfg(feature = "Networking")] +pub trait IHttpRequestHeaderCollection_Impl: windows_core::IUnknownImpl { + fn Accept(&self) -> windows_core::Result; + fn AcceptEncoding(&self) -> windows_core::Result; + fn AcceptLanguage(&self) -> windows_core::Result; + fn Authorization(&self) -> windows_core::Result; + fn SetAuthorization(&self, value: windows_core::Ref<'_, HttpCredentialsHeaderValue>) -> windows_core::Result<()>; + fn CacheControl(&self) -> windows_core::Result; + fn Connection(&self) -> windows_core::Result; + fn Cookie(&self) -> windows_core::Result; + fn Date(&self) -> windows_core::Result>; + fn SetDate(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn Expect(&self) -> windows_core::Result; + fn From(&self) -> windows_core::Result; + fn SetFrom(&self, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn Host(&self) -> windows_core::Result; + fn SetHost(&self, value: windows_core::Ref<'_, super::super::super::Networking::HostName>) -> windows_core::Result<()>; + fn IfModifiedSince(&self) -> windows_core::Result>; + fn SetIfModifiedSince(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn IfUnmodifiedSince(&self) -> windows_core::Result>; + fn SetIfUnmodifiedSince(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn MaxForwards(&self) -> windows_core::Result>; + fn SetMaxForwards(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn ProxyAuthorization(&self) -> windows_core::Result; + fn SetProxyAuthorization(&self, value: windows_core::Ref<'_, HttpCredentialsHeaderValue>) -> windows_core::Result<()>; + fn Referer(&self) -> windows_core::Result; + fn SetReferer(&self, value: windows_core::Ref<'_, super::super::super::Foundation::Uri>) -> windows_core::Result<()>; + fn TransferEncoding(&self) -> windows_core::Result; + fn UserAgent(&self) -> windows_core::Result; + fn Append(&self, name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryAppendWithoutValidation(&self, name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result; +} +#[cfg(feature = "Networking")] +impl IHttpRequestHeaderCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Accept(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::Accept(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AcceptEncoding(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::AcceptEncoding(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn AcceptLanguage(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::AcceptLanguage(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Authorization(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::Authorization(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAuthorization(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpRequestHeaderCollection_Impl::SetAuthorization(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn CacheControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::CacheControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Connection(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::Connection(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Cookie(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::Cookie(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Date(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::Date(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDate(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpRequestHeaderCollection_Impl::SetDate(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Expect(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::Expect(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn From(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::From(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetFrom(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpRequestHeaderCollection_Impl::SetFrom(this, core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn Host(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::Host(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetHost(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpRequestHeaderCollection_Impl::SetHost(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn IfModifiedSince(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::IfModifiedSince(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetIfModifiedSince(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpRequestHeaderCollection_Impl::SetIfModifiedSince(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn IfUnmodifiedSince(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::IfUnmodifiedSince(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetIfUnmodifiedSince(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpRequestHeaderCollection_Impl::SetIfUnmodifiedSince(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn MaxForwards(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::MaxForwards(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetMaxForwards(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpRequestHeaderCollection_Impl::SetMaxForwards(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn ProxyAuthorization(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::ProxyAuthorization(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetProxyAuthorization(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpRequestHeaderCollection_Impl::SetProxyAuthorization(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Referer(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::Referer(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetReferer(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpRequestHeaderCollection_Impl::SetReferer(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn TransferEncoding(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::TransferEncoding(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn UserAgent(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::UserAgent(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Append(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpRequestHeaderCollection_Impl::Append(this, core::mem::transmute(&name), core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn TryAppendWithoutValidation(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpRequestHeaderCollection_Impl::TryAppendWithoutValidation(this, core::mem::transmute(&name), core::mem::transmute(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Accept: Accept::, + AcceptEncoding: AcceptEncoding::, + AcceptLanguage: AcceptLanguage::, + Authorization: Authorization::, + SetAuthorization: SetAuthorization::, + CacheControl: CacheControl::, + Connection: Connection::, + Cookie: Cookie::, + Date: Date::, + SetDate: SetDate::, + Expect: Expect::, + From: From::, + SetFrom: SetFrom::, + Host: Host::, + SetHost: SetHost::, + IfModifiedSince: IfModifiedSince::, + SetIfModifiedSince: SetIfModifiedSince::, + IfUnmodifiedSince: IfUnmodifiedSince::, + SetIfUnmodifiedSince: SetIfUnmodifiedSince::, + MaxForwards: MaxForwards::, + SetMaxForwards: SetMaxForwards::, + ProxyAuthorization: ProxyAuthorization::, + SetProxyAuthorization: SetProxyAuthorization::, + Referer: Referer::, + SetReferer: SetReferer::, + TransferEncoding: TransferEncoding::, + UserAgent: UserAgent::, + Append: Append::, + TryAppendWithoutValidation: TryAppendWithoutValidation::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpRequestHeaderCollection_Vtbl { @@ -21005,6 +105598,225 @@ windows_core::imp::define_interface!(IHttpResponseHeaderCollection, IHttpRespons impl windows_core::RuntimeType for IHttpResponseHeaderCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpResponseHeaderCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpResponseHeaderCollection"; +} +pub trait IHttpResponseHeaderCollection_Impl: windows_core::IUnknownImpl { + fn Age(&self) -> windows_core::Result>; + fn SetAge(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn Allow(&self) -> windows_core::Result; + fn CacheControl(&self) -> windows_core::Result; + fn Connection(&self) -> windows_core::Result; + fn Date(&self) -> windows_core::Result>; + fn SetDate(&self, value: windows_core::Ref<'_, super::super::super::Foundation::IReference>) -> windows_core::Result<()>; + fn Location(&self) -> windows_core::Result; + fn SetLocation(&self, value: windows_core::Ref<'_, super::super::super::Foundation::Uri>) -> windows_core::Result<()>; + fn ProxyAuthenticate(&self) -> windows_core::Result; + fn RetryAfter(&self) -> windows_core::Result; + fn SetRetryAfter(&self, value: windows_core::Ref<'_, HttpDateOrDeltaHeaderValue>) -> windows_core::Result<()>; + fn TransferEncoding(&self) -> windows_core::Result; + fn WwwAuthenticate(&self) -> windows_core::Result; + fn Append(&self, name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryAppendWithoutValidation(&self, name: &windows_core::HSTRING, value: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpResponseHeaderCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Age(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseHeaderCollection_Impl::Age(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetAge(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpResponseHeaderCollection_Impl::SetAge(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Allow(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseHeaderCollection_Impl::Allow(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CacheControl(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseHeaderCollection_Impl::CacheControl(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Connection(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseHeaderCollection_Impl::Connection(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Date(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseHeaderCollection_Impl::Date(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetDate(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpResponseHeaderCollection_Impl::SetDate(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn Location(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseHeaderCollection_Impl::Location(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetLocation(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpResponseHeaderCollection_Impl::SetLocation(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn ProxyAuthenticate(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseHeaderCollection_Impl::ProxyAuthenticate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn RetryAfter(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseHeaderCollection_Impl::RetryAfter(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetRetryAfter(this: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpResponseHeaderCollection_Impl::SetRetryAfter(this, core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn TransferEncoding(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseHeaderCollection_Impl::TransferEncoding(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn WwwAuthenticate(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseHeaderCollection_Impl::WwwAuthenticate(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Append(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, value: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpResponseHeaderCollection_Impl::Append(this, core::mem::transmute(&name), core::mem::transmute(&value)).into() + } + } + unsafe extern "system" fn TryAppendWithoutValidation(this: *mut core::ffi::c_void, name: *mut core::ffi::c_void, value: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpResponseHeaderCollection_Impl::TryAppendWithoutValidation(this, core::mem::transmute(&name), core::mem::transmute(&value)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Age: Age::, + SetAge: SetAge::, + Allow: Allow::, + CacheControl: CacheControl::, + Connection: Connection::, + Date: Date::, + SetDate: SetDate::, + Location: Location::, + SetLocation: SetLocation::, + ProxyAuthenticate: ProxyAuthenticate::, + RetryAfter: RetryAfter::, + SetRetryAfter: SetRetryAfter::, + TransferEncoding: TransferEncoding::, + WwwAuthenticate: WwwAuthenticate::, + Append: Append::, + TryAppendWithoutValidation: TryAppendWithoutValidation::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpResponseHeaderCollection_Vtbl { @@ -21030,6 +105842,51 @@ windows_core::imp::define_interface!(IHttpTransferCodingHeaderValue, IHttpTransf impl windows_core::RuntimeType for IHttpTransferCodingHeaderValue { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpTransferCodingHeaderValue { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpTransferCodingHeaderValue"; +} +pub trait IHttpTransferCodingHeaderValue_Impl: windows_core::IUnknownImpl { + fn Parameters(&self) -> windows_core::Result>; + fn Value(&self) -> windows_core::Result; +} +impl IHttpTransferCodingHeaderValue_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parameters(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpTransferCodingHeaderValue_Impl::Parameters(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Value(this: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpTransferCodingHeaderValue_Impl::Value(this) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parameters: Parameters::, + Value: Value::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpTransferCodingHeaderValue_Vtbl { @@ -21041,6 +105898,43 @@ windows_core::imp::define_interface!(IHttpTransferCodingHeaderValueCollection, I impl windows_core::RuntimeType for IHttpTransferCodingHeaderValueCollection { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpTransferCodingHeaderValueCollection { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpTransferCodingHeaderValueCollection"; +} +pub trait IHttpTransferCodingHeaderValueCollection_Impl: windows_core::IUnknownImpl { + fn ParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result<()>; + fn TryParseAdd(&self, input: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpTransferCodingHeaderValueCollection_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn ParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IHttpTransferCodingHeaderValueCollection_Impl::ParseAdd(this, core::mem::transmute(&input)).into() + } + } + unsafe extern "system" fn TryParseAdd(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpTransferCodingHeaderValueCollection_Impl::TryParseAdd(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + ParseAdd: ParseAdd::, + TryParseAdd: TryParseAdd::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpTransferCodingHeaderValueCollection_Vtbl { @@ -21052,6 +105946,33 @@ windows_core::imp::define_interface!(IHttpTransferCodingHeaderValueFactory, IHtt impl windows_core::RuntimeType for IHttpTransferCodingHeaderValueFactory { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpTransferCodingHeaderValueFactory { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpTransferCodingHeaderValueFactory"; +} +pub trait IHttpTransferCodingHeaderValueFactory_Impl: windows_core::IUnknownImpl { + fn Create(&self, input: &windows_core::HSTRING) -> windows_core::Result; +} +impl IHttpTransferCodingHeaderValueFactory_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Create(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpTransferCodingHeaderValueFactory_Impl::Create(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { base__: windows_core::IInspectable_Vtbl::new::(), Create: Create:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpTransferCodingHeaderValueFactory_Vtbl { @@ -21062,6 +105983,50 @@ windows_core::imp::define_interface!(IHttpTransferCodingHeaderValueStatics, IHtt impl windows_core::RuntimeType for IHttpTransferCodingHeaderValueStatics { const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::for_interface::(); } +impl windows_core::RuntimeName for IHttpTransferCodingHeaderValueStatics { + const NAME: &'static str = "Windows.Web.Http.Headers.IHttpTransferCodingHeaderValueStatics"; +} +pub trait IHttpTransferCodingHeaderValueStatics_Impl: windows_core::IUnknownImpl { + fn Parse(&self, input: &windows_core::HSTRING) -> windows_core::Result; + fn TryParse(&self, input: &windows_core::HSTRING, transferCodingHeaderValue: windows_core::OutRef<'_, HttpTransferCodingHeaderValue>) -> windows_core::Result; +} +impl IHttpTransferCodingHeaderValueStatics_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn Parse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, result__: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpTransferCodingHeaderValueStatics_Impl::Parse(this, core::mem::transmute(&input)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + core::mem::forget(ok__); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn TryParse(this: *mut core::ffi::c_void, input: *mut core::ffi::c_void, transfercodingheadervalue: *mut *mut core::ffi::c_void, result__: *mut bool) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IHttpTransferCodingHeaderValueStatics_Impl::TryParse(this, core::mem::transmute(&input), core::mem::transmute_copy(&transfercodingheadervalue)) { + Ok(ok__) => { + result__.write(core::mem::transmute_copy(&ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + Self { + base__: windows_core::IInspectable_Vtbl::new::(), + Parse: Parse::, + TryParse: TryParse::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} #[repr(C)] #[doc(hidden)] pub struct IHttpTransferCodingHeaderValueStatics_Vtbl { @@ -21072,11 +106037,15 @@ pub struct IHttpTransferCodingHeaderValueStatics_Vtbl { } } } +#[cfg(feature = "Win32")] pub mod Win32{ +#[cfg(feature = "Win32_Devices")] pub mod Devices{ +#[cfg(feature = "Win32_Devices_FunctionDiscovery")] pub mod FunctionDiscovery{ pub const PKEY_Device_FriendlyName: super::super::Foundation::PROPERTYKEY = super::super::Foundation::PROPERTYKEY { fmtid: windows_core::GUID::from_u128(0xa45c254e_df1c_4efd_8020_67d146a850e0), pid: 14 }; } +#[cfg(feature = "Win32_Devices_HumanInterfaceDevice")] pub mod HumanInterfaceDevice{ #[inline] pub unsafe fn DirectInput8Create(hinst: super::super::Foundation::HINSTANCE, dwversion: u32, riidltf: *const windows_core::GUID, ppvout: *mut *mut core::ffi::c_void, punkouter: P4) -> windows_core::Result<()> @@ -21459,10 +106428,31 @@ impl IDirectInput8W { pub unsafe fn EnumDevices(&self, param0: u32, param1: LPDIENUMDEVICESCALLBACKW, param2: *mut core::ffi::c_void, param3: u32) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).EnumDevices)(windows_core::Interface::as_raw(self), param0, param1, param2 as _, param3).ok() } } + pub unsafe fn GetDeviceStatus(&self, param0: *const windows_core::GUID) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetDeviceStatus)(windows_core::Interface::as_raw(self), param0).ok() } + } + pub unsafe fn RunControlPanel(&self, param0: super::super::Foundation::HWND, param1: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RunControlPanel)(windows_core::Interface::as_raw(self), param0, param1).ok() } + } pub unsafe fn Initialize(&self, param0: super::super::Foundation::HINSTANCE, param1: u32) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Initialize)(windows_core::Interface::as_raw(self), param0, param1).ok() } } + pub unsafe fn FindDevice(&self, param0: *const windows_core::GUID, param1: P1, param2: *mut windows_core::GUID) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).FindDevice)(windows_core::Interface::as_raw(self), param0, param1.param().abi(), param2 as _).ok() } } + pub unsafe fn EnumDevicesBySemantics(&self, param0: P0, param1: *mut DIACTIONFORMATW, param2: LPDIENUMDEVICESBYSEMANTICSCBW, param3: *mut core::ffi::c_void, param4: u32) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).EnumDevicesBySemantics)(windows_core::Interface::as_raw(self), param0.param().abi(), param1 as _, param2, param3 as _, param4).ok() } + } + pub unsafe fn ConfigureDevices(&self, param0: LPDICONFIGUREDEVICESCALLBACK, param1: *mut DICONFIGUREDEVICESPARAMSW, param2: u32, param3: *mut core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).ConfigureDevices)(windows_core::Interface::as_raw(self), param0, core::mem::transmute(param1), param2, param3 as _).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IDirectInput8W_Vtbl { @@ -21477,7 +106467,7 @@ pub struct IDirectInput8W_Vtbl { pub ConfigureDevices: unsafe extern "system" fn(*mut core::ffi::c_void, LPDICONFIGUREDEVICESCALLBACK, *mut DICONFIGUREDEVICESPARAMSW, u32, *mut core::ffi::c_void) -> windows_core::HRESULT, } pub trait IDirectInput8W_Impl: windows_core::IUnknownImpl { - fn CreateDevice(&self, param0: *const windows_core::GUID, param1: windows_core::OutRef, param2: windows_core::Ref) -> windows_core::Result<()>; + fn CreateDevice(&self, param0: *const windows_core::GUID, param1: windows_core::OutRef<'_, IDirectInputDevice8W>, param2: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; fn EnumDevices(&self, param0: u32, param1: LPDIENUMDEVICESCALLBACKW, param2: *mut core::ffi::c_void, param3: u32) -> windows_core::Result<()>; fn GetDeviceStatus(&self, param0: *const windows_core::GUID) -> windows_core::Result<()>; fn RunControlPanel(&self, param0: super::super::Foundation::HWND, param1: u32) -> windows_core::Result<()>; @@ -21556,18 +106546,48 @@ impl windows_core::RuntimeName for IDirectInput8W {} windows_core::imp::define_interface!(IDirectInputDevice8W, IDirectInputDevice8W_Vtbl, 0x54d41081_dc15_4833_a41b_748f73a38179); windows_core::imp::interface_hierarchy!(IDirectInputDevice8W, windows_core::IUnknown); impl IDirectInputDevice8W { + pub unsafe fn GetCapabilities(&self, param0: *mut DIDEVCAPS) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetCapabilities)(windows_core::Interface::as_raw(self), param0 as _).ok() } + } + pub unsafe fn EnumObjects(&self, param0: LPDIENUMDEVICEOBJECTSCALLBACKW, param1: *mut core::ffi::c_void, param2: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).EnumObjects)(windows_core::Interface::as_raw(self), param0, param1 as _, param2).ok() } + } + pub unsafe fn GetProperty(&self, param0: *const windows_core::GUID, param1: *mut DIPROPHEADER) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetProperty)(windows_core::Interface::as_raw(self), param0, param1 as _).ok() } + } + pub unsafe fn SetProperty(&self, param0: *const windows_core::GUID, param1: *mut DIPROPHEADER) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetProperty)(windows_core::Interface::as_raw(self), param0, param1 as _).ok() } + } pub unsafe fn Acquire(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Acquire)(windows_core::Interface::as_raw(self)).ok() } } + pub unsafe fn Unacquire(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Unacquire)(windows_core::Interface::as_raw(self)).ok() } + } pub unsafe fn GetDeviceState(&self, param0: u32, param1: *mut core::ffi::c_void) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).GetDeviceState)(windows_core::Interface::as_raw(self), param0, param1 as _).ok() } } + pub unsafe fn GetDeviceData(&self, param0: u32, param1: *mut DIDEVICEOBJECTDATA, param2: *mut u32, param3: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetDeviceData)(windows_core::Interface::as_raw(self), param0, param1 as _, param2 as _, param3).ok() } + } pub unsafe fn SetDataFormat(&self, param0: *mut DIDATAFORMAT) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetDataFormat)(windows_core::Interface::as_raw(self), param0 as _).ok() } } + pub unsafe fn SetEventNotification(&self, param0: super::super::Foundation::HANDLE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetEventNotification)(windows_core::Interface::as_raw(self), param0).ok() } + } pub unsafe fn SetCooperativeLevel(&self, param0: super::super::Foundation::HWND, param1: u32) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetCooperativeLevel)(windows_core::Interface::as_raw(self), param0, param1).ok() } } + pub unsafe fn GetObjectInfo(&self, param0: *mut DIDEVICEOBJECTINSTANCEW, param1: u32, param2: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetObjectInfo)(windows_core::Interface::as_raw(self), param0 as _, param1, param2).ok() } + } + pub unsafe fn GetDeviceInfo(&self, param0: *mut DIDEVICEINSTANCEW) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetDeviceInfo)(windows_core::Interface::as_raw(self), param0 as _).ok() } + } + pub unsafe fn RunControlPanel(&self, param0: super::super::Foundation::HWND, param1: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RunControlPanel)(windows_core::Interface::as_raw(self), param0, param1).ok() } + } pub unsafe fn Initialize(&self, param0: super::super::Foundation::HINSTANCE, param1: u32, param2: *const windows_core::GUID) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Initialize)(windows_core::Interface::as_raw(self), param0, param1, param2).ok() } } @@ -21577,10 +106597,58 @@ impl IDirectInputDevice8W { { unsafe { (windows_core::Interface::vtable(self).CreateEffect)(windows_core::Interface::as_raw(self), param0, param1 as _, core::mem::transmute(param2), param3.param().abi()).ok() } } + pub unsafe fn EnumEffects(&self, param0: LPDIENUMEFFECTSCALLBACKW, param1: *mut core::ffi::c_void, param2: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).EnumEffects)(windows_core::Interface::as_raw(self), param0, param1 as _, param2).ok() } + } + pub unsafe fn GetEffectInfo(&self, param0: *mut DIEFFECTINFOW, param1: *const windows_core::GUID) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetEffectInfo)(windows_core::Interface::as_raw(self), param0 as _, param1).ok() } + } + pub unsafe fn GetForceFeedbackState(&self, param0: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetForceFeedbackState)(windows_core::Interface::as_raw(self), param0 as _).ok() } + } + pub unsafe fn SendForceFeedbackCommand(&self, param0: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SendForceFeedbackCommand)(windows_core::Interface::as_raw(self), param0).ok() } + } + pub unsafe fn EnumCreatedEffectObjects(&self, param0: LPDIENUMCREATEDEFFECTOBJECTSCALLBACK, param1: *mut core::ffi::c_void, param2: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).EnumCreatedEffectObjects)(windows_core::Interface::as_raw(self), param0, param1 as _, param2).ok() } + } + pub unsafe fn Escape(&self, param0: *mut DIEFFESCAPE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Escape)(windows_core::Interface::as_raw(self), param0 as _).ok() } + } pub unsafe fn Poll(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Poll)(windows_core::Interface::as_raw(self)).ok() } } + pub unsafe fn SendDeviceData(&self, param0: u32, param1: *mut DIDEVICEOBJECTDATA, param2: *mut u32, param3: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SendDeviceData)(windows_core::Interface::as_raw(self), param0, param1 as _, param2 as _, param3).ok() } } + pub unsafe fn EnumEffectsInFile(&self, param0: P0, param1: LPDIENUMEFFECTSINFILECALLBACK, param2: *mut core::ffi::c_void, param3: u32) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).EnumEffectsInFile)(windows_core::Interface::as_raw(self), param0.param().abi(), param1, param2 as _, param3).ok() } + } + pub unsafe fn WriteEffectToFile(&self, param0: P0, param1: u32, param2: *mut DIFILEEFFECT, param3: u32) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).WriteEffectToFile)(windows_core::Interface::as_raw(self), param0.param().abi(), param1, param2 as _, param3).ok() } + } + pub unsafe fn BuildActionMap(&self, param0: *mut DIACTIONFORMATW, param1: P1, param2: u32) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).BuildActionMap)(windows_core::Interface::as_raw(self), param0 as _, param1.param().abi(), param2).ok() } + } + pub unsafe fn SetActionMap(&self, param0: *mut DIACTIONFORMATW, param1: P1, param2: u32) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetActionMap)(windows_core::Interface::as_raw(self), param0 as _, param1.param().abi(), param2).ok() } + } + pub unsafe fn GetImageInfo(&self, param0: *mut DIDEVICEIMAGEINFOHEADERW) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetImageInfo)(windows_core::Interface::as_raw(self), param0 as _).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IDirectInputDevice8W_Vtbl { @@ -21631,7 +106699,7 @@ pub trait IDirectInputDevice8W_Impl: windows_core::IUnknownImpl { fn GetDeviceInfo(&self, param0: *mut DIDEVICEINSTANCEW) -> windows_core::Result<()>; fn RunControlPanel(&self, param0: super::super::Foundation::HWND, param1: u32) -> windows_core::Result<()>; fn Initialize(&self, param0: super::super::Foundation::HINSTANCE, param1: u32, param2: *const windows_core::GUID) -> windows_core::Result<()>; - fn CreateEffect(&self, param0: *const windows_core::GUID, param1: *mut DIEFFECT, param2: windows_core::OutRef, param3: windows_core::Ref) -> windows_core::Result<()>; + fn CreateEffect(&self, param0: *const windows_core::GUID, param1: *mut DIEFFECT, param2: windows_core::OutRef<'_, IDirectInputEffect>, param3: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; fn EnumEffects(&self, param0: LPDIENUMEFFECTSCALLBACKW, param1: *mut core::ffi::c_void, param2: u32) -> windows_core::Result<()>; fn GetEffectInfo(&self, param0: *mut DIEFFECTINFOW, param1: *const windows_core::GUID) -> windows_core::Result<()>; fn GetForceFeedbackState(&self, param0: *mut u32) -> windows_core::Result<()>; @@ -21866,6 +106934,12 @@ impl IDirectInputEffect { pub unsafe fn Initialize(&self, param0: super::super::Foundation::HINSTANCE, param1: u32, param2: *const windows_core::GUID) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Initialize)(windows_core::Interface::as_raw(self), param0, param1, param2).ok() } } + pub unsafe fn GetEffectGuid(&self, param0: *mut windows_core::GUID) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetEffectGuid)(windows_core::Interface::as_raw(self), param0 as _).ok() } + } + pub unsafe fn GetParameters(&self, param0: *mut DIEFFECT, param1: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetParameters)(windows_core::Interface::as_raw(self), param0 as _, param1).ok() } + } pub unsafe fn SetParameters(&self, param0: *mut DIEFFECT, param1: u32) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetParameters)(windows_core::Interface::as_raw(self), param0 as _, param1).ok() } } @@ -21875,7 +106949,19 @@ impl IDirectInputEffect { pub unsafe fn Stop(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Stop)(windows_core::Interface::as_raw(self)).ok() } } + pub unsafe fn GetEffectStatus(&self, param0: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetEffectStatus)(windows_core::Interface::as_raw(self), param0 as _).ok() } } + pub unsafe fn Download(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Download)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn Unload(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Unload)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn Escape(&self, param0: *mut DIEFFESCAPE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Escape)(windows_core::Interface::as_raw(self), param0 as _).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IDirectInputEffect_Vtbl { @@ -21984,20 +107070,22 @@ impl IDirectInputEffect_Vtbl { } } impl windows_core::RuntimeName for IDirectInputEffect {} -pub type LPDICONFIGUREDEVICESCALLBACK = Option, param1: *mut core::ffi::c_void) -> windows_core::BOOL>; -pub type LPDIENUMCREATEDEFFECTOBJECTSCALLBACK = Option, param1: *mut core::ffi::c_void) -> windows_core::BOOL>; +pub type LPDICONFIGUREDEVICESCALLBACK = Option, param1: *mut core::ffi::c_void) -> windows_core::BOOL>; +pub type LPDIENUMCREATEDEFFECTOBJECTSCALLBACK = Option, param1: *mut core::ffi::c_void) -> windows_core::BOOL>; pub type LPDIENUMDEVICEOBJECTSCALLBACKW = Option windows_core::BOOL>; -pub type LPDIENUMDEVICESBYSEMANTICSCBW = Option, param2: u32, param3: u32, param4: *mut core::ffi::c_void) -> windows_core::BOOL>; +pub type LPDIENUMDEVICESBYSEMANTICSCBW = Option, param2: u32, param3: u32, param4: *mut core::ffi::c_void) -> windows_core::BOOL>; pub type LPDIENUMDEVICESCALLBACKW = Option windows_core::BOOL>; pub type LPDIENUMEFFECTSCALLBACKW = Option windows_core::BOOL>; pub type LPDIENUMEFFECTSINFILECALLBACK = Option windows_core::BOOL>; } +#[cfg(feature = "Win32_Devices_Properties")] pub mod Properties{ #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct DEVPROPTYPE(pub u32); } } +#[cfg(feature = "Win32_Foundation")] pub mod Foundation{ #[inline] pub unsafe fn CloseHandle(hobject: HANDLE) -> windows_core::Result<()> { @@ -22316,7 +107404,9 @@ pub const WAIT_TIMEOUT: WAIT_EVENT = WAIT_EVENT(258u32); #[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] pub struct WPARAM(pub usize); } +#[cfg(feature = "Win32_Graphics")] pub mod Graphics{ +#[cfg(feature = "Win32_Graphics_Direct3D")] pub mod Direct3D{ pub const D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST: D3D_PRIMITIVE_TOPOLOGY = D3D_PRIMITIVE_TOPOLOGY(4i32); #[repr(transparent)] @@ -22393,6 +107483,12 @@ impl ID3DBlob_Vtbl { impl windows_core::RuntimeName for ID3DBlob {} windows_core::imp::define_interface!(ID3DInclude, ID3DInclude_Vtbl); impl ID3DInclude { + pub unsafe fn Open(&self, includetype: D3D_INCLUDE_TYPE, pfilename: P1, pparentdata: *const core::ffi::c_void, ppdata: *mut *mut core::ffi::c_void, pbytes: *mut u32) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).Open)(windows_core::Interface::as_raw(self), includetype, pfilename.param().abi(), pparentdata, ppdata as _, pbytes as _).ok() } + } pub unsafe fn Close(&self, pdata: *const core::ffi::c_void) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Close)(windows_core::Interface::as_raw(self), pdata).ok() } } @@ -22439,6 +107535,7 @@ impl ID3DInclude { unsafe { windows_core::ScopedInterface::new(core::mem::transmute(&this.vtable)) } } } +#[cfg(feature = "Win32_Graphics_Direct3D_Fxc")] pub mod Fxc{ #[inline] pub unsafe fn D3DCompile(psrcdata: *const core::ffi::c_void, srcdatasize: usize, psourcename: P2, pdefines: Option<*const super::D3D_SHADER_MACRO>, pinclude: P4, pentrypoint: P5, ptarget: P6, flags1: u32, flags2: u32, ppcode: *mut Option, pperrormsgs: Option<*mut Option>) -> windows_core::Result<()> @@ -22453,6 +107550,7 @@ where } } } +#[cfg(feature = "Win32_Graphics_Direct3D11")] pub mod Direct3D11{ #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi"))] #[inline] @@ -24076,6 +109174,11 @@ impl core::ops::Deref for ID3D11Asynchronous { } } windows_core::imp::interface_hierarchy!(ID3D11Asynchronous, windows_core::IUnknown, ID3D11DeviceChild); +impl ID3D11Asynchronous { + pub unsafe fn GetDataSize(&self) -> u32 { + unsafe { (windows_core::Interface::vtable(self).GetDataSize)(windows_core::Interface::as_raw(self)) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11Asynchronous_Vtbl { @@ -24110,6 +109213,24 @@ impl core::ops::Deref for ID3D11AuthenticatedChannel { } } windows_core::imp::interface_hierarchy!(ID3D11AuthenticatedChannel, windows_core::IUnknown, ID3D11DeviceChild); +impl ID3D11AuthenticatedChannel { + pub unsafe fn GetCertificateSize(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetCertificateSize)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetCertificate(&self, pcertificate: &mut [u8]) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetCertificate)(windows_core::Interface::as_raw(self), pcertificate.len().try_into().unwrap(), core::mem::transmute(pcertificate.as_ptr())).ok() } + } + pub unsafe fn GetChannelHandle(&self) -> super::super::Foundation::HANDLE { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetChannelHandle)(windows_core::Interface::as_raw(self), &mut result__); + result__ + } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11AuthenticatedChannel_Vtbl { @@ -24210,6 +109331,11 @@ impl core::ops::Deref for ID3D11BlendState1 { } } windows_core::imp::interface_hierarchy!(ID3D11BlendState1, windows_core::IUnknown, ID3D11DeviceChild, ID3D11BlendState); +impl ID3D11BlendState1 { + pub unsafe fn GetDesc1(&self, pdesc: *mut D3D11_BLEND_DESC1) { + unsafe { (windows_core::Interface::vtable(self).GetDesc1)(windows_core::Interface::as_raw(self), pdesc as _) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11BlendState1_Vtbl { @@ -24284,10 +109410,23 @@ impl core::ops::Deref for ID3D11ClassInstance { } windows_core::imp::interface_hierarchy!(ID3D11ClassInstance, windows_core::IUnknown, ID3D11DeviceChild); impl ID3D11ClassInstance { + pub unsafe fn GetClassLinkage(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetClassLinkage)(windows_core::Interface::as_raw(self), &mut result__); + windows_core::Type::from_abi(result__) + } + } pub unsafe fn GetDesc(&self, pdesc: *mut D3D11_CLASS_INSTANCE_DESC) { unsafe { (windows_core::Interface::vtable(self).GetDesc)(windows_core::Interface::as_raw(self), pdesc as _) } } + pub unsafe fn GetInstanceName(&self, pinstancename: Option, pbufferlength: *mut usize) { + unsafe { (windows_core::Interface::vtable(self).GetInstanceName)(windows_core::Interface::as_raw(self), pinstancename.unwrap_or(core::mem::zeroed()) as _, pbufferlength as _) } } + pub unsafe fn GetTypeName(&self, ptypename: Option, pbufferlength: *mut usize) { + unsafe { (windows_core::Interface::vtable(self).GetTypeName)(windows_core::Interface::as_raw(self), ptypename.unwrap_or(core::mem::zeroed()) as _, pbufferlength as _) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11ClassInstance_Vtbl { @@ -24300,7 +109439,7 @@ pub struct ID3D11ClassInstance_Vtbl { unsafe impl Send for ID3D11ClassInstance {} unsafe impl Sync for ID3D11ClassInstance {} pub trait ID3D11ClassInstance_Impl: ID3D11DeviceChild_Impl { - fn GetClassLinkage(&self, pplinkage: windows_core::OutRef); + fn GetClassLinkage(&self, pplinkage: windows_core::OutRef<'_, ID3D11ClassLinkage>); fn GetDesc(&self, pdesc: *mut D3D11_CLASS_INSTANCE_DESC); fn GetInstanceName(&self, pinstancename: windows_core::PSTR, pbufferlength: *mut usize); fn GetTypeName(&self, ptypename: windows_core::PSTR, pbufferlength: *mut usize); @@ -24352,6 +109491,26 @@ impl core::ops::Deref for ID3D11ClassLinkage { } } windows_core::imp::interface_hierarchy!(ID3D11ClassLinkage, windows_core::IUnknown, ID3D11DeviceChild); +impl ID3D11ClassLinkage { + pub unsafe fn GetClassInstance(&self, pclassinstancename: P0, instanceindex: u32) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetClassInstance)(windows_core::Interface::as_raw(self), pclassinstancename.param().abi(), instanceindex, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn CreateClassInstance(&self, pclasstypename: P0, constantbufferoffset: u32, constantvectoroffset: u32, textureoffset: u32, sampleroffset: u32) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateClassInstance)(windows_core::Interface::as_raw(self), pclasstypename.param().abi(), constantbufferoffset, constantvectoroffset, textureoffset, sampleroffset, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11ClassLinkage_Vtbl { @@ -24410,6 +109569,11 @@ impl core::ops::Deref for ID3D11CommandList { } } windows_core::imp::interface_hierarchy!(ID3D11CommandList, windows_core::IUnknown, ID3D11DeviceChild); +impl ID3D11CommandList { + pub unsafe fn GetContextFlags(&self) -> u32 { + unsafe { (windows_core::Interface::vtable(self).GetContextFlags)(windows_core::Interface::as_raw(self)) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11CommandList_Vtbl { @@ -24512,6 +109676,38 @@ impl core::ops::Deref for ID3D11CryptoSession { } } windows_core::imp::interface_hierarchy!(ID3D11CryptoSession, windows_core::IUnknown, ID3D11DeviceChild); +impl ID3D11CryptoSession { + pub unsafe fn GetCryptoType(&self) -> windows_core::GUID { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetCryptoType)(windows_core::Interface::as_raw(self), &mut result__); + result__ + } + } + pub unsafe fn GetDecoderProfile(&self) -> windows_core::GUID { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDecoderProfile)(windows_core::Interface::as_raw(self), &mut result__); + result__ + } + } + pub unsafe fn GetCertificateSize(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetCertificateSize)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetCertificate(&self, pcertificate: &mut [u8]) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetCertificate)(windows_core::Interface::as_raw(self), pcertificate.len().try_into().unwrap(), core::mem::transmute(pcertificate.as_ptr())).ok() } + } + pub unsafe fn GetCryptoSessionHandle(&self) -> super::super::Foundation::HANDLE { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetCryptoSessionHandle)(windows_core::Interface::as_raw(self), &mut result__); + result__ + } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11CryptoSession_Vtbl { @@ -24675,9 +109871,17 @@ impl ID3D11Device { unsafe { (windows_core::Interface::vtable(self).CreateBuffer)(windows_core::Interface::as_raw(self), pdesc, pinitialdata.unwrap_or(core::mem::zeroed()) as _, ppbuffer.unwrap_or(core::mem::zeroed()) as _).ok() } } #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CreateTexture1D(&self, pdesc: *const D3D11_TEXTURE1D_DESC, pinitialdata: Option<*const D3D11_SUBRESOURCE_DATA>, pptexture1d: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateTexture1D)(windows_core::Interface::as_raw(self), pdesc, pinitialdata.unwrap_or(core::mem::zeroed()) as _, pptexture1d.unwrap_or(core::mem::zeroed()) as _).ok() } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] pub unsafe fn CreateTexture2D(&self, pdesc: *const D3D11_TEXTURE2D_DESC, pinitialdata: Option<*const D3D11_SUBRESOURCE_DATA>, pptexture2d: Option<*mut Option>) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).CreateTexture2D)(windows_core::Interface::as_raw(self), pdesc, pinitialdata.unwrap_or(core::mem::zeroed()) as _, pptexture2d.unwrap_or(core::mem::zeroed()) as _).ok() } } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CreateTexture3D(&self, pdesc: *const D3D11_TEXTURE3D_DESC, pinitialdata: Option<*const D3D11_SUBRESOURCE_DATA>, pptexture3d: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateTexture3D)(windows_core::Interface::as_raw(self), pdesc, pinitialdata.unwrap_or(core::mem::zeroed()) as _, pptexture3d.unwrap_or(core::mem::zeroed()) as _).ok() } + } #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi_Common"))] pub unsafe fn CreateShaderResourceView(&self, presource: P0, pdesc: Option<*const D3D11_SHADER_RESOURCE_VIEW_DESC>, ppsrview: Option<*mut Option>) -> windows_core::Result<()> where @@ -24686,6 +109890,13 @@ impl ID3D11Device { unsafe { (windows_core::Interface::vtable(self).CreateShaderResourceView)(windows_core::Interface::as_raw(self), presource.param().abi(), pdesc.unwrap_or(core::mem::zeroed()) as _, ppsrview.unwrap_or(core::mem::zeroed()) as _).ok() } } #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CreateUnorderedAccessView(&self, presource: P0, pdesc: Option<*const D3D11_UNORDERED_ACCESS_VIEW_DESC>, ppuaview: Option<*mut Option>) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CreateUnorderedAccessView)(windows_core::Interface::as_raw(self), presource.param().abi(), pdesc.unwrap_or(core::mem::zeroed()) as _, ppuaview.unwrap_or(core::mem::zeroed()) as _).ok() } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] pub unsafe fn CreateRenderTargetView(&self, presource: P0, pdesc: Option<*const D3D11_RENDER_TARGET_VIEW_DESC>, pprtview: Option<*mut Option>) -> windows_core::Result<()> where P0: windows_core::Param, @@ -24709,12 +109920,62 @@ impl ID3D11Device { { unsafe { (windows_core::Interface::vtable(self).CreateVertexShader)(windows_core::Interface::as_raw(self), core::mem::transmute(pshaderbytecode.as_ptr()), pshaderbytecode.len().try_into().unwrap(), pclasslinkage.param().abi(), ppvertexshader.unwrap_or(core::mem::zeroed()) as _).ok() } } + pub unsafe fn CreateGeometryShader(&self, pshaderbytecode: &[u8], pclasslinkage: P2, ppgeometryshader: Option<*mut Option>) -> windows_core::Result<()> + where + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CreateGeometryShader)(windows_core::Interface::as_raw(self), core::mem::transmute(pshaderbytecode.as_ptr()), pshaderbytecode.len().try_into().unwrap(), pclasslinkage.param().abi(), ppgeometryshader.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn CreateGeometryShaderWithStreamOutput(&self, pshaderbytecode: &[u8], psodeclaration: Option<&[D3D11_SO_DECLARATION_ENTRY]>, pbufferstrides: Option<&[u32]>, rasterizedstream: u32, pclasslinkage: P7, ppgeometryshader: Option<*mut Option>) -> windows_core::Result<()> + where + P7: windows_core::Param, + { + unsafe { + (windows_core::Interface::vtable(self).CreateGeometryShaderWithStreamOutput)( + windows_core::Interface::as_raw(self), + core::mem::transmute(pshaderbytecode.as_ptr()), + pshaderbytecode.len().try_into().unwrap(), + core::mem::transmute(psodeclaration.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), + psodeclaration.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), + core::mem::transmute(pbufferstrides.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), + pbufferstrides.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), + rasterizedstream, + pclasslinkage.param().abi(), + ppgeometryshader.unwrap_or(core::mem::zeroed()) as _, + ) + .ok() + } + } pub unsafe fn CreatePixelShader(&self, pshaderbytecode: &[u8], pclasslinkage: P2, pppixelshader: Option<*mut Option>) -> windows_core::Result<()> where P2: windows_core::Param, { unsafe { (windows_core::Interface::vtable(self).CreatePixelShader)(windows_core::Interface::as_raw(self), core::mem::transmute(pshaderbytecode.as_ptr()), pshaderbytecode.len().try_into().unwrap(), pclasslinkage.param().abi(), pppixelshader.unwrap_or(core::mem::zeroed()) as _).ok() } } + pub unsafe fn CreateHullShader(&self, pshaderbytecode: &[u8], pclasslinkage: P2, pphullshader: Option<*mut Option>) -> windows_core::Result<()> + where + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CreateHullShader)(windows_core::Interface::as_raw(self), core::mem::transmute(pshaderbytecode.as_ptr()), pshaderbytecode.len().try_into().unwrap(), pclasslinkage.param().abi(), pphullshader.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn CreateDomainShader(&self, pshaderbytecode: &[u8], pclasslinkage: P2, ppdomainshader: Option<*mut Option>) -> windows_core::Result<()> + where + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CreateDomainShader)(windows_core::Interface::as_raw(self), core::mem::transmute(pshaderbytecode.as_ptr()), pshaderbytecode.len().try_into().unwrap(), pclasslinkage.param().abi(), ppdomainshader.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn CreateComputeShader(&self, pshaderbytecode: &[u8], pclasslinkage: P2, ppcomputeshader: Option<*mut Option>) -> windows_core::Result<()> + where + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CreateComputeShader)(windows_core::Interface::as_raw(self), core::mem::transmute(pshaderbytecode.as_ptr()), pshaderbytecode.len().try_into().unwrap(), pclasslinkage.param().abi(), ppcomputeshader.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn CreateClassLinkage(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateClassLinkage)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub unsafe fn CreateBlendState(&self, pblendstatedesc: *const D3D11_BLEND_DESC, ppblendstate: Option<*mut Option>) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).CreateBlendState)(windows_core::Interface::as_raw(self), pblendstatedesc, ppblendstate.unwrap_or(core::mem::zeroed()) as _).ok() } } @@ -24724,15 +109985,76 @@ impl ID3D11Device { pub unsafe fn CreateRasterizerState(&self, prasterizerdesc: *const D3D11_RASTERIZER_DESC, pprasterizerstate: Option<*mut Option>) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).CreateRasterizerState)(windows_core::Interface::as_raw(self), prasterizerdesc, pprasterizerstate.unwrap_or(core::mem::zeroed()) as _).ok() } } + pub unsafe fn CreateSamplerState(&self, psamplerdesc: *const D3D11_SAMPLER_DESC, ppsamplerstate: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateSamplerState)(windows_core::Interface::as_raw(self), psamplerdesc, ppsamplerstate.unwrap_or(core::mem::zeroed()) as _).ok() } + } pub unsafe fn CreateQuery(&self, pquerydesc: *const D3D11_QUERY_DESC, ppquery: Option<*mut Option>) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).CreateQuery)(windows_core::Interface::as_raw(self), pquerydesc, ppquery.unwrap_or(core::mem::zeroed()) as _).ok() } } + pub unsafe fn CreatePredicate(&self, ppredicatedesc: *const D3D11_QUERY_DESC, pppredicate: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreatePredicate)(windows_core::Interface::as_raw(self), ppredicatedesc, pppredicate.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn CreateCounter(&self, pcounterdesc: *const D3D11_COUNTER_DESC, ppcounter: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateCounter)(windows_core::Interface::as_raw(self), pcounterdesc, ppcounter.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn CreateDeferredContext(&self, contextflags: u32, ppdeferredcontext: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateDeferredContext)(windows_core::Interface::as_raw(self), contextflags, ppdeferredcontext.unwrap_or(core::mem::zeroed()) as _).ok() } + } pub unsafe fn OpenSharedResource(&self, hresource: super::super::Foundation::HANDLE, result__: *mut Option) -> windows_core::Result<()> where T: windows_core::Interface, { unsafe { (windows_core::Interface::vtable(self).OpenSharedResource)(windows_core::Interface::as_raw(self), hresource, &T::IID, result__ as *mut _ as *mut _).ok() } } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CheckFormatSupport(&self, format: super::Dxgi::Common::DXGI_FORMAT) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CheckFormatSupport)(windows_core::Interface::as_raw(self), format, &mut result__).map(|| result__) + } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CheckMultisampleQualityLevels(&self, format: super::Dxgi::Common::DXGI_FORMAT, samplecount: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CheckMultisampleQualityLevels)(windows_core::Interface::as_raw(self), format, samplecount, &mut result__).map(|| result__) + } + } + pub unsafe fn CheckCounterInfo(&self) -> D3D11_COUNTER_INFO { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CheckCounterInfo)(windows_core::Interface::as_raw(self), &mut result__); + result__ + } + } + pub unsafe fn CheckCounter(&self, pdesc: *const D3D11_COUNTER_DESC, ptype: *mut D3D11_COUNTER_TYPE, pactivecounters: *mut u32, szname: Option, pnamelength: Option<*mut u32>, szunits: Option, punitslength: Option<*mut u32>, szdescription: Option, pdescriptionlength: Option<*mut u32>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CheckCounter)(windows_core::Interface::as_raw(self), pdesc, ptype as _, pactivecounters as _, szname.unwrap_or(core::mem::zeroed()) as _, pnamelength.unwrap_or(core::mem::zeroed()) as _, szunits.unwrap_or(core::mem::zeroed()) as _, punitslength.unwrap_or(core::mem::zeroed()) as _, szdescription.unwrap_or(core::mem::zeroed()) as _, pdescriptionlength.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn CheckFeatureSupport(&self, feature: D3D11_FEATURE, pfeaturesupportdata: *mut core::ffi::c_void, featuresupportdatasize: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CheckFeatureSupport)(windows_core::Interface::as_raw(self), feature, pfeaturesupportdata as _, featuresupportdatasize).ok() } + } + pub unsafe fn GetPrivateData(&self, guid: *const windows_core::GUID, pdatasize: *mut u32, pdata: Option<*mut core::ffi::c_void>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetPrivateData)(windows_core::Interface::as_raw(self), guid, pdatasize as _, pdata.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn SetPrivateData(&self, guid: *const windows_core::GUID, datasize: u32, pdata: Option<*const core::ffi::c_void>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetPrivateData)(windows_core::Interface::as_raw(self), guid, datasize, pdata.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn SetPrivateDataInterface(&self, guid: *const windows_core::GUID, pdata: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetPrivateDataInterface)(windows_core::Interface::as_raw(self), guid, pdata.param().abi()).ok() } + } + #[cfg(feature = "Win32_Graphics_Direct3D")] + pub unsafe fn GetFeatureLevel(&self) -> super::Direct3D::D3D_FEATURE_LEVEL { + unsafe { (windows_core::Interface::vtable(self).GetFeatureLevel)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetCreationFlags(&self) -> u32 { + unsafe { (windows_core::Interface::vtable(self).GetCreationFlags)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetDeviceRemovedReason(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetDeviceRemovedReason)(windows_core::Interface::as_raw(self)).ok() } + } pub unsafe fn GetImmediateContext(&self) -> windows_core::Result { unsafe { let mut result__ = core::mem::zeroed(); @@ -24740,7 +110062,13 @@ impl ID3D11Device { windows_core::Type::from_abi(result__) } } + pub unsafe fn SetExceptionMode(&self, raiseflags: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetExceptionMode)(windows_core::Interface::as_raw(self), raiseflags).ok() } } + pub unsafe fn GetExceptionMode(&self) -> u32 { + unsafe { (windows_core::Interface::vtable(self).GetExceptionMode)(windows_core::Interface::as_raw(self)) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11Device_Vtbl { @@ -24823,31 +110151,31 @@ unsafe impl Send for ID3D11Device {} unsafe impl Sync for ID3D11Device {} #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi_Common"))] pub trait ID3D11Device_Impl: windows_core::IUnknownImpl { - fn CreateBuffer(&self, pdesc: *const D3D11_BUFFER_DESC, pinitialdata: *const D3D11_SUBRESOURCE_DATA, ppbuffer: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateTexture1D(&self, pdesc: *const D3D11_TEXTURE1D_DESC, pinitialdata: *const D3D11_SUBRESOURCE_DATA, pptexture1d: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateTexture2D(&self, pdesc: *const D3D11_TEXTURE2D_DESC, pinitialdata: *const D3D11_SUBRESOURCE_DATA, pptexture2d: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateTexture3D(&self, pdesc: *const D3D11_TEXTURE3D_DESC, pinitialdata: *const D3D11_SUBRESOURCE_DATA, pptexture3d: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateShaderResourceView(&self, presource: windows_core::Ref, pdesc: *const D3D11_SHADER_RESOURCE_VIEW_DESC, ppsrview: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateUnorderedAccessView(&self, presource: windows_core::Ref, pdesc: *const D3D11_UNORDERED_ACCESS_VIEW_DESC, ppuaview: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateRenderTargetView(&self, presource: windows_core::Ref, pdesc: *const D3D11_RENDER_TARGET_VIEW_DESC, pprtview: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateDepthStencilView(&self, presource: windows_core::Ref, pdesc: *const D3D11_DEPTH_STENCIL_VIEW_DESC, ppdepthstencilview: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateInputLayout(&self, pinputelementdescs: *const D3D11_INPUT_ELEMENT_DESC, numelements: u32, pshaderbytecodewithinputsignature: *const core::ffi::c_void, bytecodelength: usize, ppinputlayout: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateVertexShader(&self, pshaderbytecode: *const core::ffi::c_void, bytecodelength: usize, pclasslinkage: windows_core::Ref, ppvertexshader: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateGeometryShader(&self, pshaderbytecode: *const core::ffi::c_void, bytecodelength: usize, pclasslinkage: windows_core::Ref, ppgeometryshader: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateGeometryShaderWithStreamOutput(&self, pshaderbytecode: *const core::ffi::c_void, bytecodelength: usize, psodeclaration: *const D3D11_SO_DECLARATION_ENTRY, numentries: u32, pbufferstrides: *const u32, numstrides: u32, rasterizedstream: u32, pclasslinkage: windows_core::Ref, ppgeometryshader: windows_core::OutRef) -> windows_core::Result<()>; - fn CreatePixelShader(&self, pshaderbytecode: *const core::ffi::c_void, bytecodelength: usize, pclasslinkage: windows_core::Ref, pppixelshader: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateHullShader(&self, pshaderbytecode: *const core::ffi::c_void, bytecodelength: usize, pclasslinkage: windows_core::Ref, pphullshader: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateDomainShader(&self, pshaderbytecode: *const core::ffi::c_void, bytecodelength: usize, pclasslinkage: windows_core::Ref, ppdomainshader: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateComputeShader(&self, pshaderbytecode: *const core::ffi::c_void, bytecodelength: usize, pclasslinkage: windows_core::Ref, ppcomputeshader: windows_core::OutRef) -> windows_core::Result<()>; + fn CreateBuffer(&self, pdesc: *const D3D11_BUFFER_DESC, pinitialdata: *const D3D11_SUBRESOURCE_DATA, ppbuffer: windows_core::OutRef<'_, ID3D11Buffer>) -> windows_core::Result<()>; + fn CreateTexture1D(&self, pdesc: *const D3D11_TEXTURE1D_DESC, pinitialdata: *const D3D11_SUBRESOURCE_DATA, pptexture1d: windows_core::OutRef<'_, ID3D11Texture1D>) -> windows_core::Result<()>; + fn CreateTexture2D(&self, pdesc: *const D3D11_TEXTURE2D_DESC, pinitialdata: *const D3D11_SUBRESOURCE_DATA, pptexture2d: windows_core::OutRef<'_, ID3D11Texture2D>) -> windows_core::Result<()>; + fn CreateTexture3D(&self, pdesc: *const D3D11_TEXTURE3D_DESC, pinitialdata: *const D3D11_SUBRESOURCE_DATA, pptexture3d: windows_core::OutRef<'_, ID3D11Texture3D>) -> windows_core::Result<()>; + fn CreateShaderResourceView(&self, presource: windows_core::Ref<'_, ID3D11Resource>, pdesc: *const D3D11_SHADER_RESOURCE_VIEW_DESC, ppsrview: windows_core::OutRef<'_, ID3D11ShaderResourceView>) -> windows_core::Result<()>; + fn CreateUnorderedAccessView(&self, presource: windows_core::Ref<'_, ID3D11Resource>, pdesc: *const D3D11_UNORDERED_ACCESS_VIEW_DESC, ppuaview: windows_core::OutRef<'_, ID3D11UnorderedAccessView>) -> windows_core::Result<()>; + fn CreateRenderTargetView(&self, presource: windows_core::Ref<'_, ID3D11Resource>, pdesc: *const D3D11_RENDER_TARGET_VIEW_DESC, pprtview: windows_core::OutRef<'_, ID3D11RenderTargetView>) -> windows_core::Result<()>; + fn CreateDepthStencilView(&self, presource: windows_core::Ref<'_, ID3D11Resource>, pdesc: *const D3D11_DEPTH_STENCIL_VIEW_DESC, ppdepthstencilview: windows_core::OutRef<'_, ID3D11DepthStencilView>) -> windows_core::Result<()>; + fn CreateInputLayout(&self, pinputelementdescs: *const D3D11_INPUT_ELEMENT_DESC, numelements: u32, pshaderbytecodewithinputsignature: *const core::ffi::c_void, bytecodelength: usize, ppinputlayout: windows_core::OutRef<'_, ID3D11InputLayout>) -> windows_core::Result<()>; + fn CreateVertexShader(&self, pshaderbytecode: *const core::ffi::c_void, bytecodelength: usize, pclasslinkage: windows_core::Ref<'_, ID3D11ClassLinkage>, ppvertexshader: windows_core::OutRef<'_, ID3D11VertexShader>) -> windows_core::Result<()>; + fn CreateGeometryShader(&self, pshaderbytecode: *const core::ffi::c_void, bytecodelength: usize, pclasslinkage: windows_core::Ref<'_, ID3D11ClassLinkage>, ppgeometryshader: windows_core::OutRef<'_, ID3D11GeometryShader>) -> windows_core::Result<()>; + fn CreateGeometryShaderWithStreamOutput(&self, pshaderbytecode: *const core::ffi::c_void, bytecodelength: usize, psodeclaration: *const D3D11_SO_DECLARATION_ENTRY, numentries: u32, pbufferstrides: *const u32, numstrides: u32, rasterizedstream: u32, pclasslinkage: windows_core::Ref<'_, ID3D11ClassLinkage>, ppgeometryshader: windows_core::OutRef<'_, ID3D11GeometryShader>) -> windows_core::Result<()>; + fn CreatePixelShader(&self, pshaderbytecode: *const core::ffi::c_void, bytecodelength: usize, pclasslinkage: windows_core::Ref<'_, ID3D11ClassLinkage>, pppixelshader: windows_core::OutRef<'_, ID3D11PixelShader>) -> windows_core::Result<()>; + fn CreateHullShader(&self, pshaderbytecode: *const core::ffi::c_void, bytecodelength: usize, pclasslinkage: windows_core::Ref<'_, ID3D11ClassLinkage>, pphullshader: windows_core::OutRef<'_, ID3D11HullShader>) -> windows_core::Result<()>; + fn CreateDomainShader(&self, pshaderbytecode: *const core::ffi::c_void, bytecodelength: usize, pclasslinkage: windows_core::Ref<'_, ID3D11ClassLinkage>, ppdomainshader: windows_core::OutRef<'_, ID3D11DomainShader>) -> windows_core::Result<()>; + fn CreateComputeShader(&self, pshaderbytecode: *const core::ffi::c_void, bytecodelength: usize, pclasslinkage: windows_core::Ref<'_, ID3D11ClassLinkage>, ppcomputeshader: windows_core::OutRef<'_, ID3D11ComputeShader>) -> windows_core::Result<()>; fn CreateClassLinkage(&self) -> windows_core::Result; - fn CreateBlendState(&self, pblendstatedesc: *const D3D11_BLEND_DESC, ppblendstate: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateDepthStencilState(&self, pdepthstencildesc: *const D3D11_DEPTH_STENCIL_DESC, ppdepthstencilstate: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateRasterizerState(&self, prasterizerdesc: *const D3D11_RASTERIZER_DESC, pprasterizerstate: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateSamplerState(&self, psamplerdesc: *const D3D11_SAMPLER_DESC, ppsamplerstate: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateQuery(&self, pquerydesc: *const D3D11_QUERY_DESC, ppquery: windows_core::OutRef) -> windows_core::Result<()>; - fn CreatePredicate(&self, ppredicatedesc: *const D3D11_QUERY_DESC, pppredicate: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateCounter(&self, pcounterdesc: *const D3D11_COUNTER_DESC, ppcounter: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateDeferredContext(&self, contextflags: u32, ppdeferredcontext: windows_core::OutRef) -> windows_core::Result<()>; + fn CreateBlendState(&self, pblendstatedesc: *const D3D11_BLEND_DESC, ppblendstate: windows_core::OutRef<'_, ID3D11BlendState>) -> windows_core::Result<()>; + fn CreateDepthStencilState(&self, pdepthstencildesc: *const D3D11_DEPTH_STENCIL_DESC, ppdepthstencilstate: windows_core::OutRef<'_, ID3D11DepthStencilState>) -> windows_core::Result<()>; + fn CreateRasterizerState(&self, prasterizerdesc: *const D3D11_RASTERIZER_DESC, pprasterizerstate: windows_core::OutRef<'_, ID3D11RasterizerState>) -> windows_core::Result<()>; + fn CreateSamplerState(&self, psamplerdesc: *const D3D11_SAMPLER_DESC, ppsamplerstate: windows_core::OutRef<'_, ID3D11SamplerState>) -> windows_core::Result<()>; + fn CreateQuery(&self, pquerydesc: *const D3D11_QUERY_DESC, ppquery: windows_core::OutRef<'_, ID3D11Query>) -> windows_core::Result<()>; + fn CreatePredicate(&self, ppredicatedesc: *const D3D11_QUERY_DESC, pppredicate: windows_core::OutRef<'_, ID3D11Predicate>) -> windows_core::Result<()>; + fn CreateCounter(&self, pcounterdesc: *const D3D11_COUNTER_DESC, ppcounter: windows_core::OutRef<'_, ID3D11Counter>) -> windows_core::Result<()>; + fn CreateDeferredContext(&self, contextflags: u32, ppdeferredcontext: windows_core::OutRef<'_, ID3D11DeviceContext>) -> windows_core::Result<()>; fn OpenSharedResource(&self, hresource: super::super::Foundation::HANDLE, returnedinterface: *const windows_core::GUID, ppresource: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; fn CheckFormatSupport(&self, format: super::Dxgi::Common::DXGI_FORMAT) -> windows_core::Result; fn CheckMultisampleQualityLevels(&self, format: super::Dxgi::Common::DXGI_FORMAT, samplecount: u32) -> windows_core::Result; @@ -24856,11 +110184,11 @@ pub trait ID3D11Device_Impl: windows_core::IUnknownImpl { fn CheckFeatureSupport(&self, feature: D3D11_FEATURE, pfeaturesupportdata: *mut core::ffi::c_void, featuresupportdatasize: u32) -> windows_core::Result<()>; fn GetPrivateData(&self, guid: *const windows_core::GUID, pdatasize: *mut u32, pdata: *mut core::ffi::c_void) -> windows_core::Result<()>; fn SetPrivateData(&self, guid: *const windows_core::GUID, datasize: u32, pdata: *const core::ffi::c_void) -> windows_core::Result<()>; - fn SetPrivateDataInterface(&self, guid: *const windows_core::GUID, pdata: windows_core::Ref) -> windows_core::Result<()>; + fn SetPrivateDataInterface(&self, guid: *const windows_core::GUID, pdata: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; fn GetFeatureLevel(&self) -> super::Direct3D::D3D_FEATURE_LEVEL; fn GetCreationFlags(&self) -> u32; fn GetDeviceRemovedReason(&self) -> windows_core::Result<()>; - fn GetImmediateContext(&self, ppimmediatecontext: windows_core::OutRef); + fn GetImmediateContext(&self, ppimmediatecontext: windows_core::OutRef<'_, ID3D11DeviceContext>); fn SetExceptionMode(&self, raiseflags: u32) -> windows_core::Result<()>; fn GetExceptionMode(&self) -> u32; } @@ -25183,6 +110511,43 @@ impl core::ops::Deref for ID3D11Device1 { } } windows_core::imp::interface_hierarchy!(ID3D11Device1, windows_core::IUnknown, ID3D11Device); +impl ID3D11Device1 { + pub unsafe fn GetImmediateContext1(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetImmediateContext1)(windows_core::Interface::as_raw(self), &mut result__); + windows_core::Type::from_abi(result__) + } + } + pub unsafe fn CreateDeferredContext1(&self, contextflags: u32, ppdeferredcontext: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateDeferredContext1)(windows_core::Interface::as_raw(self), contextflags, ppdeferredcontext.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn CreateBlendState1(&self, pblendstatedesc: *const D3D11_BLEND_DESC1, ppblendstate: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateBlendState1)(windows_core::Interface::as_raw(self), pblendstatedesc, ppblendstate.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn CreateRasterizerState1(&self, prasterizerdesc: *const D3D11_RASTERIZER_DESC1, pprasterizerstate: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateRasterizerState1)(windows_core::Interface::as_raw(self), prasterizerdesc, pprasterizerstate.unwrap_or(core::mem::zeroed()) as _).ok() } + } + #[cfg(feature = "Win32_Graphics_Direct3D")] + pub unsafe fn CreateDeviceContextState(&self, flags: u32, pfeaturelevels: &[super::Direct3D::D3D_FEATURE_LEVEL], sdkversion: u32, emulatedinterface: *const windows_core::GUID, pchosenfeaturelevel: Option<*mut super::Direct3D::D3D_FEATURE_LEVEL>, ppcontextstate: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateDeviceContextState)(windows_core::Interface::as_raw(self), flags, core::mem::transmute(pfeaturelevels.as_ptr()), pfeaturelevels.len().try_into().unwrap(), sdkversion, emulatedinterface, pchosenfeaturelevel.unwrap_or(core::mem::zeroed()) as _, ppcontextstate.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn OpenSharedResource1(&self, hresource: super::super::Foundation::HANDLE) -> windows_core::Result + where + T: windows_core::Interface, + { + let mut result__ = core::ptr::null_mut(); + unsafe { (windows_core::Interface::vtable(self).OpenSharedResource1)(windows_core::Interface::as_raw(self), hresource, &T::IID, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } + } + pub unsafe fn OpenSharedResourceByName(&self, lpname: P0, dwdesiredaccess: u32) -> windows_core::Result + where + P0: windows_core::Param, + T: windows_core::Interface, + { + let mut result__ = core::ptr::null_mut(); + unsafe { (windows_core::Interface::vtable(self).OpenSharedResourceByName)(windows_core::Interface::as_raw(self), lpname.param().abi(), dwdesiredaccess, &T::IID, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11Device1_Vtbl { @@ -25202,11 +110567,11 @@ unsafe impl Send for ID3D11Device1 {} unsafe impl Sync for ID3D11Device1 {} #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi_Common"))] pub trait ID3D11Device1_Impl: ID3D11Device_Impl { - fn GetImmediateContext1(&self, ppimmediatecontext: windows_core::OutRef); - fn CreateDeferredContext1(&self, contextflags: u32, ppdeferredcontext: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateBlendState1(&self, pblendstatedesc: *const D3D11_BLEND_DESC1, ppblendstate: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateRasterizerState1(&self, prasterizerdesc: *const D3D11_RASTERIZER_DESC1, pprasterizerstate: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateDeviceContextState(&self, flags: u32, pfeaturelevels: *const super::Direct3D::D3D_FEATURE_LEVEL, featurelevels: u32, sdkversion: u32, emulatedinterface: *const windows_core::GUID, pchosenfeaturelevel: *mut super::Direct3D::D3D_FEATURE_LEVEL, ppcontextstate: windows_core::OutRef) -> windows_core::Result<()>; + fn GetImmediateContext1(&self, ppimmediatecontext: windows_core::OutRef<'_, ID3D11DeviceContext1>); + fn CreateDeferredContext1(&self, contextflags: u32, ppdeferredcontext: windows_core::OutRef<'_, ID3D11DeviceContext1>) -> windows_core::Result<()>; + fn CreateBlendState1(&self, pblendstatedesc: *const D3D11_BLEND_DESC1, ppblendstate: windows_core::OutRef<'_, ID3D11BlendState1>) -> windows_core::Result<()>; + fn CreateRasterizerState1(&self, prasterizerdesc: *const D3D11_RASTERIZER_DESC1, pprasterizerstate: windows_core::OutRef<'_, ID3D11RasterizerState1>) -> windows_core::Result<()>; + fn CreateDeviceContextState(&self, flags: u32, pfeaturelevels: *const super::Direct3D::D3D_FEATURE_LEVEL, featurelevels: u32, sdkversion: u32, emulatedinterface: *const windows_core::GUID, pchosenfeaturelevel: *mut super::Direct3D::D3D_FEATURE_LEVEL, ppcontextstate: windows_core::OutRef<'_, ID3DDeviceContextState>) -> windows_core::Result<()>; fn OpenSharedResource1(&self, hresource: super::super::Foundation::HANDLE, returnedinterface: *const windows_core::GUID, ppresource: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; fn OpenSharedResourceByName(&self, lpname: &windows_core::PCWSTR, dwdesiredaccess: u32, returnedinterface: *const windows_core::GUID, ppresource: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; } @@ -25280,6 +110645,31 @@ impl core::ops::Deref for ID3D11Device2 { } } windows_core::imp::interface_hierarchy!(ID3D11Device2, windows_core::IUnknown, ID3D11Device, ID3D11Device1); +impl ID3D11Device2 { + pub unsafe fn GetImmediateContext2(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetImmediateContext2)(windows_core::Interface::as_raw(self), &mut result__); + windows_core::Type::from_abi(result__) + } + } + pub unsafe fn CreateDeferredContext2(&self, contextflags: u32, ppdeferredcontext: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateDeferredContext2)(windows_core::Interface::as_raw(self), contextflags, ppdeferredcontext.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn GetResourceTiling(&self, ptiledresource: P0, pnumtilesforentireresource: Option<*mut u32>, ppackedmipdesc: Option<*mut D3D11_PACKED_MIP_DESC>, pstandardtileshapefornonpackedmips: Option<*mut D3D11_TILE_SHAPE>, pnumsubresourcetilings: Option<*mut u32>, firstsubresourcetilingtoget: u32, psubresourcetilingsfornonpackedmips: *mut D3D11_SUBRESOURCE_TILING) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).GetResourceTiling)(windows_core::Interface::as_raw(self), ptiledresource.param().abi(), pnumtilesforentireresource.unwrap_or(core::mem::zeroed()) as _, ppackedmipdesc.unwrap_or(core::mem::zeroed()) as _, pstandardtileshapefornonpackedmips.unwrap_or(core::mem::zeroed()) as _, pnumsubresourcetilings.unwrap_or(core::mem::zeroed()) as _, firstsubresourcetilingtoget, psubresourcetilingsfornonpackedmips as _) } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CheckMultisampleQualityLevels1(&self, format: super::Dxgi::Common::DXGI_FORMAT, samplecount: u32, flags: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CheckMultisampleQualityLevels1)(windows_core::Interface::as_raw(self), format, samplecount, flags, &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11Device2_Vtbl { @@ -25296,9 +110686,9 @@ unsafe impl Send for ID3D11Device2 {} unsafe impl Sync for ID3D11Device2 {} #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi_Common"))] pub trait ID3D11Device2_Impl: ID3D11Device1_Impl { - fn GetImmediateContext2(&self, ppimmediatecontext: windows_core::OutRef); - fn CreateDeferredContext2(&self, contextflags: u32, ppdeferredcontext: windows_core::OutRef) -> windows_core::Result<()>; - fn GetResourceTiling(&self, ptiledresource: windows_core::Ref, pnumtilesforentireresource: *mut u32, ppackedmipdesc: *mut D3D11_PACKED_MIP_DESC, pstandardtileshapefornonpackedmips: *mut D3D11_TILE_SHAPE, pnumsubresourcetilings: *mut u32, firstsubresourcetilingtoget: u32, psubresourcetilingsfornonpackedmips: *mut D3D11_SUBRESOURCE_TILING); + fn GetImmediateContext2(&self, ppimmediatecontext: windows_core::OutRef<'_, ID3D11DeviceContext2>); + fn CreateDeferredContext2(&self, contextflags: u32, ppdeferredcontext: windows_core::OutRef<'_, ID3D11DeviceContext2>) -> windows_core::Result<()>; + fn GetResourceTiling(&self, ptiledresource: windows_core::Ref<'_, ID3D11Resource>, pnumtilesforentireresource: *mut u32, ppackedmipdesc: *mut D3D11_PACKED_MIP_DESC, pstandardtileshapefornonpackedmips: *mut D3D11_TILE_SHAPE, pnumsubresourcetilings: *mut u32, firstsubresourcetilingtoget: u32, psubresourcetilingsfornonpackedmips: *mut D3D11_SUBRESOURCE_TILING); fn CheckMultisampleQualityLevels1(&self, format: super::Dxgi::Common::DXGI_FORMAT, samplecount: u32, flags: u32) -> windows_core::Result; } #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi_Common"))] @@ -25356,6 +110746,65 @@ impl core::ops::Deref for ID3D11Device3 { } } windows_core::imp::interface_hierarchy!(ID3D11Device3, windows_core::IUnknown, ID3D11Device, ID3D11Device1, ID3D11Device2); +impl ID3D11Device3 { + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CreateTexture2D1(&self, pdesc1: *const D3D11_TEXTURE2D_DESC1, pinitialdata: Option<*const D3D11_SUBRESOURCE_DATA>, pptexture2d: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateTexture2D1)(windows_core::Interface::as_raw(self), pdesc1, pinitialdata.unwrap_or(core::mem::zeroed()) as _, pptexture2d.unwrap_or(core::mem::zeroed()) as _).ok() } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CreateTexture3D1(&self, pdesc1: *const D3D11_TEXTURE3D_DESC1, pinitialdata: Option<*const D3D11_SUBRESOURCE_DATA>, pptexture3d: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateTexture3D1)(windows_core::Interface::as_raw(self), pdesc1, pinitialdata.unwrap_or(core::mem::zeroed()) as _, pptexture3d.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn CreateRasterizerState2(&self, prasterizerdesc: *const D3D11_RASTERIZER_DESC2, pprasterizerstate: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateRasterizerState2)(windows_core::Interface::as_raw(self), prasterizerdesc, pprasterizerstate.unwrap_or(core::mem::zeroed()) as _).ok() } + } + #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi_Common"))] + pub unsafe fn CreateShaderResourceView1(&self, presource: P0, pdesc1: Option<*const D3D11_SHADER_RESOURCE_VIEW_DESC1>, ppsrview1: Option<*mut Option>) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CreateShaderResourceView1)(windows_core::Interface::as_raw(self), presource.param().abi(), pdesc1.unwrap_or(core::mem::zeroed()) as _, ppsrview1.unwrap_or(core::mem::zeroed()) as _).ok() } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CreateUnorderedAccessView1(&self, presource: P0, pdesc1: Option<*const D3D11_UNORDERED_ACCESS_VIEW_DESC1>, ppuaview1: Option<*mut Option>) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CreateUnorderedAccessView1)(windows_core::Interface::as_raw(self), presource.param().abi(), pdesc1.unwrap_or(core::mem::zeroed()) as _, ppuaview1.unwrap_or(core::mem::zeroed()) as _).ok() } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CreateRenderTargetView1(&self, presource: P0, pdesc1: Option<*const D3D11_RENDER_TARGET_VIEW_DESC1>, pprtview1: Option<*mut Option>) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CreateRenderTargetView1)(windows_core::Interface::as_raw(self), presource.param().abi(), pdesc1.unwrap_or(core::mem::zeroed()) as _, pprtview1.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn CreateQuery1(&self, pquerydesc1: *const D3D11_QUERY_DESC1, ppquery1: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateQuery1)(windows_core::Interface::as_raw(self), pquerydesc1, ppquery1.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn GetImmediateContext3(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetImmediateContext3)(windows_core::Interface::as_raw(self), &mut result__); + windows_core::Type::from_abi(result__) + } + } + pub unsafe fn CreateDeferredContext3(&self, contextflags: u32, ppdeferredcontext: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateDeferredContext3)(windows_core::Interface::as_raw(self), contextflags, ppdeferredcontext.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn WriteToSubresource(&self, pdstresource: P0, dstsubresource: u32, pdstbox: Option<*const D3D11_BOX>, psrcdata: *const core::ffi::c_void, srcrowpitch: u32, srcdepthpitch: u32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).WriteToSubresource)(windows_core::Interface::as_raw(self), pdstresource.param().abi(), dstsubresource, pdstbox.unwrap_or(core::mem::zeroed()) as _, psrcdata, srcrowpitch, srcdepthpitch) } + } + pub unsafe fn ReadFromSubresource(&self, pdstdata: *mut core::ffi::c_void, dstrowpitch: u32, dstdepthpitch: u32, psrcresource: P3, srcsubresource: u32, psrcbox: Option<*const D3D11_BOX>) + where + P3: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).ReadFromSubresource)(windows_core::Interface::as_raw(self), pdstdata as _, dstrowpitch, dstdepthpitch, psrcresource.param().abi(), srcsubresource, psrcbox.unwrap_or(core::mem::zeroed()) as _) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11Device3_Vtbl { @@ -25391,17 +110840,17 @@ unsafe impl Send for ID3D11Device3 {} unsafe impl Sync for ID3D11Device3 {} #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi_Common"))] pub trait ID3D11Device3_Impl: ID3D11Device2_Impl { - fn CreateTexture2D1(&self, pdesc1: *const D3D11_TEXTURE2D_DESC1, pinitialdata: *const D3D11_SUBRESOURCE_DATA, pptexture2d: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateTexture3D1(&self, pdesc1: *const D3D11_TEXTURE3D_DESC1, pinitialdata: *const D3D11_SUBRESOURCE_DATA, pptexture3d: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateRasterizerState2(&self, prasterizerdesc: *const D3D11_RASTERIZER_DESC2, pprasterizerstate: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateShaderResourceView1(&self, presource: windows_core::Ref, pdesc1: *const D3D11_SHADER_RESOURCE_VIEW_DESC1, ppsrview1: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateUnorderedAccessView1(&self, presource: windows_core::Ref, pdesc1: *const D3D11_UNORDERED_ACCESS_VIEW_DESC1, ppuaview1: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateRenderTargetView1(&self, presource: windows_core::Ref, pdesc1: *const D3D11_RENDER_TARGET_VIEW_DESC1, pprtview1: windows_core::OutRef) -> windows_core::Result<()>; - fn CreateQuery1(&self, pquerydesc1: *const D3D11_QUERY_DESC1, ppquery1: windows_core::OutRef) -> windows_core::Result<()>; - fn GetImmediateContext3(&self, ppimmediatecontext: windows_core::OutRef); - fn CreateDeferredContext3(&self, contextflags: u32, ppdeferredcontext: windows_core::OutRef) -> windows_core::Result<()>; - fn WriteToSubresource(&self, pdstresource: windows_core::Ref, dstsubresource: u32, pdstbox: *const D3D11_BOX, psrcdata: *const core::ffi::c_void, srcrowpitch: u32, srcdepthpitch: u32); - fn ReadFromSubresource(&self, pdstdata: *mut core::ffi::c_void, dstrowpitch: u32, dstdepthpitch: u32, psrcresource: windows_core::Ref, srcsubresource: u32, psrcbox: *const D3D11_BOX); + fn CreateTexture2D1(&self, pdesc1: *const D3D11_TEXTURE2D_DESC1, pinitialdata: *const D3D11_SUBRESOURCE_DATA, pptexture2d: windows_core::OutRef<'_, ID3D11Texture2D1>) -> windows_core::Result<()>; + fn CreateTexture3D1(&self, pdesc1: *const D3D11_TEXTURE3D_DESC1, pinitialdata: *const D3D11_SUBRESOURCE_DATA, pptexture3d: windows_core::OutRef<'_, ID3D11Texture3D1>) -> windows_core::Result<()>; + fn CreateRasterizerState2(&self, prasterizerdesc: *const D3D11_RASTERIZER_DESC2, pprasterizerstate: windows_core::OutRef<'_, ID3D11RasterizerState2>) -> windows_core::Result<()>; + fn CreateShaderResourceView1(&self, presource: windows_core::Ref<'_, ID3D11Resource>, pdesc1: *const D3D11_SHADER_RESOURCE_VIEW_DESC1, ppsrview1: windows_core::OutRef<'_, ID3D11ShaderResourceView1>) -> windows_core::Result<()>; + fn CreateUnorderedAccessView1(&self, presource: windows_core::Ref<'_, ID3D11Resource>, pdesc1: *const D3D11_UNORDERED_ACCESS_VIEW_DESC1, ppuaview1: windows_core::OutRef<'_, ID3D11UnorderedAccessView1>) -> windows_core::Result<()>; + fn CreateRenderTargetView1(&self, presource: windows_core::Ref<'_, ID3D11Resource>, pdesc1: *const D3D11_RENDER_TARGET_VIEW_DESC1, pprtview1: windows_core::OutRef<'_, ID3D11RenderTargetView1>) -> windows_core::Result<()>; + fn CreateQuery1(&self, pquerydesc1: *const D3D11_QUERY_DESC1, ppquery1: windows_core::OutRef<'_, ID3D11Query1>) -> windows_core::Result<()>; + fn GetImmediateContext3(&self, ppimmediatecontext: windows_core::OutRef<'_, ID3D11DeviceContext3>); + fn CreateDeferredContext3(&self, contextflags: u32, ppdeferredcontext: windows_core::OutRef<'_, ID3D11DeviceContext3>) -> windows_core::Result<()>; + fn WriteToSubresource(&self, pdstresource: windows_core::Ref<'_, ID3D11Resource>, dstsubresource: u32, pdstbox: *const D3D11_BOX, psrcdata: *const core::ffi::c_void, srcrowpitch: u32, srcdepthpitch: u32); + fn ReadFromSubresource(&self, pdstdata: *mut core::ffi::c_void, dstrowpitch: u32, dstdepthpitch: u32, psrcresource: windows_core::Ref<'_, ID3D11Resource>, srcsubresource: u32, psrcbox: *const D3D11_BOX); } #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi_Common"))] impl ID3D11Device3_Vtbl { @@ -25501,6 +110950,17 @@ impl core::ops::Deref for ID3D11Device4 { } } windows_core::imp::interface_hierarchy!(ID3D11Device4, windows_core::IUnknown, ID3D11Device, ID3D11Device1, ID3D11Device2, ID3D11Device3); +impl ID3D11Device4 { + pub unsafe fn RegisterDeviceRemovedEvent(&self, hevent: super::super::Foundation::HANDLE) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).RegisterDeviceRemovedEvent)(windows_core::Interface::as_raw(self), hevent, &mut result__).map(|| result__) + } + } + pub unsafe fn UnregisterDeviceRemoved(&self, dwcookie: u32) { + unsafe { (windows_core::Interface::vtable(self).UnregisterDeviceRemoved)(windows_core::Interface::as_raw(self), dwcookie) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11Device4_Vtbl { @@ -25556,6 +111016,20 @@ impl core::ops::Deref for ID3D11Device5 { } } windows_core::imp::interface_hierarchy!(ID3D11Device5, windows_core::IUnknown, ID3D11Device, ID3D11Device1, ID3D11Device2, ID3D11Device3, ID3D11Device4); +impl ID3D11Device5 { + pub unsafe fn OpenSharedFence(&self, hfence: super::super::Foundation::HANDLE, result__: *mut Option) -> windows_core::Result<()> + where + T: windows_core::Interface, + { + unsafe { (windows_core::Interface::vtable(self).OpenSharedFence)(windows_core::Interface::as_raw(self), hfence, &T::IID, result__ as *mut _ as *mut _).ok() } + } + pub unsafe fn CreateFence(&self, initialvalue: u64, flags: D3D11_FENCE_FLAG, result__: *mut Option) -> windows_core::Result<()> + where + T: windows_core::Interface, + { + unsafe { (windows_core::Interface::vtable(self).CreateFence)(windows_core::Interface::as_raw(self), initialvalue, flags, &T::IID, result__ as *mut _ as *mut _).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11Device5_Vtbl { @@ -25599,6 +111073,27 @@ impl ID3D11Device5_Vtbl { impl windows_core::RuntimeName for ID3D11Device5 {} windows_core::imp::define_interface!(ID3D11DeviceChild, ID3D11DeviceChild_Vtbl, 0x1841e5c8_16b0_489b_bcc8_44cfb0d5deae); windows_core::imp::interface_hierarchy!(ID3D11DeviceChild, windows_core::IUnknown); +impl ID3D11DeviceChild { + pub unsafe fn GetDevice(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDevice)(windows_core::Interface::as_raw(self), &mut result__); + windows_core::Type::from_abi(result__) + } + } + pub unsafe fn GetPrivateData(&self, guid: *const windows_core::GUID, pdatasize: *mut u32, pdata: Option<*mut core::ffi::c_void>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetPrivateData)(windows_core::Interface::as_raw(self), guid, pdatasize as _, pdata.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn SetPrivateData(&self, guid: *const windows_core::GUID, datasize: u32, pdata: Option<*const core::ffi::c_void>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetPrivateData)(windows_core::Interface::as_raw(self), guid, datasize, pdata.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn SetPrivateDataInterface(&self, guid: *const windows_core::GUID, pdata: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetPrivateDataInterface)(windows_core::Interface::as_raw(self), guid, pdata.param().abi()).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11DeviceChild_Vtbl { @@ -25611,10 +111106,10 @@ pub struct ID3D11DeviceChild_Vtbl { unsafe impl Send for ID3D11DeviceChild {} unsafe impl Sync for ID3D11DeviceChild {} pub trait ID3D11DeviceChild_Impl: windows_core::IUnknownImpl { - fn GetDevice(&self, ppdevice: windows_core::OutRef); + fn GetDevice(&self, ppdevice: windows_core::OutRef<'_, ID3D11Device>); fn GetPrivateData(&self, guid: *const windows_core::GUID, pdatasize: *mut u32, pdata: *mut core::ffi::c_void) -> windows_core::Result<()>; fn SetPrivateData(&self, guid: *const windows_core::GUID, datasize: u32, pdata: *const core::ffi::c_void) -> windows_core::Result<()>; - fn SetPrivateDataInterface(&self, guid: *const windows_core::GUID, pdata: windows_core::Ref) -> windows_core::Result<()>; + fn SetPrivateDataInterface(&self, guid: *const windows_core::GUID, pdata: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; } impl ID3D11DeviceChild_Vtbl { pub const fn new() -> Self { @@ -25676,12 +111171,21 @@ impl ID3D11DeviceContext { { unsafe { (windows_core::Interface::vtable(self).PSSetShader)(windows_core::Interface::as_raw(self), ppixelshader.param().abi(), core::mem::transmute(ppclassinstances.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), ppclassinstances.as_deref().map_or(0, |slice| slice.len().try_into().unwrap())) } } + pub unsafe fn PSSetSamplers(&self, startslot: u32, ppsamplers: Option<&[Option]>) { + unsafe { (windows_core::Interface::vtable(self).PSSetSamplers)(windows_core::Interface::as_raw(self), startslot, ppsamplers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppsamplers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } pub unsafe fn VSSetShader(&self, pvertexshader: P0, ppclassinstances: Option<&[Option]>) where P0: windows_core::Param, { unsafe { (windows_core::Interface::vtable(self).VSSetShader)(windows_core::Interface::as_raw(self), pvertexshader.param().abi(), core::mem::transmute(ppclassinstances.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), ppclassinstances.as_deref().map_or(0, |slice| slice.len().try_into().unwrap())) } } + pub unsafe fn DrawIndexed(&self, indexcount: u32, startindexlocation: u32, basevertexlocation: i32) { + unsafe { (windows_core::Interface::vtable(self).DrawIndexed)(windows_core::Interface::as_raw(self), indexcount, startindexlocation, basevertexlocation) } + } + pub unsafe fn Draw(&self, vertexcount: u32, startvertexlocation: u32) { + unsafe { (windows_core::Interface::vtable(self).Draw)(windows_core::Interface::as_raw(self), vertexcount, startvertexlocation) } + } pub unsafe fn Map(&self, presource: P0, subresource: u32, maptype: D3D11_MAP, mapflags: u32, pmappedresource: Option<*mut D3D11_MAPPED_SUBRESOURCE>) -> windows_core::Result<()> where P0: windows_core::Param, @@ -25716,6 +111220,18 @@ impl ID3D11DeviceContext { pub unsafe fn DrawIndexedInstanced(&self, indexcountperinstance: u32, instancecount: u32, startindexlocation: u32, basevertexlocation: i32, startinstancelocation: u32) { unsafe { (windows_core::Interface::vtable(self).DrawIndexedInstanced)(windows_core::Interface::as_raw(self), indexcountperinstance, instancecount, startindexlocation, basevertexlocation, startinstancelocation) } } + pub unsafe fn DrawInstanced(&self, vertexcountperinstance: u32, instancecount: u32, startvertexlocation: u32, startinstancelocation: u32) { + unsafe { (windows_core::Interface::vtable(self).DrawInstanced)(windows_core::Interface::as_raw(self), vertexcountperinstance, instancecount, startvertexlocation, startinstancelocation) } + } + pub unsafe fn GSSetConstantBuffers(&self, startslot: u32, ppconstantbuffers: Option<&[Option]>) { + unsafe { (windows_core::Interface::vtable(self).GSSetConstantBuffers)(windows_core::Interface::as_raw(self), startslot, ppconstantbuffers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppconstantbuffers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn GSSetShader(&self, pshader: P0, ppclassinstances: Option<&[Option]>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).GSSetShader)(windows_core::Interface::as_raw(self), pshader.param().abi(), core::mem::transmute(ppclassinstances.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), ppclassinstances.as_deref().map_or(0, |slice| slice.len().try_into().unwrap())) } + } #[cfg(feature = "Win32_Graphics_Direct3D")] pub unsafe fn IASetPrimitiveTopology(&self, topology: super::Direct3D::D3D_PRIMITIVE_TOPOLOGY) { unsafe { (windows_core::Interface::vtable(self).IASetPrimitiveTopology)(windows_core::Interface::as_raw(self), topology) } @@ -25723,6 +111239,15 @@ impl ID3D11DeviceContext { pub unsafe fn VSSetShaderResources(&self, startslot: u32, ppshaderresourceviews: Option<&[Option]>) { unsafe { (windows_core::Interface::vtable(self).VSSetShaderResources)(windows_core::Interface::as_raw(self), startslot, ppshaderresourceviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppshaderresourceviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } } + pub unsafe fn VSSetSamplers(&self, startslot: u32, ppsamplers: Option<&[Option]>) { + unsafe { (windows_core::Interface::vtable(self).VSSetSamplers)(windows_core::Interface::as_raw(self), startslot, ppsamplers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppsamplers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn Begin(&self, pasync: P0) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).Begin)(windows_core::Interface::as_raw(self), pasync.param().abi()) } + } pub unsafe fn End(&self, pasync: P0) where P0: windows_core::Param, @@ -25735,12 +111260,30 @@ impl ID3D11DeviceContext { { unsafe { (windows_core::Interface::vtable(self).GetData)(windows_core::Interface::as_raw(self), pasync.param().abi(), pdata.unwrap_or(core::mem::zeroed()) as _, datasize, getdataflags).ok() } } + pub unsafe fn SetPredication(&self, ppredicate: P0, predicatevalue: bool) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetPredication)(windows_core::Interface::as_raw(self), ppredicate.param().abi(), predicatevalue.into()) } + } + pub unsafe fn GSSetShaderResources(&self, startslot: u32, ppshaderresourceviews: Option<&[Option]>) { + unsafe { (windows_core::Interface::vtable(self).GSSetShaderResources)(windows_core::Interface::as_raw(self), startslot, ppshaderresourceviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppshaderresourceviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn GSSetSamplers(&self, startslot: u32, ppsamplers: Option<&[Option]>) { + unsafe { (windows_core::Interface::vtable(self).GSSetSamplers)(windows_core::Interface::as_raw(self), startslot, ppsamplers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppsamplers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } pub unsafe fn OMSetRenderTargets(&self, pprendertargetviews: Option<&[Option]>, pdepthstencilview: P2) where P2: windows_core::Param, { unsafe { (windows_core::Interface::vtable(self).OMSetRenderTargets)(windows_core::Interface::as_raw(self), pprendertargetviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(pprendertargetviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), pdepthstencilview.param().abi()) } } + pub unsafe fn OMSetRenderTargetsAndUnorderedAccessViews(&self, pprendertargetviews: Option<&[Option]>, pdepthstencilview: P2, uavstartslot: u32, numuavs: u32, ppunorderedaccessviews: Option<*const Option>, puavinitialcounts: Option<*const u32>) + where + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).OMSetRenderTargetsAndUnorderedAccessViews)(windows_core::Interface::as_raw(self), pprendertargetviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(pprendertargetviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), pdepthstencilview.param().abi(), uavstartslot, numuavs, ppunorderedaccessviews.unwrap_or(core::mem::zeroed()) as _, puavinitialcounts.unwrap_or(core::mem::zeroed()) as _) } + } pub unsafe fn OMSetBlendState(&self, pblendstate: P0, blendfactor: Option<&[f32; 4]>, samplemask: u32) where P0: windows_core::Param, @@ -25753,6 +111296,33 @@ impl ID3D11DeviceContext { { unsafe { (windows_core::Interface::vtable(self).OMSetDepthStencilState)(windows_core::Interface::as_raw(self), pdepthstencilstate.param().abi(), stencilref) } } + pub unsafe fn SOSetTargets(&self, numbuffers: u32, ppsotargets: Option<*const Option>, poffsets: Option<*const u32>) { + unsafe { (windows_core::Interface::vtable(self).SOSetTargets)(windows_core::Interface::as_raw(self), numbuffers, ppsotargets.unwrap_or(core::mem::zeroed()) as _, poffsets.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn DrawAuto(&self) { + unsafe { (windows_core::Interface::vtable(self).DrawAuto)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn DrawIndexedInstancedIndirect(&self, pbufferforargs: P0, alignedbyteoffsetforargs: u32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DrawIndexedInstancedIndirect)(windows_core::Interface::as_raw(self), pbufferforargs.param().abi(), alignedbyteoffsetforargs) } + } + pub unsafe fn DrawInstancedIndirect(&self, pbufferforargs: P0, alignedbyteoffsetforargs: u32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DrawInstancedIndirect)(windows_core::Interface::as_raw(self), pbufferforargs.param().abi(), alignedbyteoffsetforargs) } + } + pub unsafe fn Dispatch(&self, threadgroupcountx: u32, threadgroupcounty: u32, threadgroupcountz: u32) { + unsafe { (windows_core::Interface::vtable(self).Dispatch)(windows_core::Interface::as_raw(self), threadgroupcountx, threadgroupcounty, threadgroupcountz) } + } + pub unsafe fn DispatchIndirect(&self, pbufferforargs: P0, alignedbyteoffsetforargs: u32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DispatchIndirect)(windows_core::Interface::as_raw(self), pbufferforargs.param().abi(), alignedbyteoffsetforargs) } + } pub unsafe fn RSSetState(&self, prasterizerstate: P0) where P0: windows_core::Param, @@ -25762,6 +111332,9 @@ impl ID3D11DeviceContext { pub unsafe fn RSSetViewports(&self, pviewports: Option<&[D3D11_VIEWPORT]>) { unsafe { (windows_core::Interface::vtable(self).RSSetViewports)(windows_core::Interface::as_raw(self), pviewports.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(pviewports.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } } + pub unsafe fn RSSetScissorRects(&self, prects: Option<&[super::super::Foundation::RECT]>) { + unsafe { (windows_core::Interface::vtable(self).RSSetScissorRects)(windows_core::Interface::as_raw(self), prects.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(prects.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } pub unsafe fn CopySubresourceRegion(&self, pdstresource: P0, dstsubresource: u32, dstx: u32, dsty: u32, dstz: u32, psrcresource: P5, srcsubresource: u32, psrcbox: Option<*const D3D11_BOX>) where P0: windows_core::Param, @@ -25769,28 +111342,284 @@ impl ID3D11DeviceContext { { unsafe { (windows_core::Interface::vtable(self).CopySubresourceRegion)(windows_core::Interface::as_raw(self), pdstresource.param().abi(), dstsubresource, dstx, dsty, dstz, psrcresource.param().abi(), srcsubresource, psrcbox.unwrap_or(core::mem::zeroed()) as _) } } + pub unsafe fn CopyResource(&self, pdstresource: P0, psrcresource: P1) + where + P0: windows_core::Param, + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CopyResource)(windows_core::Interface::as_raw(self), pdstresource.param().abi(), psrcresource.param().abi()) } + } pub unsafe fn UpdateSubresource(&self, pdstresource: P0, dstsubresource: u32, pdstbox: Option<*const D3D11_BOX>, psrcdata: *const core::ffi::c_void, srcrowpitch: u32, srcdepthpitch: u32) where P0: windows_core::Param, { unsafe { (windows_core::Interface::vtable(self).UpdateSubresource)(windows_core::Interface::as_raw(self), pdstresource.param().abi(), dstsubresource, pdstbox.unwrap_or(core::mem::zeroed()) as _, psrcdata, srcrowpitch, srcdepthpitch) } } + pub unsafe fn CopyStructureCount(&self, pdstbuffer: P0, dstalignedbyteoffset: u32, psrcview: P2) + where + P0: windows_core::Param, + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CopyStructureCount)(windows_core::Interface::as_raw(self), pdstbuffer.param().abi(), dstalignedbyteoffset, psrcview.param().abi()) } + } pub unsafe fn ClearRenderTargetView(&self, prendertargetview: P0, colorrgba: &[f32; 4]) where P0: windows_core::Param, { unsafe { (windows_core::Interface::vtable(self).ClearRenderTargetView)(windows_core::Interface::as_raw(self), prendertargetview.param().abi(), core::mem::transmute(colorrgba.as_ptr())) } } + pub unsafe fn ClearUnorderedAccessViewUint(&self, punorderedaccessview: P0, values: &[u32; 4]) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).ClearUnorderedAccessViewUint)(windows_core::Interface::as_raw(self), punorderedaccessview.param().abi(), core::mem::transmute(values.as_ptr())) } + } + pub unsafe fn ClearUnorderedAccessViewFloat(&self, punorderedaccessview: P0, values: &[f32; 4]) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).ClearUnorderedAccessViewFloat)(windows_core::Interface::as_raw(self), punorderedaccessview.param().abi(), core::mem::transmute(values.as_ptr())) } + } pub unsafe fn ClearDepthStencilView(&self, pdepthstencilview: P0, clearflags: u32, depth: f32, stencil: u8) where P0: windows_core::Param, { unsafe { (windows_core::Interface::vtable(self).ClearDepthStencilView)(windows_core::Interface::as_raw(self), pdepthstencilview.param().abi(), clearflags, depth, stencil) } } + pub unsafe fn GenerateMips(&self, pshaderresourceview: P0) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).GenerateMips)(windows_core::Interface::as_raw(self), pshaderresourceview.param().abi()) } + } + pub unsafe fn SetResourceMinLOD(&self, presource: P0, minlod: f32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetResourceMinLOD)(windows_core::Interface::as_raw(self), presource.param().abi(), minlod) } + } + pub unsafe fn GetResourceMinLOD(&self, presource: P0) -> f32 + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).GetResourceMinLOD)(windows_core::Interface::as_raw(self), presource.param().abi()) } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn ResolveSubresource(&self, pdstresource: P0, dstsubresource: u32, psrcresource: P2, srcsubresource: u32, format: super::Dxgi::Common::DXGI_FORMAT) + where + P0: windows_core::Param, + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).ResolveSubresource)(windows_core::Interface::as_raw(self), pdstresource.param().abi(), dstsubresource, psrcresource.param().abi(), srcsubresource, format) } + } + pub unsafe fn ExecuteCommandList(&self, pcommandlist: P0, restorecontextstate: bool) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).ExecuteCommandList)(windows_core::Interface::as_raw(self), pcommandlist.param().abi(), restorecontextstate.into()) } + } + pub unsafe fn HSSetShaderResources(&self, startslot: u32, ppshaderresourceviews: Option<&[Option]>) { + unsafe { (windows_core::Interface::vtable(self).HSSetShaderResources)(windows_core::Interface::as_raw(self), startslot, ppshaderresourceviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppshaderresourceviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn HSSetShader(&self, phullshader: P0, ppclassinstances: Option<&[Option]>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).HSSetShader)(windows_core::Interface::as_raw(self), phullshader.param().abi(), core::mem::transmute(ppclassinstances.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), ppclassinstances.as_deref().map_or(0, |slice| slice.len().try_into().unwrap())) } + } + pub unsafe fn HSSetSamplers(&self, startslot: u32, ppsamplers: Option<&[Option]>) { + unsafe { (windows_core::Interface::vtable(self).HSSetSamplers)(windows_core::Interface::as_raw(self), startslot, ppsamplers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppsamplers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn HSSetConstantBuffers(&self, startslot: u32, ppconstantbuffers: Option<&[Option]>) { + unsafe { (windows_core::Interface::vtable(self).HSSetConstantBuffers)(windows_core::Interface::as_raw(self), startslot, ppconstantbuffers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppconstantbuffers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn DSSetShaderResources(&self, startslot: u32, ppshaderresourceviews: Option<&[Option]>) { + unsafe { (windows_core::Interface::vtable(self).DSSetShaderResources)(windows_core::Interface::as_raw(self), startslot, ppshaderresourceviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppshaderresourceviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn DSSetShader(&self, pdomainshader: P0, ppclassinstances: Option<&[Option]>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DSSetShader)(windows_core::Interface::as_raw(self), pdomainshader.param().abi(), core::mem::transmute(ppclassinstances.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), ppclassinstances.as_deref().map_or(0, |slice| slice.len().try_into().unwrap())) } + } + pub unsafe fn DSSetSamplers(&self, startslot: u32, ppsamplers: Option<&[Option]>) { + unsafe { (windows_core::Interface::vtable(self).DSSetSamplers)(windows_core::Interface::as_raw(self), startslot, ppsamplers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppsamplers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn DSSetConstantBuffers(&self, startslot: u32, ppconstantbuffers: Option<&[Option]>) { + unsafe { (windows_core::Interface::vtable(self).DSSetConstantBuffers)(windows_core::Interface::as_raw(self), startslot, ppconstantbuffers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppconstantbuffers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn CSSetShaderResources(&self, startslot: u32, ppshaderresourceviews: Option<&[Option]>) { + unsafe { (windows_core::Interface::vtable(self).CSSetShaderResources)(windows_core::Interface::as_raw(self), startslot, ppshaderresourceviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppshaderresourceviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn CSSetUnorderedAccessViews(&self, startslot: u32, numuavs: u32, ppunorderedaccessviews: Option<*const Option>, puavinitialcounts: Option<*const u32>) { + unsafe { (windows_core::Interface::vtable(self).CSSetUnorderedAccessViews)(windows_core::Interface::as_raw(self), startslot, numuavs, ppunorderedaccessviews.unwrap_or(core::mem::zeroed()) as _, puavinitialcounts.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn CSSetShader(&self, pcomputeshader: P0, ppclassinstances: Option<&[Option]>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CSSetShader)(windows_core::Interface::as_raw(self), pcomputeshader.param().abi(), core::mem::transmute(ppclassinstances.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), ppclassinstances.as_deref().map_or(0, |slice| slice.len().try_into().unwrap())) } + } + pub unsafe fn CSSetSamplers(&self, startslot: u32, ppsamplers: Option<&[Option]>) { + unsafe { (windows_core::Interface::vtable(self).CSSetSamplers)(windows_core::Interface::as_raw(self), startslot, ppsamplers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppsamplers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn CSSetConstantBuffers(&self, startslot: u32, ppconstantbuffers: Option<&[Option]>) { + unsafe { (windows_core::Interface::vtable(self).CSSetConstantBuffers)(windows_core::Interface::as_raw(self), startslot, ppconstantbuffers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppconstantbuffers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn VSGetConstantBuffers(&self, startslot: u32, ppconstantbuffers: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).VSGetConstantBuffers)(windows_core::Interface::as_raw(self), startslot, ppconstantbuffers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppconstantbuffers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn PSGetShaderResources(&self, startslot: u32, ppshaderresourceviews: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).PSGetShaderResources)(windows_core::Interface::as_raw(self), startslot, ppshaderresourceviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppshaderresourceviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn PSGetShader(&self, pppixelshader: *mut Option, ppclassinstances: Option<*mut Option>, pnumclassinstances: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).PSGetShader)(windows_core::Interface::as_raw(self), core::mem::transmute(pppixelshader), ppclassinstances.unwrap_or(core::mem::zeroed()) as _, pnumclassinstances.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn PSGetSamplers(&self, startslot: u32, ppsamplers: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).PSGetSamplers)(windows_core::Interface::as_raw(self), startslot, ppsamplers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppsamplers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn VSGetShader(&self, ppvertexshader: *mut Option, ppclassinstances: Option<*mut Option>, pnumclassinstances: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).VSGetShader)(windows_core::Interface::as_raw(self), core::mem::transmute(ppvertexshader), ppclassinstances.unwrap_or(core::mem::zeroed()) as _, pnumclassinstances.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn PSGetConstantBuffers(&self, startslot: u32, ppconstantbuffers: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).PSGetConstantBuffers)(windows_core::Interface::as_raw(self), startslot, ppconstantbuffers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppconstantbuffers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn IAGetInputLayout(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).IAGetInputLayout)(windows_core::Interface::as_raw(self), &mut result__); + windows_core::Type::from_abi(result__) + } + } + pub unsafe fn IAGetVertexBuffers(&self, startslot: u32, numbuffers: u32, ppvertexbuffers: Option<*mut Option>, pstrides: Option<*mut u32>, poffsets: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).IAGetVertexBuffers)(windows_core::Interface::as_raw(self), startslot, numbuffers, ppvertexbuffers.unwrap_or(core::mem::zeroed()) as _, pstrides.unwrap_or(core::mem::zeroed()) as _, poffsets.unwrap_or(core::mem::zeroed()) as _) } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn IAGetIndexBuffer(&self, pindexbuffer: Option<*mut Option>, format: Option<*mut super::Dxgi::Common::DXGI_FORMAT>, offset: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).IAGetIndexBuffer)(windows_core::Interface::as_raw(self), pindexbuffer.unwrap_or(core::mem::zeroed()) as _, format.unwrap_or(core::mem::zeroed()) as _, offset.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn GSGetConstantBuffers(&self, startslot: u32, ppconstantbuffers: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).GSGetConstantBuffers)(windows_core::Interface::as_raw(self), startslot, ppconstantbuffers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppconstantbuffers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn GSGetShader(&self, ppgeometryshader: *mut Option, ppclassinstances: Option<*mut Option>, pnumclassinstances: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).GSGetShader)(windows_core::Interface::as_raw(self), core::mem::transmute(ppgeometryshader), ppclassinstances.unwrap_or(core::mem::zeroed()) as _, pnumclassinstances.unwrap_or(core::mem::zeroed()) as _) } + } + #[cfg(feature = "Win32_Graphics_Direct3D")] + pub unsafe fn IAGetPrimitiveTopology(&self) -> super::Direct3D::D3D_PRIMITIVE_TOPOLOGY { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).IAGetPrimitiveTopology)(windows_core::Interface::as_raw(self), &mut result__); + result__ + } + } + pub unsafe fn VSGetShaderResources(&self, startslot: u32, ppshaderresourceviews: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).VSGetShaderResources)(windows_core::Interface::as_raw(self), startslot, ppshaderresourceviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppshaderresourceviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn VSGetSamplers(&self, startslot: u32, ppsamplers: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).VSGetSamplers)(windows_core::Interface::as_raw(self), startslot, ppsamplers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppsamplers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn GetPredication(&self, pppredicate: Option<*mut Option>, ppredicatevalue: Option<*mut windows_core::BOOL>) { + unsafe { (windows_core::Interface::vtable(self).GetPredication)(windows_core::Interface::as_raw(self), pppredicate.unwrap_or(core::mem::zeroed()) as _, ppredicatevalue.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn GSGetShaderResources(&self, startslot: u32, ppshaderresourceviews: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).GSGetShaderResources)(windows_core::Interface::as_raw(self), startslot, ppshaderresourceviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppshaderresourceviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn GSGetSamplers(&self, startslot: u32, ppsamplers: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).GSGetSamplers)(windows_core::Interface::as_raw(self), startslot, ppsamplers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppsamplers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn OMGetRenderTargets(&self, pprendertargetviews: Option<&mut [Option]>, ppdepthstencilview: Option<*mut Option>) { + unsafe { (windows_core::Interface::vtable(self).OMGetRenderTargets)(windows_core::Interface::as_raw(self), pprendertargetviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(pprendertargetviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), ppdepthstencilview.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn OMGetRenderTargetsAndUnorderedAccessViews(&self, pprendertargetviews: Option<&mut [Option]>, ppdepthstencilview: Option<*mut Option>, uavstartslot: u32, ppunorderedaccessviews: Option<&mut [Option]>) { + unsafe { + (windows_core::Interface::vtable(self).OMGetRenderTargetsAndUnorderedAccessViews)( + windows_core::Interface::as_raw(self), + pprendertargetviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), + core::mem::transmute(pprendertargetviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), + ppdepthstencilview.unwrap_or(core::mem::zeroed()) as _, + uavstartslot, + ppunorderedaccessviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), + core::mem::transmute(ppunorderedaccessviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), + ) + } + } + pub unsafe fn OMGetBlendState(&self, ppblendstate: Option<*mut Option>, blendfactor: Option<&mut [f32; 4]>, psamplemask: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).OMGetBlendState)(windows_core::Interface::as_raw(self), ppblendstate.unwrap_or(core::mem::zeroed()) as _, core::mem::transmute(blendfactor.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), psamplemask.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn OMGetDepthStencilState(&self, ppdepthstencilstate: Option<*mut Option>, pstencilref: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).OMGetDepthStencilState)(windows_core::Interface::as_raw(self), ppdepthstencilstate.unwrap_or(core::mem::zeroed()) as _, pstencilref.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn SOGetTargets(&self, ppsotargets: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).SOGetTargets)(windows_core::Interface::as_raw(self), ppsotargets.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppsotargets.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn RSGetState(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).RSGetState)(windows_core::Interface::as_raw(self), &mut result__); + windows_core::Type::from_abi(result__) + } + } + pub unsafe fn RSGetViewports(&self, pnumviewports: *mut u32, pviewports: Option<*mut D3D11_VIEWPORT>) { + unsafe { (windows_core::Interface::vtable(self).RSGetViewports)(windows_core::Interface::as_raw(self), pnumviewports as _, pviewports.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn RSGetScissorRects(&self, pnumrects: *mut u32, prects: Option<*mut super::super::Foundation::RECT>) { + unsafe { (windows_core::Interface::vtable(self).RSGetScissorRects)(windows_core::Interface::as_raw(self), pnumrects as _, prects.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn HSGetShaderResources(&self, startslot: u32, ppshaderresourceviews: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).HSGetShaderResources)(windows_core::Interface::as_raw(self), startslot, ppshaderresourceviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppshaderresourceviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn HSGetShader(&self, pphullshader: *mut Option, ppclassinstances: Option<*mut Option>, pnumclassinstances: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).HSGetShader)(windows_core::Interface::as_raw(self), core::mem::transmute(pphullshader), ppclassinstances.unwrap_or(core::mem::zeroed()) as _, pnumclassinstances.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn HSGetSamplers(&self, startslot: u32, ppsamplers: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).HSGetSamplers)(windows_core::Interface::as_raw(self), startslot, ppsamplers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppsamplers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn HSGetConstantBuffers(&self, startslot: u32, ppconstantbuffers: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).HSGetConstantBuffers)(windows_core::Interface::as_raw(self), startslot, ppconstantbuffers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppconstantbuffers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn DSGetShaderResources(&self, startslot: u32, ppshaderresourceviews: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).DSGetShaderResources)(windows_core::Interface::as_raw(self), startslot, ppshaderresourceviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppshaderresourceviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn DSGetShader(&self, ppdomainshader: *mut Option, ppclassinstances: Option<*mut Option>, pnumclassinstances: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).DSGetShader)(windows_core::Interface::as_raw(self), core::mem::transmute(ppdomainshader), ppclassinstances.unwrap_or(core::mem::zeroed()) as _, pnumclassinstances.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn DSGetSamplers(&self, startslot: u32, ppsamplers: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).DSGetSamplers)(windows_core::Interface::as_raw(self), startslot, ppsamplers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppsamplers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn DSGetConstantBuffers(&self, startslot: u32, ppconstantbuffers: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).DSGetConstantBuffers)(windows_core::Interface::as_raw(self), startslot, ppconstantbuffers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppconstantbuffers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn CSGetShaderResources(&self, startslot: u32, ppshaderresourceviews: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).CSGetShaderResources)(windows_core::Interface::as_raw(self), startslot, ppshaderresourceviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppshaderresourceviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn CSGetUnorderedAccessViews(&self, startslot: u32, ppunorderedaccessviews: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).CSGetUnorderedAccessViews)(windows_core::Interface::as_raw(self), startslot, ppunorderedaccessviews.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppunorderedaccessviews.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn CSGetShader(&self, ppcomputeshader: *mut Option, ppclassinstances: Option<*mut Option>, pnumclassinstances: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).CSGetShader)(windows_core::Interface::as_raw(self), core::mem::transmute(ppcomputeshader), ppclassinstances.unwrap_or(core::mem::zeroed()) as _, pnumclassinstances.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn CSGetSamplers(&self, startslot: u32, ppsamplers: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).CSGetSamplers)(windows_core::Interface::as_raw(self), startslot, ppsamplers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppsamplers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn CSGetConstantBuffers(&self, startslot: u32, ppconstantbuffers: Option<&mut [Option]>) { + unsafe { (windows_core::Interface::vtable(self).CSGetConstantBuffers)(windows_core::Interface::as_raw(self), startslot, ppconstantbuffers.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(ppconstantbuffers.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + pub unsafe fn ClearState(&self) { + unsafe { (windows_core::Interface::vtable(self).ClearState)(windows_core::Interface::as_raw(self)) } + } pub unsafe fn Flush(&self) { unsafe { (windows_core::Interface::vtable(self).Flush)(windows_core::Interface::as_raw(self)) } } + pub unsafe fn GetType(&self) -> D3D11_DEVICE_CONTEXT_TYPE { + unsafe { (windows_core::Interface::vtable(self).GetType)(windows_core::Interface::as_raw(self)) } } + pub unsafe fn GetContextFlags(&self) -> u32 { + unsafe { (windows_core::Interface::vtable(self).GetContextFlags)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn FinishCommandList(&self, restoredeferredcontextstate: bool, ppcommandlist: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).FinishCommandList)(windows_core::Interface::as_raw(self), restoredeferredcontextstate.into(), ppcommandlist.unwrap_or(core::mem::zeroed()) as _).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11DeviceContext_Vtbl { @@ -25925,112 +111754,112 @@ unsafe impl Sync for ID3D11DeviceContext {} pub trait ID3D11DeviceContext_Impl: ID3D11DeviceChild_Impl { fn VSSetConstantBuffers(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *const Option); fn PSSetShaderResources(&self, startslot: u32, numviews: u32, ppshaderresourceviews: *const Option); - fn PSSetShader(&self, ppixelshader: windows_core::Ref, ppclassinstances: *const Option, numclassinstances: u32); + fn PSSetShader(&self, ppixelshader: windows_core::Ref<'_, ID3D11PixelShader>, ppclassinstances: *const Option, numclassinstances: u32); fn PSSetSamplers(&self, startslot: u32, numsamplers: u32, ppsamplers: *const Option); - fn VSSetShader(&self, pvertexshader: windows_core::Ref, ppclassinstances: *const Option, numclassinstances: u32); + fn VSSetShader(&self, pvertexshader: windows_core::Ref<'_, ID3D11VertexShader>, ppclassinstances: *const Option, numclassinstances: u32); fn DrawIndexed(&self, indexcount: u32, startindexlocation: u32, basevertexlocation: i32); fn Draw(&self, vertexcount: u32, startvertexlocation: u32); - fn Map(&self, presource: windows_core::Ref, subresource: u32, maptype: D3D11_MAP, mapflags: u32, pmappedresource: *mut D3D11_MAPPED_SUBRESOURCE) -> windows_core::Result<()>; - fn Unmap(&self, presource: windows_core::Ref, subresource: u32); + fn Map(&self, presource: windows_core::Ref<'_, ID3D11Resource>, subresource: u32, maptype: D3D11_MAP, mapflags: u32, pmappedresource: *mut D3D11_MAPPED_SUBRESOURCE) -> windows_core::Result<()>; + fn Unmap(&self, presource: windows_core::Ref<'_, ID3D11Resource>, subresource: u32); fn PSSetConstantBuffers(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *const Option); - fn IASetInputLayout(&self, pinputlayout: windows_core::Ref); + fn IASetInputLayout(&self, pinputlayout: windows_core::Ref<'_, ID3D11InputLayout>); fn IASetVertexBuffers(&self, startslot: u32, numbuffers: u32, ppvertexbuffers: *const Option, pstrides: *const u32, poffsets: *const u32); - fn IASetIndexBuffer(&self, pindexbuffer: windows_core::Ref, format: super::Dxgi::Common::DXGI_FORMAT, offset: u32); + fn IASetIndexBuffer(&self, pindexbuffer: windows_core::Ref<'_, ID3D11Buffer>, format: super::Dxgi::Common::DXGI_FORMAT, offset: u32); fn DrawIndexedInstanced(&self, indexcountperinstance: u32, instancecount: u32, startindexlocation: u32, basevertexlocation: i32, startinstancelocation: u32); fn DrawInstanced(&self, vertexcountperinstance: u32, instancecount: u32, startvertexlocation: u32, startinstancelocation: u32); fn GSSetConstantBuffers(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *const Option); - fn GSSetShader(&self, pshader: windows_core::Ref, ppclassinstances: *const Option, numclassinstances: u32); + fn GSSetShader(&self, pshader: windows_core::Ref<'_, ID3D11GeometryShader>, ppclassinstances: *const Option, numclassinstances: u32); fn IASetPrimitiveTopology(&self, topology: super::Direct3D::D3D_PRIMITIVE_TOPOLOGY); fn VSSetShaderResources(&self, startslot: u32, numviews: u32, ppshaderresourceviews: *const Option); fn VSSetSamplers(&self, startslot: u32, numsamplers: u32, ppsamplers: *const Option); - fn Begin(&self, pasync: windows_core::Ref); - fn End(&self, pasync: windows_core::Ref); - fn GetData(&self, pasync: windows_core::Ref, pdata: *mut core::ffi::c_void, datasize: u32, getdataflags: u32) -> windows_core::Result<()>; - fn SetPredication(&self, ppredicate: windows_core::Ref, predicatevalue: windows_core::BOOL); + fn Begin(&self, pasync: windows_core::Ref<'_, ID3D11Asynchronous>); + fn End(&self, pasync: windows_core::Ref<'_, ID3D11Asynchronous>); + fn GetData(&self, pasync: windows_core::Ref<'_, ID3D11Asynchronous>, pdata: *mut core::ffi::c_void, datasize: u32, getdataflags: u32) -> windows_core::Result<()>; + fn SetPredication(&self, ppredicate: windows_core::Ref<'_, ID3D11Predicate>, predicatevalue: windows_core::BOOL); fn GSSetShaderResources(&self, startslot: u32, numviews: u32, ppshaderresourceviews: *const Option); fn GSSetSamplers(&self, startslot: u32, numsamplers: u32, ppsamplers: *const Option); - fn OMSetRenderTargets(&self, numviews: u32, pprendertargetviews: *const Option, pdepthstencilview: windows_core::Ref); - fn OMSetRenderTargetsAndUnorderedAccessViews(&self, numrtvs: u32, pprendertargetviews: *const Option, pdepthstencilview: windows_core::Ref, uavstartslot: u32, numuavs: u32, ppunorderedaccessviews: *const Option, puavinitialcounts: *const u32); - fn OMSetBlendState(&self, pblendstate: windows_core::Ref, blendfactor: *const f32, samplemask: u32); - fn OMSetDepthStencilState(&self, pdepthstencilstate: windows_core::Ref, stencilref: u32); + fn OMSetRenderTargets(&self, numviews: u32, pprendertargetviews: *const Option, pdepthstencilview: windows_core::Ref<'_, ID3D11DepthStencilView>); + fn OMSetRenderTargetsAndUnorderedAccessViews(&self, numrtvs: u32, pprendertargetviews: *const Option, pdepthstencilview: windows_core::Ref<'_, ID3D11DepthStencilView>, uavstartslot: u32, numuavs: u32, ppunorderedaccessviews: *const Option, puavinitialcounts: *const u32); + fn OMSetBlendState(&self, pblendstate: windows_core::Ref<'_, ID3D11BlendState>, blendfactor: *const f32, samplemask: u32); + fn OMSetDepthStencilState(&self, pdepthstencilstate: windows_core::Ref<'_, ID3D11DepthStencilState>, stencilref: u32); fn SOSetTargets(&self, numbuffers: u32, ppsotargets: *const Option, poffsets: *const u32); fn DrawAuto(&self); - fn DrawIndexedInstancedIndirect(&self, pbufferforargs: windows_core::Ref, alignedbyteoffsetforargs: u32); - fn DrawInstancedIndirect(&self, pbufferforargs: windows_core::Ref, alignedbyteoffsetforargs: u32); + fn DrawIndexedInstancedIndirect(&self, pbufferforargs: windows_core::Ref<'_, ID3D11Buffer>, alignedbyteoffsetforargs: u32); + fn DrawInstancedIndirect(&self, pbufferforargs: windows_core::Ref<'_, ID3D11Buffer>, alignedbyteoffsetforargs: u32); fn Dispatch(&self, threadgroupcountx: u32, threadgroupcounty: u32, threadgroupcountz: u32); - fn DispatchIndirect(&self, pbufferforargs: windows_core::Ref, alignedbyteoffsetforargs: u32); - fn RSSetState(&self, prasterizerstate: windows_core::Ref); + fn DispatchIndirect(&self, pbufferforargs: windows_core::Ref<'_, ID3D11Buffer>, alignedbyteoffsetforargs: u32); + fn RSSetState(&self, prasterizerstate: windows_core::Ref<'_, ID3D11RasterizerState>); fn RSSetViewports(&self, numviewports: u32, pviewports: *const D3D11_VIEWPORT); fn RSSetScissorRects(&self, numrects: u32, prects: *const super::super::Foundation::RECT); - fn CopySubresourceRegion(&self, pdstresource: windows_core::Ref, dstsubresource: u32, dstx: u32, dsty: u32, dstz: u32, psrcresource: windows_core::Ref, srcsubresource: u32, psrcbox: *const D3D11_BOX); - fn CopyResource(&self, pdstresource: windows_core::Ref, psrcresource: windows_core::Ref); - fn UpdateSubresource(&self, pdstresource: windows_core::Ref, dstsubresource: u32, pdstbox: *const D3D11_BOX, psrcdata: *const core::ffi::c_void, srcrowpitch: u32, srcdepthpitch: u32); - fn CopyStructureCount(&self, pdstbuffer: windows_core::Ref, dstalignedbyteoffset: u32, psrcview: windows_core::Ref); - fn ClearRenderTargetView(&self, prendertargetview: windows_core::Ref, colorrgba: *const f32); - fn ClearUnorderedAccessViewUint(&self, punorderedaccessview: windows_core::Ref, values: *const u32); - fn ClearUnorderedAccessViewFloat(&self, punorderedaccessview: windows_core::Ref, values: *const f32); - fn ClearDepthStencilView(&self, pdepthstencilview: windows_core::Ref, clearflags: u32, depth: f32, stencil: u8); - fn GenerateMips(&self, pshaderresourceview: windows_core::Ref); - fn SetResourceMinLOD(&self, presource: windows_core::Ref, minlod: f32); - fn GetResourceMinLOD(&self, presource: windows_core::Ref) -> f32; - fn ResolveSubresource(&self, pdstresource: windows_core::Ref, dstsubresource: u32, psrcresource: windows_core::Ref, srcsubresource: u32, format: super::Dxgi::Common::DXGI_FORMAT); - fn ExecuteCommandList(&self, pcommandlist: windows_core::Ref, restorecontextstate: windows_core::BOOL); + fn CopySubresourceRegion(&self, pdstresource: windows_core::Ref<'_, ID3D11Resource>, dstsubresource: u32, dstx: u32, dsty: u32, dstz: u32, psrcresource: windows_core::Ref<'_, ID3D11Resource>, srcsubresource: u32, psrcbox: *const D3D11_BOX); + fn CopyResource(&self, pdstresource: windows_core::Ref<'_, ID3D11Resource>, psrcresource: windows_core::Ref<'_, ID3D11Resource>); + fn UpdateSubresource(&self, pdstresource: windows_core::Ref<'_, ID3D11Resource>, dstsubresource: u32, pdstbox: *const D3D11_BOX, psrcdata: *const core::ffi::c_void, srcrowpitch: u32, srcdepthpitch: u32); + fn CopyStructureCount(&self, pdstbuffer: windows_core::Ref<'_, ID3D11Buffer>, dstalignedbyteoffset: u32, psrcview: windows_core::Ref<'_, ID3D11UnorderedAccessView>); + fn ClearRenderTargetView(&self, prendertargetview: windows_core::Ref<'_, ID3D11RenderTargetView>, colorrgba: *const f32); + fn ClearUnorderedAccessViewUint(&self, punorderedaccessview: windows_core::Ref<'_, ID3D11UnorderedAccessView>, values: *const u32); + fn ClearUnorderedAccessViewFloat(&self, punorderedaccessview: windows_core::Ref<'_, ID3D11UnorderedAccessView>, values: *const f32); + fn ClearDepthStencilView(&self, pdepthstencilview: windows_core::Ref<'_, ID3D11DepthStencilView>, clearflags: u32, depth: f32, stencil: u8); + fn GenerateMips(&self, pshaderresourceview: windows_core::Ref<'_, ID3D11ShaderResourceView>); + fn SetResourceMinLOD(&self, presource: windows_core::Ref<'_, ID3D11Resource>, minlod: f32); + fn GetResourceMinLOD(&self, presource: windows_core::Ref<'_, ID3D11Resource>) -> f32; + fn ResolveSubresource(&self, pdstresource: windows_core::Ref<'_, ID3D11Resource>, dstsubresource: u32, psrcresource: windows_core::Ref<'_, ID3D11Resource>, srcsubresource: u32, format: super::Dxgi::Common::DXGI_FORMAT); + fn ExecuteCommandList(&self, pcommandlist: windows_core::Ref<'_, ID3D11CommandList>, restorecontextstate: windows_core::BOOL); fn HSSetShaderResources(&self, startslot: u32, numviews: u32, ppshaderresourceviews: *const Option); - fn HSSetShader(&self, phullshader: windows_core::Ref, ppclassinstances: *const Option, numclassinstances: u32); + fn HSSetShader(&self, phullshader: windows_core::Ref<'_, ID3D11HullShader>, ppclassinstances: *const Option, numclassinstances: u32); fn HSSetSamplers(&self, startslot: u32, numsamplers: u32, ppsamplers: *const Option); fn HSSetConstantBuffers(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *const Option); fn DSSetShaderResources(&self, startslot: u32, numviews: u32, ppshaderresourceviews: *const Option); - fn DSSetShader(&self, pdomainshader: windows_core::Ref, ppclassinstances: *const Option, numclassinstances: u32); + fn DSSetShader(&self, pdomainshader: windows_core::Ref<'_, ID3D11DomainShader>, ppclassinstances: *const Option, numclassinstances: u32); fn DSSetSamplers(&self, startslot: u32, numsamplers: u32, ppsamplers: *const Option); fn DSSetConstantBuffers(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *const Option); fn CSSetShaderResources(&self, startslot: u32, numviews: u32, ppshaderresourceviews: *const Option); fn CSSetUnorderedAccessViews(&self, startslot: u32, numuavs: u32, ppunorderedaccessviews: *const Option, puavinitialcounts: *const u32); - fn CSSetShader(&self, pcomputeshader: windows_core::Ref, ppclassinstances: *const Option, numclassinstances: u32); + fn CSSetShader(&self, pcomputeshader: windows_core::Ref<'_, ID3D11ComputeShader>, ppclassinstances: *const Option, numclassinstances: u32); fn CSSetSamplers(&self, startslot: u32, numsamplers: u32, ppsamplers: *const Option); fn CSSetConstantBuffers(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *const Option); fn VSGetConstantBuffers(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *mut Option); fn PSGetShaderResources(&self, startslot: u32, numviews: u32, ppshaderresourceviews: *mut Option); - fn PSGetShader(&self, pppixelshader: windows_core::OutRef, ppclassinstances: windows_core::OutRef, pnumclassinstances: *mut u32); + fn PSGetShader(&self, pppixelshader: windows_core::OutRef<'_, ID3D11PixelShader>, ppclassinstances: windows_core::OutRef<'_, ID3D11ClassInstance>, pnumclassinstances: *mut u32); fn PSGetSamplers(&self, startslot: u32, numsamplers: u32, ppsamplers: *mut Option); - fn VSGetShader(&self, ppvertexshader: windows_core::OutRef, ppclassinstances: windows_core::OutRef, pnumclassinstances: *mut u32); + fn VSGetShader(&self, ppvertexshader: windows_core::OutRef<'_, ID3D11VertexShader>, ppclassinstances: windows_core::OutRef<'_, ID3D11ClassInstance>, pnumclassinstances: *mut u32); fn PSGetConstantBuffers(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *mut Option); - fn IAGetInputLayout(&self, ppinputlayout: windows_core::OutRef); - fn IAGetVertexBuffers(&self, startslot: u32, numbuffers: u32, ppvertexbuffers: windows_core::OutRef, pstrides: *mut u32, poffsets: *mut u32); - fn IAGetIndexBuffer(&self, pindexbuffer: windows_core::OutRef, format: *mut super::Dxgi::Common::DXGI_FORMAT, offset: *mut u32); + fn IAGetInputLayout(&self, ppinputlayout: windows_core::OutRef<'_, ID3D11InputLayout>); + fn IAGetVertexBuffers(&self, startslot: u32, numbuffers: u32, ppvertexbuffers: windows_core::OutRef<'_, ID3D11Buffer>, pstrides: *mut u32, poffsets: *mut u32); + fn IAGetIndexBuffer(&self, pindexbuffer: windows_core::OutRef<'_, ID3D11Buffer>, format: *mut super::Dxgi::Common::DXGI_FORMAT, offset: *mut u32); fn GSGetConstantBuffers(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *mut Option); - fn GSGetShader(&self, ppgeometryshader: windows_core::OutRef, ppclassinstances: windows_core::OutRef, pnumclassinstances: *mut u32); + fn GSGetShader(&self, ppgeometryshader: windows_core::OutRef<'_, ID3D11GeometryShader>, ppclassinstances: windows_core::OutRef<'_, ID3D11ClassInstance>, pnumclassinstances: *mut u32); fn IAGetPrimitiveTopology(&self, ptopology: *mut super::Direct3D::D3D_PRIMITIVE_TOPOLOGY); fn VSGetShaderResources(&self, startslot: u32, numviews: u32, ppshaderresourceviews: *mut Option); fn VSGetSamplers(&self, startslot: u32, numsamplers: u32, ppsamplers: *mut Option); - fn GetPredication(&self, pppredicate: windows_core::OutRef, ppredicatevalue: *mut windows_core::BOOL); + fn GetPredication(&self, pppredicate: windows_core::OutRef<'_, ID3D11Predicate>, ppredicatevalue: *mut windows_core::BOOL); fn GSGetShaderResources(&self, startslot: u32, numviews: u32, ppshaderresourceviews: *mut Option); fn GSGetSamplers(&self, startslot: u32, numsamplers: u32, ppsamplers: *mut Option); - fn OMGetRenderTargets(&self, numviews: u32, pprendertargetviews: *mut Option, ppdepthstencilview: windows_core::OutRef); - fn OMGetRenderTargetsAndUnorderedAccessViews(&self, numrtvs: u32, pprendertargetviews: *mut Option, ppdepthstencilview: windows_core::OutRef, uavstartslot: u32, numuavs: u32, ppunorderedaccessviews: *mut Option); - fn OMGetBlendState(&self, ppblendstate: windows_core::OutRef, blendfactor: *mut f32, psamplemask: *mut u32); - fn OMGetDepthStencilState(&self, ppdepthstencilstate: windows_core::OutRef, pstencilref: *mut u32); + fn OMGetRenderTargets(&self, numviews: u32, pprendertargetviews: *mut Option, ppdepthstencilview: windows_core::OutRef<'_, ID3D11DepthStencilView>); + fn OMGetRenderTargetsAndUnorderedAccessViews(&self, numrtvs: u32, pprendertargetviews: *mut Option, ppdepthstencilview: windows_core::OutRef<'_, ID3D11DepthStencilView>, uavstartslot: u32, numuavs: u32, ppunorderedaccessviews: *mut Option); + fn OMGetBlendState(&self, ppblendstate: windows_core::OutRef<'_, ID3D11BlendState>, blendfactor: *mut f32, psamplemask: *mut u32); + fn OMGetDepthStencilState(&self, ppdepthstencilstate: windows_core::OutRef<'_, ID3D11DepthStencilState>, pstencilref: *mut u32); fn SOGetTargets(&self, numbuffers: u32, ppsotargets: *mut Option); - fn RSGetState(&self, pprasterizerstate: windows_core::OutRef); + fn RSGetState(&self, pprasterizerstate: windows_core::OutRef<'_, ID3D11RasterizerState>); fn RSGetViewports(&self, pnumviewports: *mut u32, pviewports: *mut D3D11_VIEWPORT); fn RSGetScissorRects(&self, pnumrects: *mut u32, prects: *mut super::super::Foundation::RECT); fn HSGetShaderResources(&self, startslot: u32, numviews: u32, ppshaderresourceviews: *mut Option); - fn HSGetShader(&self, pphullshader: windows_core::OutRef, ppclassinstances: windows_core::OutRef, pnumclassinstances: *mut u32); + fn HSGetShader(&self, pphullshader: windows_core::OutRef<'_, ID3D11HullShader>, ppclassinstances: windows_core::OutRef<'_, ID3D11ClassInstance>, pnumclassinstances: *mut u32); fn HSGetSamplers(&self, startslot: u32, numsamplers: u32, ppsamplers: *mut Option); fn HSGetConstantBuffers(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *mut Option); fn DSGetShaderResources(&self, startslot: u32, numviews: u32, ppshaderresourceviews: *mut Option); - fn DSGetShader(&self, ppdomainshader: windows_core::OutRef, ppclassinstances: windows_core::OutRef, pnumclassinstances: *mut u32); + fn DSGetShader(&self, ppdomainshader: windows_core::OutRef<'_, ID3D11DomainShader>, ppclassinstances: windows_core::OutRef<'_, ID3D11ClassInstance>, pnumclassinstances: *mut u32); fn DSGetSamplers(&self, startslot: u32, numsamplers: u32, ppsamplers: *mut Option); fn DSGetConstantBuffers(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *mut Option); fn CSGetShaderResources(&self, startslot: u32, numviews: u32, ppshaderresourceviews: *mut Option); fn CSGetUnorderedAccessViews(&self, startslot: u32, numuavs: u32, ppunorderedaccessviews: *mut Option); - fn CSGetShader(&self, ppcomputeshader: windows_core::OutRef, ppclassinstances: windows_core::OutRef, pnumclassinstances: *mut u32); + fn CSGetShader(&self, ppcomputeshader: windows_core::OutRef<'_, ID3D11ComputeShader>, ppclassinstances: windows_core::OutRef<'_, ID3D11ClassInstance>, pnumclassinstances: *mut u32); fn CSGetSamplers(&self, startslot: u32, numsamplers: u32, ppsamplers: *mut Option); fn CSGetConstantBuffers(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *mut Option); fn ClearState(&self); fn Flush(&self); fn GetType(&self) -> D3D11_DEVICE_CONTEXT_TYPE; fn GetContextFlags(&self) -> u32; - fn FinishCommandList(&self, restoredeferredcontextstate: windows_core::BOOL, ppcommandlist: windows_core::OutRef) -> windows_core::Result<()>; + fn FinishCommandList(&self, restoredeferredcontextstate: windows_core::BOOL, ppcommandlist: windows_core::OutRef<'_, ID3D11CommandList>) -> windows_core::Result<()>; } #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi_Common"))] impl ID3D11DeviceContext_Vtbl { @@ -26809,6 +112638,87 @@ impl core::ops::Deref for ID3D11DeviceContext1 { } } windows_core::imp::interface_hierarchy!(ID3D11DeviceContext1, windows_core::IUnknown, ID3D11DeviceChild, ID3D11DeviceContext); +impl ID3D11DeviceContext1 { + pub unsafe fn CopySubresourceRegion1(&self, pdstresource: P0, dstsubresource: u32, dstx: u32, dsty: u32, dstz: u32, psrcresource: P5, srcsubresource: u32, psrcbox: Option<*const D3D11_BOX>, copyflags: u32) + where + P0: windows_core::Param, + P5: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CopySubresourceRegion1)(windows_core::Interface::as_raw(self), pdstresource.param().abi(), dstsubresource, dstx, dsty, dstz, psrcresource.param().abi(), srcsubresource, psrcbox.unwrap_or(core::mem::zeroed()) as _, copyflags) } + } + pub unsafe fn UpdateSubresource1(&self, pdstresource: P0, dstsubresource: u32, pdstbox: Option<*const D3D11_BOX>, psrcdata: *const core::ffi::c_void, srcrowpitch: u32, srcdepthpitch: u32, copyflags: u32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).UpdateSubresource1)(windows_core::Interface::as_raw(self), pdstresource.param().abi(), dstsubresource, pdstbox.unwrap_or(core::mem::zeroed()) as _, psrcdata, srcrowpitch, srcdepthpitch, copyflags) } + } + pub unsafe fn DiscardResource(&self, presource: P0) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DiscardResource)(windows_core::Interface::as_raw(self), presource.param().abi()) } + } + pub unsafe fn DiscardView(&self, presourceview: P0) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DiscardView)(windows_core::Interface::as_raw(self), presourceview.param().abi()) } + } + pub unsafe fn VSSetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: Option<*const Option>, pfirstconstant: Option<*const u32>, pnumconstants: Option<*const u32>) { + unsafe { (windows_core::Interface::vtable(self).VSSetConstantBuffers1)(windows_core::Interface::as_raw(self), startslot, numbuffers, ppconstantbuffers.unwrap_or(core::mem::zeroed()) as _, pfirstconstant.unwrap_or(core::mem::zeroed()) as _, pnumconstants.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn HSSetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: Option<*const Option>, pfirstconstant: Option<*const u32>, pnumconstants: Option<*const u32>) { + unsafe { (windows_core::Interface::vtable(self).HSSetConstantBuffers1)(windows_core::Interface::as_raw(self), startslot, numbuffers, ppconstantbuffers.unwrap_or(core::mem::zeroed()) as _, pfirstconstant.unwrap_or(core::mem::zeroed()) as _, pnumconstants.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn DSSetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: Option<*const Option>, pfirstconstant: Option<*const u32>, pnumconstants: Option<*const u32>) { + unsafe { (windows_core::Interface::vtable(self).DSSetConstantBuffers1)(windows_core::Interface::as_raw(self), startslot, numbuffers, ppconstantbuffers.unwrap_or(core::mem::zeroed()) as _, pfirstconstant.unwrap_or(core::mem::zeroed()) as _, pnumconstants.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn GSSetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: Option<*const Option>, pfirstconstant: Option<*const u32>, pnumconstants: Option<*const u32>) { + unsafe { (windows_core::Interface::vtable(self).GSSetConstantBuffers1)(windows_core::Interface::as_raw(self), startslot, numbuffers, ppconstantbuffers.unwrap_or(core::mem::zeroed()) as _, pfirstconstant.unwrap_or(core::mem::zeroed()) as _, pnumconstants.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn PSSetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: Option<*const Option>, pfirstconstant: Option<*const u32>, pnumconstants: Option<*const u32>) { + unsafe { (windows_core::Interface::vtable(self).PSSetConstantBuffers1)(windows_core::Interface::as_raw(self), startslot, numbuffers, ppconstantbuffers.unwrap_or(core::mem::zeroed()) as _, pfirstconstant.unwrap_or(core::mem::zeroed()) as _, pnumconstants.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn CSSetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: Option<*const Option>, pfirstconstant: Option<*const u32>, pnumconstants: Option<*const u32>) { + unsafe { (windows_core::Interface::vtable(self).CSSetConstantBuffers1)(windows_core::Interface::as_raw(self), startslot, numbuffers, ppconstantbuffers.unwrap_or(core::mem::zeroed()) as _, pfirstconstant.unwrap_or(core::mem::zeroed()) as _, pnumconstants.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn VSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: Option<*mut Option>, pfirstconstant: Option<*mut u32>, pnumconstants: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).VSGetConstantBuffers1)(windows_core::Interface::as_raw(self), startslot, numbuffers, ppconstantbuffers.unwrap_or(core::mem::zeroed()) as _, pfirstconstant.unwrap_or(core::mem::zeroed()) as _, pnumconstants.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn HSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: Option<*mut Option>, pfirstconstant: Option<*mut u32>, pnumconstants: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).HSGetConstantBuffers1)(windows_core::Interface::as_raw(self), startslot, numbuffers, ppconstantbuffers.unwrap_or(core::mem::zeroed()) as _, pfirstconstant.unwrap_or(core::mem::zeroed()) as _, pnumconstants.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn DSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: Option<*mut Option>, pfirstconstant: Option<*mut u32>, pnumconstants: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).DSGetConstantBuffers1)(windows_core::Interface::as_raw(self), startslot, numbuffers, ppconstantbuffers.unwrap_or(core::mem::zeroed()) as _, pfirstconstant.unwrap_or(core::mem::zeroed()) as _, pnumconstants.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn GSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: Option<*mut Option>, pfirstconstant: Option<*mut u32>, pnumconstants: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).GSGetConstantBuffers1)(windows_core::Interface::as_raw(self), startslot, numbuffers, ppconstantbuffers.unwrap_or(core::mem::zeroed()) as _, pfirstconstant.unwrap_or(core::mem::zeroed()) as _, pnumconstants.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn PSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: Option<*mut Option>, pfirstconstant: Option<*mut u32>, pnumconstants: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).PSGetConstantBuffers1)(windows_core::Interface::as_raw(self), startslot, numbuffers, ppconstantbuffers.unwrap_or(core::mem::zeroed()) as _, pfirstconstant.unwrap_or(core::mem::zeroed()) as _, pnumconstants.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn CSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: Option<*mut Option>, pfirstconstant: Option<*mut u32>, pnumconstants: Option<*mut u32>) { + unsafe { (windows_core::Interface::vtable(self).CSGetConstantBuffers1)(windows_core::Interface::as_raw(self), startslot, numbuffers, ppconstantbuffers.unwrap_or(core::mem::zeroed()) as _, pfirstconstant.unwrap_or(core::mem::zeroed()) as _, pnumconstants.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn SwapDeviceContextState(&self, pstate: P0, pppreviousstate: Option<*mut Option>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SwapDeviceContextState)(windows_core::Interface::as_raw(self), pstate.param().abi(), pppreviousstate.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn ClearView(&self, pview: P0, color: &[f32; 4], prect: Option<&[super::super::Foundation::RECT]>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).ClearView)(windows_core::Interface::as_raw(self), pview.param().abi(), core::mem::transmute(color.as_ptr()), core::mem::transmute(prect.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), prect.as_deref().map_or(0, |slice| slice.len().try_into().unwrap())) } + } + pub unsafe fn DiscardView1(&self, presourceview: P0, prects: Option<&[super::super::Foundation::RECT]>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DiscardView1)(windows_core::Interface::as_raw(self), presourceview.param().abi(), core::mem::transmute(prects.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), prects.as_deref().map_or(0, |slice| slice.len().try_into().unwrap())) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11DeviceContext1_Vtbl { @@ -26837,25 +112747,25 @@ unsafe impl Send for ID3D11DeviceContext1 {} unsafe impl Sync for ID3D11DeviceContext1 {} #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi_Common"))] pub trait ID3D11DeviceContext1_Impl: ID3D11DeviceContext_Impl { - fn CopySubresourceRegion1(&self, pdstresource: windows_core::Ref, dstsubresource: u32, dstx: u32, dsty: u32, dstz: u32, psrcresource: windows_core::Ref, srcsubresource: u32, psrcbox: *const D3D11_BOX, copyflags: u32); - fn UpdateSubresource1(&self, pdstresource: windows_core::Ref, dstsubresource: u32, pdstbox: *const D3D11_BOX, psrcdata: *const core::ffi::c_void, srcrowpitch: u32, srcdepthpitch: u32, copyflags: u32); - fn DiscardResource(&self, presource: windows_core::Ref); - fn DiscardView(&self, presourceview: windows_core::Ref); + fn CopySubresourceRegion1(&self, pdstresource: windows_core::Ref<'_, ID3D11Resource>, dstsubresource: u32, dstx: u32, dsty: u32, dstz: u32, psrcresource: windows_core::Ref<'_, ID3D11Resource>, srcsubresource: u32, psrcbox: *const D3D11_BOX, copyflags: u32); + fn UpdateSubresource1(&self, pdstresource: windows_core::Ref<'_, ID3D11Resource>, dstsubresource: u32, pdstbox: *const D3D11_BOX, psrcdata: *const core::ffi::c_void, srcrowpitch: u32, srcdepthpitch: u32, copyflags: u32); + fn DiscardResource(&self, presource: windows_core::Ref<'_, ID3D11Resource>); + fn DiscardView(&self, presourceview: windows_core::Ref<'_, ID3D11View>); fn VSSetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *const Option, pfirstconstant: *const u32, pnumconstants: *const u32); fn HSSetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *const Option, pfirstconstant: *const u32, pnumconstants: *const u32); fn DSSetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *const Option, pfirstconstant: *const u32, pnumconstants: *const u32); fn GSSetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *const Option, pfirstconstant: *const u32, pnumconstants: *const u32); fn PSSetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *const Option, pfirstconstant: *const u32, pnumconstants: *const u32); fn CSSetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: *const Option, pfirstconstant: *const u32, pnumconstants: *const u32); - fn VSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: windows_core::OutRef, pfirstconstant: *mut u32, pnumconstants: *mut u32); - fn HSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: windows_core::OutRef, pfirstconstant: *mut u32, pnumconstants: *mut u32); - fn DSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: windows_core::OutRef, pfirstconstant: *mut u32, pnumconstants: *mut u32); - fn GSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: windows_core::OutRef, pfirstconstant: *mut u32, pnumconstants: *mut u32); - fn PSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: windows_core::OutRef, pfirstconstant: *mut u32, pnumconstants: *mut u32); - fn CSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: windows_core::OutRef, pfirstconstant: *mut u32, pnumconstants: *mut u32); - fn SwapDeviceContextState(&self, pstate: windows_core::Ref, pppreviousstate: windows_core::OutRef); - fn ClearView(&self, pview: windows_core::Ref, color: *const f32, prect: *const super::super::Foundation::RECT, numrects: u32); - fn DiscardView1(&self, presourceview: windows_core::Ref, prects: *const super::super::Foundation::RECT, numrects: u32); + fn VSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: windows_core::OutRef<'_, ID3D11Buffer>, pfirstconstant: *mut u32, pnumconstants: *mut u32); + fn HSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: windows_core::OutRef<'_, ID3D11Buffer>, pfirstconstant: *mut u32, pnumconstants: *mut u32); + fn DSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: windows_core::OutRef<'_, ID3D11Buffer>, pfirstconstant: *mut u32, pnumconstants: *mut u32); + fn GSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: windows_core::OutRef<'_, ID3D11Buffer>, pfirstconstant: *mut u32, pnumconstants: *mut u32); + fn PSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: windows_core::OutRef<'_, ID3D11Buffer>, pfirstconstant: *mut u32, pnumconstants: *mut u32); + fn CSGetConstantBuffers1(&self, startslot: u32, numbuffers: u32, ppconstantbuffers: windows_core::OutRef<'_, ID3D11Buffer>, pfirstconstant: *mut u32, pnumconstants: *mut u32); + fn SwapDeviceContextState(&self, pstate: windows_core::Ref<'_, ID3DDeviceContextState>, pppreviousstate: windows_core::OutRef<'_, ID3DDeviceContextState>); + fn ClearView(&self, pview: windows_core::Ref<'_, ID3D11View>, color: *const f32, prect: *const super::super::Foundation::RECT, numrects: u32); + fn DiscardView1(&self, presourceview: windows_core::Ref<'_, ID3D11View>, prects: *const super::super::Foundation::RECT, numrects: u32); } #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi_Common"))] impl ID3D11DeviceContext1_Vtbl { @@ -27011,6 +112921,66 @@ impl core::ops::Deref for ID3D11DeviceContext2 { } } windows_core::imp::interface_hierarchy!(ID3D11DeviceContext2, windows_core::IUnknown, ID3D11DeviceChild, ID3D11DeviceContext, ID3D11DeviceContext1); +impl ID3D11DeviceContext2 { + pub unsafe fn UpdateTileMappings(&self, ptiledresource: P0, numtiledresourceregions: u32, ptiledresourceregionstartcoordinates: Option<*const D3D11_TILED_RESOURCE_COORDINATE>, ptiledresourceregionsizes: Option<*const D3D11_TILE_REGION_SIZE>, ptilepool: P4, numranges: u32, prangeflags: Option<*const u32>, ptilepoolstartoffsets: Option<*const u32>, prangetilecounts: Option<*const u32>, flags: u32) -> windows_core::Result<()> + where + P0: windows_core::Param, + P4: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).UpdateTileMappings)(windows_core::Interface::as_raw(self), ptiledresource.param().abi(), numtiledresourceregions, ptiledresourceregionstartcoordinates.unwrap_or(core::mem::zeroed()) as _, ptiledresourceregionsizes.unwrap_or(core::mem::zeroed()) as _, ptilepool.param().abi(), numranges, prangeflags.unwrap_or(core::mem::zeroed()) as _, ptilepoolstartoffsets.unwrap_or(core::mem::zeroed()) as _, prangetilecounts.unwrap_or(core::mem::zeroed()) as _, flags).ok() } + } + pub unsafe fn CopyTileMappings(&self, pdesttiledresource: P0, pdestregionstartcoordinate: *const D3D11_TILED_RESOURCE_COORDINATE, psourcetiledresource: P2, psourceregionstartcoordinate: *const D3D11_TILED_RESOURCE_COORDINATE, ptileregionsize: *const D3D11_TILE_REGION_SIZE, flags: u32) -> windows_core::Result<()> + where + P0: windows_core::Param, + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CopyTileMappings)(windows_core::Interface::as_raw(self), pdesttiledresource.param().abi(), pdestregionstartcoordinate, psourcetiledresource.param().abi(), psourceregionstartcoordinate, ptileregionsize, flags).ok() } + } + pub unsafe fn CopyTiles(&self, ptiledresource: P0, ptileregionstartcoordinate: *const D3D11_TILED_RESOURCE_COORDINATE, ptileregionsize: *const D3D11_TILE_REGION_SIZE, pbuffer: P3, bufferstartoffsetinbytes: u64, flags: u32) + where + P0: windows_core::Param, + P3: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CopyTiles)(windows_core::Interface::as_raw(self), ptiledresource.param().abi(), ptileregionstartcoordinate, ptileregionsize, pbuffer.param().abi(), bufferstartoffsetinbytes, flags) } + } + pub unsafe fn UpdateTiles(&self, pdesttiledresource: P0, pdesttileregionstartcoordinate: *const D3D11_TILED_RESOURCE_COORDINATE, pdesttileregionsize: *const D3D11_TILE_REGION_SIZE, psourcetiledata: *const core::ffi::c_void, flags: u32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).UpdateTiles)(windows_core::Interface::as_raw(self), pdesttiledresource.param().abi(), pdesttileregionstartcoordinate, pdesttileregionsize, psourcetiledata, flags) } + } + pub unsafe fn ResizeTilePool(&self, ptilepool: P0, newsizeinbytes: u64) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).ResizeTilePool)(windows_core::Interface::as_raw(self), ptilepool.param().abi(), newsizeinbytes).ok() } + } + pub unsafe fn TiledResourceBarrier(&self, ptiledresourceorviewaccessbeforebarrier: P0, ptiledresourceorviewaccessafterbarrier: P1) + where + P0: windows_core::Param, + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).TiledResourceBarrier)(windows_core::Interface::as_raw(self), ptiledresourceorviewaccessbeforebarrier.param().abi(), ptiledresourceorviewaccessafterbarrier.param().abi()) } + } + pub unsafe fn IsAnnotationEnabled(&self) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).IsAnnotationEnabled)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn SetMarkerInt(&self, plabel: P0, data: i32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetMarkerInt)(windows_core::Interface::as_raw(self), plabel.param().abi(), data) } + } + pub unsafe fn BeginEventInt(&self, plabel: P0, data: i32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).BeginEventInt)(windows_core::Interface::as_raw(self), plabel.param().abi(), data) } + } + pub unsafe fn EndEvent(&self) { + unsafe { (windows_core::Interface::vtable(self).EndEvent)(windows_core::Interface::as_raw(self)) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11DeviceContext2_Vtbl { @@ -27030,12 +113000,12 @@ unsafe impl Send for ID3D11DeviceContext2 {} unsafe impl Sync for ID3D11DeviceContext2 {} #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi_Common"))] pub trait ID3D11DeviceContext2_Impl: ID3D11DeviceContext1_Impl { - fn UpdateTileMappings(&self, ptiledresource: windows_core::Ref, numtiledresourceregions: u32, ptiledresourceregionstartcoordinates: *const D3D11_TILED_RESOURCE_COORDINATE, ptiledresourceregionsizes: *const D3D11_TILE_REGION_SIZE, ptilepool: windows_core::Ref, numranges: u32, prangeflags: *const u32, ptilepoolstartoffsets: *const u32, prangetilecounts: *const u32, flags: u32) -> windows_core::Result<()>; - fn CopyTileMappings(&self, pdesttiledresource: windows_core::Ref, pdestregionstartcoordinate: *const D3D11_TILED_RESOURCE_COORDINATE, psourcetiledresource: windows_core::Ref, psourceregionstartcoordinate: *const D3D11_TILED_RESOURCE_COORDINATE, ptileregionsize: *const D3D11_TILE_REGION_SIZE, flags: u32) -> windows_core::Result<()>; - fn CopyTiles(&self, ptiledresource: windows_core::Ref, ptileregionstartcoordinate: *const D3D11_TILED_RESOURCE_COORDINATE, ptileregionsize: *const D3D11_TILE_REGION_SIZE, pbuffer: windows_core::Ref, bufferstartoffsetinbytes: u64, flags: u32); - fn UpdateTiles(&self, pdesttiledresource: windows_core::Ref, pdesttileregionstartcoordinate: *const D3D11_TILED_RESOURCE_COORDINATE, pdesttileregionsize: *const D3D11_TILE_REGION_SIZE, psourcetiledata: *const core::ffi::c_void, flags: u32); - fn ResizeTilePool(&self, ptilepool: windows_core::Ref, newsizeinbytes: u64) -> windows_core::Result<()>; - fn TiledResourceBarrier(&self, ptiledresourceorviewaccessbeforebarrier: windows_core::Ref, ptiledresourceorviewaccessafterbarrier: windows_core::Ref); + fn UpdateTileMappings(&self, ptiledresource: windows_core::Ref<'_, ID3D11Resource>, numtiledresourceregions: u32, ptiledresourceregionstartcoordinates: *const D3D11_TILED_RESOURCE_COORDINATE, ptiledresourceregionsizes: *const D3D11_TILE_REGION_SIZE, ptilepool: windows_core::Ref<'_, ID3D11Buffer>, numranges: u32, prangeflags: *const u32, ptilepoolstartoffsets: *const u32, prangetilecounts: *const u32, flags: u32) -> windows_core::Result<()>; + fn CopyTileMappings(&self, pdesttiledresource: windows_core::Ref<'_, ID3D11Resource>, pdestregionstartcoordinate: *const D3D11_TILED_RESOURCE_COORDINATE, psourcetiledresource: windows_core::Ref<'_, ID3D11Resource>, psourceregionstartcoordinate: *const D3D11_TILED_RESOURCE_COORDINATE, ptileregionsize: *const D3D11_TILE_REGION_SIZE, flags: u32) -> windows_core::Result<()>; + fn CopyTiles(&self, ptiledresource: windows_core::Ref<'_, ID3D11Resource>, ptileregionstartcoordinate: *const D3D11_TILED_RESOURCE_COORDINATE, ptileregionsize: *const D3D11_TILE_REGION_SIZE, pbuffer: windows_core::Ref<'_, ID3D11Buffer>, bufferstartoffsetinbytes: u64, flags: u32); + fn UpdateTiles(&self, pdesttiledresource: windows_core::Ref<'_, ID3D11Resource>, pdesttileregionstartcoordinate: *const D3D11_TILED_RESOURCE_COORDINATE, pdesttileregionsize: *const D3D11_TILE_REGION_SIZE, psourcetiledata: *const core::ffi::c_void, flags: u32); + fn ResizeTilePool(&self, ptilepool: windows_core::Ref<'_, ID3D11Buffer>, newsizeinbytes: u64) -> windows_core::Result<()>; + fn TiledResourceBarrier(&self, ptiledresourceorviewaccessbeforebarrier: windows_core::Ref<'_, ID3D11DeviceChild>, ptiledresourceorviewaccessafterbarrier: windows_core::Ref<'_, ID3D11DeviceChild>); fn IsAnnotationEnabled(&self) -> windows_core::BOOL; fn SetMarkerInt(&self, plabel: &windows_core::PCWSTR, data: i32); fn BeginEventInt(&self, plabel: &windows_core::PCWSTR, data: i32); @@ -27132,6 +113102,21 @@ impl core::ops::Deref for ID3D11DeviceContext3 { } } windows_core::imp::interface_hierarchy!(ID3D11DeviceContext3, windows_core::IUnknown, ID3D11DeviceChild, ID3D11DeviceContext, ID3D11DeviceContext1, ID3D11DeviceContext2); +impl ID3D11DeviceContext3 { + pub unsafe fn Flush1(&self, contexttype: D3D11_CONTEXT_TYPE, hevent: Option) { + unsafe { (windows_core::Interface::vtable(self).Flush1)(windows_core::Interface::as_raw(self), contexttype, hevent.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn SetHardwareProtectionState(&self, hwprotectionenable: bool) { + unsafe { (windows_core::Interface::vtable(self).SetHardwareProtectionState)(windows_core::Interface::as_raw(self), hwprotectionenable.into()) } + } + pub unsafe fn GetHardwareProtectionState(&self) -> windows_core::BOOL { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetHardwareProtectionState)(windows_core::Interface::as_raw(self), &mut result__); + result__ + } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11DeviceContext3_Vtbl { @@ -27190,6 +113175,20 @@ impl core::ops::Deref for ID3D11DeviceContext4 { } } windows_core::imp::interface_hierarchy!(ID3D11DeviceContext4, windows_core::IUnknown, ID3D11DeviceChild, ID3D11DeviceContext, ID3D11DeviceContext1, ID3D11DeviceContext2, ID3D11DeviceContext3); +impl ID3D11DeviceContext4 { + pub unsafe fn Signal(&self, pfence: P0, value: u64) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).Signal)(windows_core::Interface::as_raw(self), pfence.param().abi(), value).ok() } + } + pub unsafe fn Wait(&self, pfence: P0, value: u64) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).Wait)(windows_core::Interface::as_raw(self), pfence.param().abi(), value).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11DeviceContext4_Vtbl { @@ -27201,8 +113200,8 @@ unsafe impl Send for ID3D11DeviceContext4 {} unsafe impl Sync for ID3D11DeviceContext4 {} #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi_Common"))] pub trait ID3D11DeviceContext4_Impl: ID3D11DeviceContext3_Impl { - fn Signal(&self, pfence: windows_core::Ref, value: u64) -> windows_core::Result<()>; - fn Wait(&self, pfence: windows_core::Ref, value: u64) -> windows_core::Result<()>; + fn Signal(&self, pfence: windows_core::Ref<'_, ID3D11Fence>, value: u64) -> windows_core::Result<()>; + fn Wait(&self, pfence: windows_core::Ref<'_, ID3D11Fence>, value: u64) -> windows_core::Result<()>; } #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi_Common"))] impl ID3D11DeviceContext4_Vtbl { @@ -27260,6 +113259,24 @@ impl core::ops::Deref for ID3D11Fence { } } windows_core::imp::interface_hierarchy!(ID3D11Fence, windows_core::IUnknown, ID3D11DeviceChild); +impl ID3D11Fence { + #[cfg(feature = "Win32_Security")] + pub unsafe fn CreateSharedHandle(&self, pattributes: Option<*const super::super::Security::SECURITY_ATTRIBUTES>, dwaccess: u32, lpname: P2) -> windows_core::Result + where + P2: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateSharedHandle)(windows_core::Interface::as_raw(self), pattributes.unwrap_or(core::mem::zeroed()) as _, dwaccess, lpname.param().abi(), &mut result__).map(|| result__) + } + } + pub unsafe fn GetCompletedValue(&self) -> u64 { + unsafe { (windows_core::Interface::vtable(self).GetCompletedValue)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn SetEventOnCompletion(&self, value: u64, hevent: super::super::Foundation::HANDLE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetEventOnCompletion)(windows_core::Interface::as_raw(self), value, hevent).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11Fence_Vtbl { @@ -27400,10 +113417,16 @@ impl ID3D11Multithread { pub unsafe fn Enter(&self) { unsafe { (windows_core::Interface::vtable(self).Enter)(windows_core::Interface::as_raw(self)) } } + pub unsafe fn Leave(&self) { + unsafe { (windows_core::Interface::vtable(self).Leave)(windows_core::Interface::as_raw(self)) } + } pub unsafe fn SetMultithreadProtected(&self, bmtprotect: bool) -> windows_core::BOOL { unsafe { (windows_core::Interface::vtable(self).SetMultithreadProtected)(windows_core::Interface::as_raw(self), bmtprotect.into()) } } + pub unsafe fn GetMultithreadProtected(&self) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).GetMultithreadProtected)(windows_core::Interface::as_raw(self)) } } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11Multithread_Vtbl { @@ -27561,6 +113584,15 @@ impl core::ops::Deref for ID3D11Query1 { } } windows_core::imp::interface_hierarchy!(ID3D11Query1, windows_core::IUnknown, ID3D11DeviceChild, ID3D11Asynchronous, ID3D11Query); +impl ID3D11Query1 { + pub unsafe fn GetDesc1(&self) -> D3D11_QUERY_DESC1 { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDesc1)(windows_core::Interface::as_raw(self), &mut result__); + result__ + } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11Query1_Vtbl { @@ -27634,6 +113666,11 @@ impl core::ops::Deref for ID3D11RasterizerState1 { } } windows_core::imp::interface_hierarchy!(ID3D11RasterizerState1, windows_core::IUnknown, ID3D11DeviceChild, ID3D11RasterizerState); +impl ID3D11RasterizerState1 { + pub unsafe fn GetDesc1(&self, pdesc: *mut D3D11_RASTERIZER_DESC1) { + unsafe { (windows_core::Interface::vtable(self).GetDesc1)(windows_core::Interface::as_raw(self), pdesc as _) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11RasterizerState1_Vtbl { @@ -27668,6 +113705,11 @@ impl core::ops::Deref for ID3D11RasterizerState2 { } } windows_core::imp::interface_hierarchy!(ID3D11RasterizerState2, windows_core::IUnknown, ID3D11DeviceChild, ID3D11RasterizerState, ID3D11RasterizerState1); +impl ID3D11RasterizerState2 { + pub unsafe fn GetDesc2(&self, pdesc: *mut D3D11_RASTERIZER_DESC2) { + unsafe { (windows_core::Interface::vtable(self).GetDesc2)(windows_core::Interface::as_raw(self), pdesc as _) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11RasterizerState2_Vtbl { @@ -27748,6 +113790,12 @@ impl core::ops::Deref for ID3D11RenderTargetView1 { } } windows_core::imp::interface_hierarchy!(ID3D11RenderTargetView1, windows_core::IUnknown, ID3D11DeviceChild, ID3D11View, ID3D11RenderTargetView); +impl ID3D11RenderTargetView1 { + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn GetDesc1(&self, pdesc1: *mut D3D11_RENDER_TARGET_VIEW_DESC1) { + unsafe { (windows_core::Interface::vtable(self).GetDesc1)(windows_core::Interface::as_raw(self), pdesc1 as _) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11RenderTargetView1_Vtbl { @@ -27788,6 +113836,21 @@ impl core::ops::Deref for ID3D11Resource { } } windows_core::imp::interface_hierarchy!(ID3D11Resource, windows_core::IUnknown, ID3D11DeviceChild); +impl ID3D11Resource { + pub unsafe fn GetType(&self) -> D3D11_RESOURCE_DIMENSION { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetType)(windows_core::Interface::as_raw(self), &mut result__); + result__ + } + } + pub unsafe fn SetEvictionPriority(&self, evictionpriority: u32) { + unsafe { (windows_core::Interface::vtable(self).SetEvictionPriority)(windows_core::Interface::as_raw(self), evictionpriority) } + } + pub unsafe fn GetEvictionPriority(&self) -> u32 { + unsafe { (windows_core::Interface::vtable(self).GetEvictionPriority)(windows_core::Interface::as_raw(self)) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11Resource_Vtbl { @@ -27928,6 +113991,12 @@ impl core::ops::Deref for ID3D11ShaderResourceView1 { } } windows_core::imp::interface_hierarchy!(ID3D11ShaderResourceView1, windows_core::IUnknown, ID3D11DeviceChild, ID3D11View, ID3D11ShaderResourceView); +impl ID3D11ShaderResourceView1 { + #[cfg(all(feature = "Win32_Graphics_Direct3D", feature = "Win32_Graphics_Dxgi_Common"))] + pub unsafe fn GetDesc1(&self, pdesc1: *mut D3D11_SHADER_RESOURCE_VIEW_DESC1) { + unsafe { (windows_core::Interface::vtable(self).GetDesc1)(windows_core::Interface::as_raw(self), pdesc1 as _) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11ShaderResourceView1_Vtbl { @@ -28060,6 +114129,12 @@ impl core::ops::Deref for ID3D11Texture2D1 { } } windows_core::imp::interface_hierarchy!(ID3D11Texture2D1, windows_core::IUnknown, ID3D11DeviceChild, ID3D11Resource, ID3D11Texture2D); +impl ID3D11Texture2D1 { + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn GetDesc1(&self, pdesc: *mut D3D11_TEXTURE2D_DESC1) { + unsafe { (windows_core::Interface::vtable(self).GetDesc1)(windows_core::Interface::as_raw(self), pdesc as _) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11Texture2D1_Vtbl { @@ -28146,6 +114221,12 @@ impl core::ops::Deref for ID3D11Texture3D1 { } } windows_core::imp::interface_hierarchy!(ID3D11Texture3D1, windows_core::IUnknown, ID3D11DeviceChild, ID3D11Resource, ID3D11Texture3D); +impl ID3D11Texture3D1 { + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn GetDesc1(&self, pdesc: *mut D3D11_TEXTURE3D_DESC1) { + unsafe { (windows_core::Interface::vtable(self).GetDesc1)(windows_core::Interface::as_raw(self), pdesc as _) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11Texture3D1_Vtbl { @@ -28232,6 +114313,12 @@ impl core::ops::Deref for ID3D11UnorderedAccessView1 { } } windows_core::imp::interface_hierarchy!(ID3D11UnorderedAccessView1, windows_core::IUnknown, ID3D11DeviceChild, ID3D11View, ID3D11UnorderedAccessView); +impl ID3D11UnorderedAccessView1 { + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn GetDesc1(&self, pdesc1: *mut D3D11_UNORDERED_ACCESS_VIEW_DESC1) { + unsafe { (windows_core::Interface::vtable(self).GetDesc1)(windows_core::Interface::as_raw(self), pdesc1 as _) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11UnorderedAccessView1_Vtbl { @@ -28297,6 +114384,386 @@ impl core::ops::Deref for ID3D11VideoContext { } } windows_core::imp::interface_hierarchy!(ID3D11VideoContext, windows_core::IUnknown, ID3D11DeviceChild); +impl ID3D11VideoContext { + pub unsafe fn GetDecoderBuffer(&self, pdecoder: P0, r#type: D3D11_VIDEO_DECODER_BUFFER_TYPE, pbuffersize: *mut u32, ppbuffer: *mut *mut core::ffi::c_void) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).GetDecoderBuffer)(windows_core::Interface::as_raw(self), pdecoder.param().abi(), r#type, pbuffersize as _, ppbuffer as _).ok() } + } + pub unsafe fn ReleaseDecoderBuffer(&self, pdecoder: P0, r#type: D3D11_VIDEO_DECODER_BUFFER_TYPE) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).ReleaseDecoderBuffer)(windows_core::Interface::as_raw(self), pdecoder.param().abi(), r#type).ok() } + } + pub unsafe fn DecoderBeginFrame(&self, pdecoder: P0, pview: P1, contentkeysize: u32, pcontentkey: Option<*const core::ffi::c_void>) -> windows_core::Result<()> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DecoderBeginFrame)(windows_core::Interface::as_raw(self), pdecoder.param().abi(), pview.param().abi(), contentkeysize, pcontentkey.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn DecoderEndFrame(&self, pdecoder: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DecoderEndFrame)(windows_core::Interface::as_raw(self), pdecoder.param().abi()).ok() } + } + pub unsafe fn SubmitDecoderBuffers(&self, pdecoder: P0, pbufferdesc: &[D3D11_VIDEO_DECODER_BUFFER_DESC]) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SubmitDecoderBuffers)(windows_core::Interface::as_raw(self), pdecoder.param().abi(), pbufferdesc.len().try_into().unwrap(), core::mem::transmute(pbufferdesc.as_ptr())).ok() } + } + pub unsafe fn DecoderExtension(&self, pdecoder: P0, pextensiondata: *const D3D11_VIDEO_DECODER_EXTENSION) -> i32 + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DecoderExtension)(windows_core::Interface::as_raw(self), pdecoder.param().abi(), pextensiondata) } + } + pub unsafe fn VideoProcessorSetOutputTargetRect(&self, pvideoprocessor: P0, enable: bool, prect: Option<*const super::super::Foundation::RECT>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetOutputTargetRect)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), enable.into(), prect.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn VideoProcessorSetOutputBackgroundColor(&self, pvideoprocessor: P0, ycbcr: bool, pcolor: *const D3D11_VIDEO_COLOR) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetOutputBackgroundColor)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), ycbcr.into(), pcolor) } + } + pub unsafe fn VideoProcessorSetOutputColorSpace(&self, pvideoprocessor: P0, pcolorspace: *const D3D11_VIDEO_PROCESSOR_COLOR_SPACE) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetOutputColorSpace)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), pcolorspace) } + } + pub unsafe fn VideoProcessorSetOutputAlphaFillMode(&self, pvideoprocessor: P0, alphafillmode: D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE, streamindex: u32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetOutputAlphaFillMode)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), alphafillmode, streamindex) } + } + pub unsafe fn VideoProcessorSetOutputConstriction(&self, pvideoprocessor: P0, enable: bool, size: super::super::Foundation::SIZE) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetOutputConstriction)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), enable.into(), core::mem::transmute(size)) } + } + pub unsafe fn VideoProcessorSetOutputStereoMode(&self, pvideoprocessor: P0, enable: bool) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetOutputStereoMode)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), enable.into()) } + } + pub unsafe fn VideoProcessorSetOutputExtension(&self, pvideoprocessor: P0, pextensionguid: *const windows_core::GUID, datasize: u32, pdata: *const core::ffi::c_void) -> i32 + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetOutputExtension)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), pextensionguid, datasize, pdata) } + } + pub unsafe fn VideoProcessorGetOutputTargetRect(&self, pvideoprocessor: P0, enabled: *mut windows_core::BOOL, prect: *mut super::super::Foundation::RECT) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetOutputTargetRect)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), enabled as _, prect as _) } + } + pub unsafe fn VideoProcessorGetOutputBackgroundColor(&self, pvideoprocessor: P0, pycbcr: *mut windows_core::BOOL, pcolor: *mut D3D11_VIDEO_COLOR) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetOutputBackgroundColor)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), pycbcr as _, pcolor as _) } + } + pub unsafe fn VideoProcessorGetOutputColorSpace(&self, pvideoprocessor: P0) -> D3D11_VIDEO_PROCESSOR_COLOR_SPACE + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).VideoProcessorGetOutputColorSpace)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), &mut result__); + result__ + } + } + pub unsafe fn VideoProcessorGetOutputAlphaFillMode(&self, pvideoprocessor: P0, palphafillmode: *mut D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE, pstreamindex: *mut u32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetOutputAlphaFillMode)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), palphafillmode as _, pstreamindex as _) } + } + pub unsafe fn VideoProcessorGetOutputConstriction(&self, pvideoprocessor: P0, penabled: *mut windows_core::BOOL, psize: *mut super::super::Foundation::SIZE) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetOutputConstriction)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), penabled as _, psize as _) } + } + pub unsafe fn VideoProcessorGetOutputStereoMode(&self, pvideoprocessor: P0) -> windows_core::BOOL + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).VideoProcessorGetOutputStereoMode)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), &mut result__); + result__ + } + } + pub unsafe fn VideoProcessorGetOutputExtension(&self, pvideoprocessor: P0, pextensionguid: *const windows_core::GUID, datasize: u32, pdata: *mut core::ffi::c_void) -> i32 + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetOutputExtension)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), pextensionguid, datasize, pdata as _) } + } + pub unsafe fn VideoProcessorSetStreamFrameFormat(&self, pvideoprocessor: P0, streamindex: u32, frameformat: D3D11_VIDEO_FRAME_FORMAT) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamFrameFormat)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, frameformat) } + } + pub unsafe fn VideoProcessorSetStreamColorSpace(&self, pvideoprocessor: P0, streamindex: u32, pcolorspace: *const D3D11_VIDEO_PROCESSOR_COLOR_SPACE) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamColorSpace)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, pcolorspace) } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn VideoProcessorSetStreamOutputRate(&self, pvideoprocessor: P0, streamindex: u32, outputrate: D3D11_VIDEO_PROCESSOR_OUTPUT_RATE, repeatframe: bool, pcustomrate: Option<*const super::Dxgi::Common::DXGI_RATIONAL>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamOutputRate)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, outputrate, repeatframe.into(), pcustomrate.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn VideoProcessorSetStreamSourceRect(&self, pvideoprocessor: P0, streamindex: u32, enable: bool, prect: Option<*const super::super::Foundation::RECT>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamSourceRect)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, enable.into(), prect.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn VideoProcessorSetStreamDestRect(&self, pvideoprocessor: P0, streamindex: u32, enable: bool, prect: Option<*const super::super::Foundation::RECT>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamDestRect)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, enable.into(), prect.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn VideoProcessorSetStreamAlpha(&self, pvideoprocessor: P0, streamindex: u32, enable: bool, alpha: f32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamAlpha)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, enable.into(), alpha) } + } + pub unsafe fn VideoProcessorSetStreamPalette(&self, pvideoprocessor: P0, streamindex: u32, pentries: Option<&[u32]>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamPalette)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, pentries.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(pentries.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))) } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn VideoProcessorSetStreamPixelAspectRatio(&self, pvideoprocessor: P0, streamindex: u32, enable: bool, psourceaspectratio: Option<*const super::Dxgi::Common::DXGI_RATIONAL>, pdestinationaspectratio: Option<*const super::Dxgi::Common::DXGI_RATIONAL>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamPixelAspectRatio)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, enable.into(), psourceaspectratio.unwrap_or(core::mem::zeroed()) as _, pdestinationaspectratio.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn VideoProcessorSetStreamLumaKey(&self, pvideoprocessor: P0, streamindex: u32, enable: bool, lower: f32, upper: f32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamLumaKey)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, enable.into(), lower, upper) } + } + pub unsafe fn VideoProcessorSetStreamStereoFormat(&self, pvideoprocessor: P0, streamindex: u32, enable: bool, format: D3D11_VIDEO_PROCESSOR_STEREO_FORMAT, leftviewframe0: bool, baseviewframe0: bool, flipmode: D3D11_VIDEO_PROCESSOR_STEREO_FLIP_MODE, monooffset: i32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamStereoFormat)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, enable.into(), format, leftviewframe0.into(), baseviewframe0.into(), flipmode, monooffset) } + } + pub unsafe fn VideoProcessorSetStreamAutoProcessingMode(&self, pvideoprocessor: P0, streamindex: u32, enable: bool) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamAutoProcessingMode)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, enable.into()) } + } + pub unsafe fn VideoProcessorSetStreamFilter(&self, pvideoprocessor: P0, streamindex: u32, filter: D3D11_VIDEO_PROCESSOR_FILTER, enable: bool, level: i32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamFilter)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, filter, enable.into(), level) } + } + pub unsafe fn VideoProcessorSetStreamExtension(&self, pvideoprocessor: P0, streamindex: u32, pextensionguid: *const windows_core::GUID, datasize: u32, pdata: *const core::ffi::c_void) -> i32 + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamExtension)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, pextensionguid, datasize, pdata) } + } + pub unsafe fn VideoProcessorGetStreamFrameFormat(&self, pvideoprocessor: P0, streamindex: u32) -> D3D11_VIDEO_FRAME_FORMAT + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).VideoProcessorGetStreamFrameFormat)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, &mut result__); + result__ + } + } + pub unsafe fn VideoProcessorGetStreamColorSpace(&self, pvideoprocessor: P0, streamindex: u32) -> D3D11_VIDEO_PROCESSOR_COLOR_SPACE + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).VideoProcessorGetStreamColorSpace)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, &mut result__); + result__ + } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn VideoProcessorGetStreamOutputRate(&self, pvideoprocessor: P0, streamindex: u32, poutputrate: *mut D3D11_VIDEO_PROCESSOR_OUTPUT_RATE, prepeatframe: *mut windows_core::BOOL, pcustomrate: *mut super::Dxgi::Common::DXGI_RATIONAL) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetStreamOutputRate)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, poutputrate as _, prepeatframe as _, pcustomrate as _) } + } + pub unsafe fn VideoProcessorGetStreamSourceRect(&self, pvideoprocessor: P0, streamindex: u32, penabled: *mut windows_core::BOOL, prect: *mut super::super::Foundation::RECT) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetStreamSourceRect)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, penabled as _, prect as _) } + } + pub unsafe fn VideoProcessorGetStreamDestRect(&self, pvideoprocessor: P0, streamindex: u32, penabled: *mut windows_core::BOOL, prect: *mut super::super::Foundation::RECT) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetStreamDestRect)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, penabled as _, prect as _) } + } + pub unsafe fn VideoProcessorGetStreamAlpha(&self, pvideoprocessor: P0, streamindex: u32, penabled: *mut windows_core::BOOL, palpha: *mut f32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetStreamAlpha)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, penabled as _, palpha as _) } + } + pub unsafe fn VideoProcessorGetStreamPalette(&self, pvideoprocessor: P0, streamindex: u32, pentries: &mut [u32]) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetStreamPalette)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, pentries.len().try_into().unwrap(), core::mem::transmute(pentries.as_ptr())) } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn VideoProcessorGetStreamPixelAspectRatio(&self, pvideoprocessor: P0, streamindex: u32, penabled: *mut windows_core::BOOL, psourceaspectratio: *mut super::Dxgi::Common::DXGI_RATIONAL, pdestinationaspectratio: *mut super::Dxgi::Common::DXGI_RATIONAL) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetStreamPixelAspectRatio)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, penabled as _, psourceaspectratio as _, pdestinationaspectratio as _) } + } + pub unsafe fn VideoProcessorGetStreamLumaKey(&self, pvideoprocessor: P0, streamindex: u32, penabled: *mut windows_core::BOOL, plower: *mut f32, pupper: *mut f32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetStreamLumaKey)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, penabled as _, plower as _, pupper as _) } + } + pub unsafe fn VideoProcessorGetStreamStereoFormat(&self, pvideoprocessor: P0, streamindex: u32, penable: *mut windows_core::BOOL, pformat: *mut D3D11_VIDEO_PROCESSOR_STEREO_FORMAT, pleftviewframe0: *mut windows_core::BOOL, pbaseviewframe0: *mut windows_core::BOOL, pflipmode: *mut D3D11_VIDEO_PROCESSOR_STEREO_FLIP_MODE, monooffset: *mut i32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetStreamStereoFormat)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, penable as _, pformat as _, pleftviewframe0 as _, pbaseviewframe0 as _, pflipmode as _, monooffset as _) } + } + pub unsafe fn VideoProcessorGetStreamAutoProcessingMode(&self, pvideoprocessor: P0, streamindex: u32) -> windows_core::BOOL + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).VideoProcessorGetStreamAutoProcessingMode)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, &mut result__); + result__ + } + } + pub unsafe fn VideoProcessorGetStreamFilter(&self, pvideoprocessor: P0, streamindex: u32, filter: D3D11_VIDEO_PROCESSOR_FILTER, penabled: *mut windows_core::BOOL, plevel: *mut i32) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetStreamFilter)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, filter, penabled as _, plevel as _) } + } + pub unsafe fn VideoProcessorGetStreamExtension(&self, pvideoprocessor: P0, streamindex: u32, pextensionguid: *const windows_core::GUID, datasize: u32, pdata: *mut core::ffi::c_void) -> i32 + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetStreamExtension)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, pextensionguid, datasize, pdata as _) } + } + pub unsafe fn VideoProcessorBlt(&self, pvideoprocessor: P0, pview: P1, outputframe: u32, pstreams: &[D3D11_VIDEO_PROCESSOR_STREAM]) -> windows_core::Result<()> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorBlt)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), pview.param().abi(), outputframe, pstreams.len().try_into().unwrap(), core::mem::transmute(pstreams.as_ptr())).ok() } + } + pub unsafe fn NegotiateCryptoSessionKeyExchange(&self, pcryptosession: P0, datasize: u32, pdata: *mut core::ffi::c_void) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).NegotiateCryptoSessionKeyExchange)(windows_core::Interface::as_raw(self), pcryptosession.param().abi(), datasize, pdata as _).ok() } + } + pub unsafe fn EncryptionBlt(&self, pcryptosession: P0, psrcsurface: P1, pdstsurface: P2, ivsize: u32, piv: Option<*mut core::ffi::c_void>) + where + P0: windows_core::Param, + P1: windows_core::Param, + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).EncryptionBlt)(windows_core::Interface::as_raw(self), pcryptosession.param().abi(), psrcsurface.param().abi(), pdstsurface.param().abi(), ivsize, piv.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn DecryptionBlt(&self, pcryptosession: P0, psrcsurface: P1, pdstsurface: P2, pencryptedblockinfo: Option<*const D3D11_ENCRYPTED_BLOCK_INFO>, contentkeysize: u32, pcontentkey: Option<*const core::ffi::c_void>, ivsize: u32, piv: Option<*mut core::ffi::c_void>) + where + P0: windows_core::Param, + P1: windows_core::Param, + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DecryptionBlt)(windows_core::Interface::as_raw(self), pcryptosession.param().abi(), psrcsurface.param().abi(), pdstsurface.param().abi(), pencryptedblockinfo.unwrap_or(core::mem::zeroed()) as _, contentkeysize, pcontentkey.unwrap_or(core::mem::zeroed()) as _, ivsize, piv.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn StartSessionKeyRefresh(&self, pcryptosession: P0, randomnumbersize: u32, prandomnumber: *mut core::ffi::c_void) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).StartSessionKeyRefresh)(windows_core::Interface::as_raw(self), pcryptosession.param().abi(), randomnumbersize, prandomnumber as _) } + } + pub unsafe fn FinishSessionKeyRefresh(&self, pcryptosession: P0) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).FinishSessionKeyRefresh)(windows_core::Interface::as_raw(self), pcryptosession.param().abi()) } + } + pub unsafe fn GetEncryptionBltKey(&self, pcryptosession: P0, keysize: u32, preadbackkey: *mut core::ffi::c_void) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).GetEncryptionBltKey)(windows_core::Interface::as_raw(self), pcryptosession.param().abi(), keysize, preadbackkey as _).ok() } + } + pub unsafe fn NegotiateAuthenticatedChannelKeyExchange(&self, pchannel: P0, datasize: u32, pdata: *mut core::ffi::c_void) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).NegotiateAuthenticatedChannelKeyExchange)(windows_core::Interface::as_raw(self), pchannel.param().abi(), datasize, pdata as _).ok() } + } + pub unsafe fn QueryAuthenticatedChannel(&self, pchannel: P0, inputsize: u32, pinput: *const core::ffi::c_void, outputsize: u32, poutput: *mut core::ffi::c_void) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).QueryAuthenticatedChannel)(windows_core::Interface::as_raw(self), pchannel.param().abi(), inputsize, pinput, outputsize, poutput as _).ok() } + } + pub unsafe fn ConfigureAuthenticatedChannel(&self, pchannel: P0, inputsize: u32, pinput: *const core::ffi::c_void, poutput: *mut D3D11_AUTHENTICATED_CONFIGURE_OUTPUT) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).ConfigureAuthenticatedChannel)(windows_core::Interface::as_raw(self), pchannel.param().abi(), inputsize, pinput, poutput as _).ok() } + } + pub unsafe fn VideoProcessorSetStreamRotation(&self, pvideoprocessor: P0, streamindex: u32, enable: bool, rotation: D3D11_VIDEO_PROCESSOR_ROTATION) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamRotation)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, enable.into(), rotation) } + } + pub unsafe fn VideoProcessorGetStreamRotation(&self, pvideoprocessor: P0, streamindex: u32, penable: *mut windows_core::BOOL, protation: *mut D3D11_VIDEO_PROCESSOR_ROTATION) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetStreamRotation)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, penable as _, protation as _) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11VideoContext_Vtbl { @@ -28376,64 +114843,64 @@ unsafe impl Send for ID3D11VideoContext {} unsafe impl Sync for ID3D11VideoContext {} #[cfg(feature = "Win32_Graphics_Dxgi_Common")] pub trait ID3D11VideoContext_Impl: ID3D11DeviceChild_Impl { - fn GetDecoderBuffer(&self, pdecoder: windows_core::Ref, r#type: D3D11_VIDEO_DECODER_BUFFER_TYPE, pbuffersize: *mut u32, ppbuffer: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; - fn ReleaseDecoderBuffer(&self, pdecoder: windows_core::Ref, r#type: D3D11_VIDEO_DECODER_BUFFER_TYPE) -> windows_core::Result<()>; - fn DecoderBeginFrame(&self, pdecoder: windows_core::Ref, pview: windows_core::Ref, contentkeysize: u32, pcontentkey: *const core::ffi::c_void) -> windows_core::Result<()>; - fn DecoderEndFrame(&self, pdecoder: windows_core::Ref) -> windows_core::Result<()>; - fn SubmitDecoderBuffers(&self, pdecoder: windows_core::Ref, numbuffers: u32, pbufferdesc: *const D3D11_VIDEO_DECODER_BUFFER_DESC) -> windows_core::Result<()>; - fn DecoderExtension(&self, pdecoder: windows_core::Ref, pextensiondata: *const D3D11_VIDEO_DECODER_EXTENSION) -> i32; - fn VideoProcessorSetOutputTargetRect(&self, pvideoprocessor: windows_core::Ref, enable: windows_core::BOOL, prect: *const super::super::Foundation::RECT); - fn VideoProcessorSetOutputBackgroundColor(&self, pvideoprocessor: windows_core::Ref, ycbcr: windows_core::BOOL, pcolor: *const D3D11_VIDEO_COLOR); - fn VideoProcessorSetOutputColorSpace(&self, pvideoprocessor: windows_core::Ref, pcolorspace: *const D3D11_VIDEO_PROCESSOR_COLOR_SPACE); - fn VideoProcessorSetOutputAlphaFillMode(&self, pvideoprocessor: windows_core::Ref, alphafillmode: D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE, streamindex: u32); - fn VideoProcessorSetOutputConstriction(&self, pvideoprocessor: windows_core::Ref, enable: windows_core::BOOL, size: &super::super::Foundation::SIZE); - fn VideoProcessorSetOutputStereoMode(&self, pvideoprocessor: windows_core::Ref, enable: windows_core::BOOL); - fn VideoProcessorSetOutputExtension(&self, pvideoprocessor: windows_core::Ref, pextensionguid: *const windows_core::GUID, datasize: u32, pdata: *const core::ffi::c_void) -> i32; - fn VideoProcessorGetOutputTargetRect(&self, pvideoprocessor: windows_core::Ref, enabled: *mut windows_core::BOOL, prect: *mut super::super::Foundation::RECT); - fn VideoProcessorGetOutputBackgroundColor(&self, pvideoprocessor: windows_core::Ref, pycbcr: *mut windows_core::BOOL, pcolor: *mut D3D11_VIDEO_COLOR); - fn VideoProcessorGetOutputColorSpace(&self, pvideoprocessor: windows_core::Ref, pcolorspace: *mut D3D11_VIDEO_PROCESSOR_COLOR_SPACE); - fn VideoProcessorGetOutputAlphaFillMode(&self, pvideoprocessor: windows_core::Ref, palphafillmode: *mut D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE, pstreamindex: *mut u32); - fn VideoProcessorGetOutputConstriction(&self, pvideoprocessor: windows_core::Ref, penabled: *mut windows_core::BOOL, psize: *mut super::super::Foundation::SIZE); - fn VideoProcessorGetOutputStereoMode(&self, pvideoprocessor: windows_core::Ref, penabled: *mut windows_core::BOOL); - fn VideoProcessorGetOutputExtension(&self, pvideoprocessor: windows_core::Ref, pextensionguid: *const windows_core::GUID, datasize: u32, pdata: *mut core::ffi::c_void) -> i32; - fn VideoProcessorSetStreamFrameFormat(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, frameformat: D3D11_VIDEO_FRAME_FORMAT); - fn VideoProcessorSetStreamColorSpace(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, pcolorspace: *const D3D11_VIDEO_PROCESSOR_COLOR_SPACE); - fn VideoProcessorSetStreamOutputRate(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, outputrate: D3D11_VIDEO_PROCESSOR_OUTPUT_RATE, repeatframe: windows_core::BOOL, pcustomrate: *const super::Dxgi::Common::DXGI_RATIONAL); - fn VideoProcessorSetStreamSourceRect(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, enable: windows_core::BOOL, prect: *const super::super::Foundation::RECT); - fn VideoProcessorSetStreamDestRect(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, enable: windows_core::BOOL, prect: *const super::super::Foundation::RECT); - fn VideoProcessorSetStreamAlpha(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, enable: windows_core::BOOL, alpha: f32); - fn VideoProcessorSetStreamPalette(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, count: u32, pentries: *const u32); - fn VideoProcessorSetStreamPixelAspectRatio(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, enable: windows_core::BOOL, psourceaspectratio: *const super::Dxgi::Common::DXGI_RATIONAL, pdestinationaspectratio: *const super::Dxgi::Common::DXGI_RATIONAL); - fn VideoProcessorSetStreamLumaKey(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, enable: windows_core::BOOL, lower: f32, upper: f32); - fn VideoProcessorSetStreamStereoFormat(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, enable: windows_core::BOOL, format: D3D11_VIDEO_PROCESSOR_STEREO_FORMAT, leftviewframe0: windows_core::BOOL, baseviewframe0: windows_core::BOOL, flipmode: D3D11_VIDEO_PROCESSOR_STEREO_FLIP_MODE, monooffset: i32); - fn VideoProcessorSetStreamAutoProcessingMode(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, enable: windows_core::BOOL); - fn VideoProcessorSetStreamFilter(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, filter: D3D11_VIDEO_PROCESSOR_FILTER, enable: windows_core::BOOL, level: i32); - fn VideoProcessorSetStreamExtension(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, pextensionguid: *const windows_core::GUID, datasize: u32, pdata: *const core::ffi::c_void) -> i32; - fn VideoProcessorGetStreamFrameFormat(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, pframeformat: *mut D3D11_VIDEO_FRAME_FORMAT); - fn VideoProcessorGetStreamColorSpace(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, pcolorspace: *mut D3D11_VIDEO_PROCESSOR_COLOR_SPACE); - fn VideoProcessorGetStreamOutputRate(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, poutputrate: *mut D3D11_VIDEO_PROCESSOR_OUTPUT_RATE, prepeatframe: *mut windows_core::BOOL, pcustomrate: *mut super::Dxgi::Common::DXGI_RATIONAL); - fn VideoProcessorGetStreamSourceRect(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, penabled: *mut windows_core::BOOL, prect: *mut super::super::Foundation::RECT); - fn VideoProcessorGetStreamDestRect(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, penabled: *mut windows_core::BOOL, prect: *mut super::super::Foundation::RECT); - fn VideoProcessorGetStreamAlpha(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, penabled: *mut windows_core::BOOL, palpha: *mut f32); - fn VideoProcessorGetStreamPalette(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, count: u32, pentries: *mut u32); - fn VideoProcessorGetStreamPixelAspectRatio(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, penabled: *mut windows_core::BOOL, psourceaspectratio: *mut super::Dxgi::Common::DXGI_RATIONAL, pdestinationaspectratio: *mut super::Dxgi::Common::DXGI_RATIONAL); - fn VideoProcessorGetStreamLumaKey(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, penabled: *mut windows_core::BOOL, plower: *mut f32, pupper: *mut f32); - fn VideoProcessorGetStreamStereoFormat(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, penable: *mut windows_core::BOOL, pformat: *mut D3D11_VIDEO_PROCESSOR_STEREO_FORMAT, pleftviewframe0: *mut windows_core::BOOL, pbaseviewframe0: *mut windows_core::BOOL, pflipmode: *mut D3D11_VIDEO_PROCESSOR_STEREO_FLIP_MODE, monooffset: *mut i32); - fn VideoProcessorGetStreamAutoProcessingMode(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, penabled: *mut windows_core::BOOL); - fn VideoProcessorGetStreamFilter(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, filter: D3D11_VIDEO_PROCESSOR_FILTER, penabled: *mut windows_core::BOOL, plevel: *mut i32); - fn VideoProcessorGetStreamExtension(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, pextensionguid: *const windows_core::GUID, datasize: u32, pdata: *mut core::ffi::c_void) -> i32; - fn VideoProcessorBlt(&self, pvideoprocessor: windows_core::Ref, pview: windows_core::Ref, outputframe: u32, streamcount: u32, pstreams: *const D3D11_VIDEO_PROCESSOR_STREAM) -> windows_core::Result<()>; - fn NegotiateCryptoSessionKeyExchange(&self, pcryptosession: windows_core::Ref, datasize: u32, pdata: *mut core::ffi::c_void) -> windows_core::Result<()>; - fn EncryptionBlt(&self, pcryptosession: windows_core::Ref, psrcsurface: windows_core::Ref, pdstsurface: windows_core::Ref, ivsize: u32, piv: *mut core::ffi::c_void); - fn DecryptionBlt(&self, pcryptosession: windows_core::Ref, psrcsurface: windows_core::Ref, pdstsurface: windows_core::Ref, pencryptedblockinfo: *const D3D11_ENCRYPTED_BLOCK_INFO, contentkeysize: u32, pcontentkey: *const core::ffi::c_void, ivsize: u32, piv: *mut core::ffi::c_void); - fn StartSessionKeyRefresh(&self, pcryptosession: windows_core::Ref, randomnumbersize: u32, prandomnumber: *mut core::ffi::c_void); - fn FinishSessionKeyRefresh(&self, pcryptosession: windows_core::Ref); - fn GetEncryptionBltKey(&self, pcryptosession: windows_core::Ref, keysize: u32, preadbackkey: *mut core::ffi::c_void) -> windows_core::Result<()>; - fn NegotiateAuthenticatedChannelKeyExchange(&self, pchannel: windows_core::Ref, datasize: u32, pdata: *mut core::ffi::c_void) -> windows_core::Result<()>; - fn QueryAuthenticatedChannel(&self, pchannel: windows_core::Ref, inputsize: u32, pinput: *const core::ffi::c_void, outputsize: u32, poutput: *mut core::ffi::c_void) -> windows_core::Result<()>; - fn ConfigureAuthenticatedChannel(&self, pchannel: windows_core::Ref, inputsize: u32, pinput: *const core::ffi::c_void, poutput: *mut D3D11_AUTHENTICATED_CONFIGURE_OUTPUT) -> windows_core::Result<()>; - fn VideoProcessorSetStreamRotation(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, enable: windows_core::BOOL, rotation: D3D11_VIDEO_PROCESSOR_ROTATION); - fn VideoProcessorGetStreamRotation(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, penable: *mut windows_core::BOOL, protation: *mut D3D11_VIDEO_PROCESSOR_ROTATION); + fn GetDecoderBuffer(&self, pdecoder: windows_core::Ref<'_, ID3D11VideoDecoder>, r#type: D3D11_VIDEO_DECODER_BUFFER_TYPE, pbuffersize: *mut u32, ppbuffer: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; + fn ReleaseDecoderBuffer(&self, pdecoder: windows_core::Ref<'_, ID3D11VideoDecoder>, r#type: D3D11_VIDEO_DECODER_BUFFER_TYPE) -> windows_core::Result<()>; + fn DecoderBeginFrame(&self, pdecoder: windows_core::Ref<'_, ID3D11VideoDecoder>, pview: windows_core::Ref<'_, ID3D11VideoDecoderOutputView>, contentkeysize: u32, pcontentkey: *const core::ffi::c_void) -> windows_core::Result<()>; + fn DecoderEndFrame(&self, pdecoder: windows_core::Ref<'_, ID3D11VideoDecoder>) -> windows_core::Result<()>; + fn SubmitDecoderBuffers(&self, pdecoder: windows_core::Ref<'_, ID3D11VideoDecoder>, numbuffers: u32, pbufferdesc: *const D3D11_VIDEO_DECODER_BUFFER_DESC) -> windows_core::Result<()>; + fn DecoderExtension(&self, pdecoder: windows_core::Ref<'_, ID3D11VideoDecoder>, pextensiondata: *const D3D11_VIDEO_DECODER_EXTENSION) -> i32; + fn VideoProcessorSetOutputTargetRect(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, enable: windows_core::BOOL, prect: *const super::super::Foundation::RECT); + fn VideoProcessorSetOutputBackgroundColor(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, ycbcr: windows_core::BOOL, pcolor: *const D3D11_VIDEO_COLOR); + fn VideoProcessorSetOutputColorSpace(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, pcolorspace: *const D3D11_VIDEO_PROCESSOR_COLOR_SPACE); + fn VideoProcessorSetOutputAlphaFillMode(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, alphafillmode: D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE, streamindex: u32); + fn VideoProcessorSetOutputConstriction(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, enable: windows_core::BOOL, size: &super::super::Foundation::SIZE); + fn VideoProcessorSetOutputStereoMode(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, enable: windows_core::BOOL); + fn VideoProcessorSetOutputExtension(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, pextensionguid: *const windows_core::GUID, datasize: u32, pdata: *const core::ffi::c_void) -> i32; + fn VideoProcessorGetOutputTargetRect(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, enabled: *mut windows_core::BOOL, prect: *mut super::super::Foundation::RECT); + fn VideoProcessorGetOutputBackgroundColor(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, pycbcr: *mut windows_core::BOOL, pcolor: *mut D3D11_VIDEO_COLOR); + fn VideoProcessorGetOutputColorSpace(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, pcolorspace: *mut D3D11_VIDEO_PROCESSOR_COLOR_SPACE); + fn VideoProcessorGetOutputAlphaFillMode(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, palphafillmode: *mut D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE, pstreamindex: *mut u32); + fn VideoProcessorGetOutputConstriction(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, penabled: *mut windows_core::BOOL, psize: *mut super::super::Foundation::SIZE); + fn VideoProcessorGetOutputStereoMode(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, penabled: *mut windows_core::BOOL); + fn VideoProcessorGetOutputExtension(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, pextensionguid: *const windows_core::GUID, datasize: u32, pdata: *mut core::ffi::c_void) -> i32; + fn VideoProcessorSetStreamFrameFormat(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, frameformat: D3D11_VIDEO_FRAME_FORMAT); + fn VideoProcessorSetStreamColorSpace(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, pcolorspace: *const D3D11_VIDEO_PROCESSOR_COLOR_SPACE); + fn VideoProcessorSetStreamOutputRate(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, outputrate: D3D11_VIDEO_PROCESSOR_OUTPUT_RATE, repeatframe: windows_core::BOOL, pcustomrate: *const super::Dxgi::Common::DXGI_RATIONAL); + fn VideoProcessorSetStreamSourceRect(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, enable: windows_core::BOOL, prect: *const super::super::Foundation::RECT); + fn VideoProcessorSetStreamDestRect(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, enable: windows_core::BOOL, prect: *const super::super::Foundation::RECT); + fn VideoProcessorSetStreamAlpha(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, enable: windows_core::BOOL, alpha: f32); + fn VideoProcessorSetStreamPalette(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, count: u32, pentries: *const u32); + fn VideoProcessorSetStreamPixelAspectRatio(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, enable: windows_core::BOOL, psourceaspectratio: *const super::Dxgi::Common::DXGI_RATIONAL, pdestinationaspectratio: *const super::Dxgi::Common::DXGI_RATIONAL); + fn VideoProcessorSetStreamLumaKey(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, enable: windows_core::BOOL, lower: f32, upper: f32); + fn VideoProcessorSetStreamStereoFormat(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, enable: windows_core::BOOL, format: D3D11_VIDEO_PROCESSOR_STEREO_FORMAT, leftviewframe0: windows_core::BOOL, baseviewframe0: windows_core::BOOL, flipmode: D3D11_VIDEO_PROCESSOR_STEREO_FLIP_MODE, monooffset: i32); + fn VideoProcessorSetStreamAutoProcessingMode(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, enable: windows_core::BOOL); + fn VideoProcessorSetStreamFilter(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, filter: D3D11_VIDEO_PROCESSOR_FILTER, enable: windows_core::BOOL, level: i32); + fn VideoProcessorSetStreamExtension(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, pextensionguid: *const windows_core::GUID, datasize: u32, pdata: *const core::ffi::c_void) -> i32; + fn VideoProcessorGetStreamFrameFormat(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, pframeformat: *mut D3D11_VIDEO_FRAME_FORMAT); + fn VideoProcessorGetStreamColorSpace(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, pcolorspace: *mut D3D11_VIDEO_PROCESSOR_COLOR_SPACE); + fn VideoProcessorGetStreamOutputRate(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, poutputrate: *mut D3D11_VIDEO_PROCESSOR_OUTPUT_RATE, prepeatframe: *mut windows_core::BOOL, pcustomrate: *mut super::Dxgi::Common::DXGI_RATIONAL); + fn VideoProcessorGetStreamSourceRect(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, penabled: *mut windows_core::BOOL, prect: *mut super::super::Foundation::RECT); + fn VideoProcessorGetStreamDestRect(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, penabled: *mut windows_core::BOOL, prect: *mut super::super::Foundation::RECT); + fn VideoProcessorGetStreamAlpha(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, penabled: *mut windows_core::BOOL, palpha: *mut f32); + fn VideoProcessorGetStreamPalette(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, count: u32, pentries: *mut u32); + fn VideoProcessorGetStreamPixelAspectRatio(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, penabled: *mut windows_core::BOOL, psourceaspectratio: *mut super::Dxgi::Common::DXGI_RATIONAL, pdestinationaspectratio: *mut super::Dxgi::Common::DXGI_RATIONAL); + fn VideoProcessorGetStreamLumaKey(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, penabled: *mut windows_core::BOOL, plower: *mut f32, pupper: *mut f32); + fn VideoProcessorGetStreamStereoFormat(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, penable: *mut windows_core::BOOL, pformat: *mut D3D11_VIDEO_PROCESSOR_STEREO_FORMAT, pleftviewframe0: *mut windows_core::BOOL, pbaseviewframe0: *mut windows_core::BOOL, pflipmode: *mut D3D11_VIDEO_PROCESSOR_STEREO_FLIP_MODE, monooffset: *mut i32); + fn VideoProcessorGetStreamAutoProcessingMode(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, penabled: *mut windows_core::BOOL); + fn VideoProcessorGetStreamFilter(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, filter: D3D11_VIDEO_PROCESSOR_FILTER, penabled: *mut windows_core::BOOL, plevel: *mut i32); + fn VideoProcessorGetStreamExtension(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, pextensionguid: *const windows_core::GUID, datasize: u32, pdata: *mut core::ffi::c_void) -> i32; + fn VideoProcessorBlt(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, pview: windows_core::Ref<'_, ID3D11VideoProcessorOutputView>, outputframe: u32, streamcount: u32, pstreams: *const D3D11_VIDEO_PROCESSOR_STREAM) -> windows_core::Result<()>; + fn NegotiateCryptoSessionKeyExchange(&self, pcryptosession: windows_core::Ref<'_, ID3D11CryptoSession>, datasize: u32, pdata: *mut core::ffi::c_void) -> windows_core::Result<()>; + fn EncryptionBlt(&self, pcryptosession: windows_core::Ref<'_, ID3D11CryptoSession>, psrcsurface: windows_core::Ref<'_, ID3D11Texture2D>, pdstsurface: windows_core::Ref<'_, ID3D11Texture2D>, ivsize: u32, piv: *mut core::ffi::c_void); + fn DecryptionBlt(&self, pcryptosession: windows_core::Ref<'_, ID3D11CryptoSession>, psrcsurface: windows_core::Ref<'_, ID3D11Texture2D>, pdstsurface: windows_core::Ref<'_, ID3D11Texture2D>, pencryptedblockinfo: *const D3D11_ENCRYPTED_BLOCK_INFO, contentkeysize: u32, pcontentkey: *const core::ffi::c_void, ivsize: u32, piv: *mut core::ffi::c_void); + fn StartSessionKeyRefresh(&self, pcryptosession: windows_core::Ref<'_, ID3D11CryptoSession>, randomnumbersize: u32, prandomnumber: *mut core::ffi::c_void); + fn FinishSessionKeyRefresh(&self, pcryptosession: windows_core::Ref<'_, ID3D11CryptoSession>); + fn GetEncryptionBltKey(&self, pcryptosession: windows_core::Ref<'_, ID3D11CryptoSession>, keysize: u32, preadbackkey: *mut core::ffi::c_void) -> windows_core::Result<()>; + fn NegotiateAuthenticatedChannelKeyExchange(&self, pchannel: windows_core::Ref<'_, ID3D11AuthenticatedChannel>, datasize: u32, pdata: *mut core::ffi::c_void) -> windows_core::Result<()>; + fn QueryAuthenticatedChannel(&self, pchannel: windows_core::Ref<'_, ID3D11AuthenticatedChannel>, inputsize: u32, pinput: *const core::ffi::c_void, outputsize: u32, poutput: *mut core::ffi::c_void) -> windows_core::Result<()>; + fn ConfigureAuthenticatedChannel(&self, pchannel: windows_core::Ref<'_, ID3D11AuthenticatedChannel>, inputsize: u32, pinput: *const core::ffi::c_void, poutput: *mut D3D11_AUTHENTICATED_CONFIGURE_OUTPUT) -> windows_core::Result<()>; + fn VideoProcessorSetStreamRotation(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, enable: windows_core::BOOL, rotation: D3D11_VIDEO_PROCESSOR_ROTATION); + fn VideoProcessorGetStreamRotation(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, penable: *mut windows_core::BOOL, protation: *mut D3D11_VIDEO_PROCESSOR_ROTATION); } #[cfg(feature = "Win32_Graphics_Dxgi_Common")] impl ID3D11VideoContext_Vtbl { @@ -28862,6 +115329,120 @@ impl core::ops::Deref for ID3D11VideoContext1 { } } windows_core::imp::interface_hierarchy!(ID3D11VideoContext1, windows_core::IUnknown, ID3D11DeviceChild, ID3D11VideoContext); +impl ID3D11VideoContext1 { + pub unsafe fn SubmitDecoderBuffers1(&self, pdecoder: P0, pbufferdesc: &[D3D11_VIDEO_DECODER_BUFFER_DESC1]) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SubmitDecoderBuffers1)(windows_core::Interface::as_raw(self), pdecoder.param().abi(), pbufferdesc.len().try_into().unwrap(), core::mem::transmute(pbufferdesc.as_ptr())).ok() } + } + pub unsafe fn GetDataForNewHardwareKey(&self, pcryptosession: P0, pprivatinputdata: &[u8]) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDataForNewHardwareKey)(windows_core::Interface::as_raw(self), pcryptosession.param().abi(), pprivatinputdata.len().try_into().unwrap(), core::mem::transmute(pprivatinputdata.as_ptr()), &mut result__).map(|| result__) + } + } + pub unsafe fn CheckCryptoSessionStatus(&self, pcryptosession: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CheckCryptoSessionStatus)(windows_core::Interface::as_raw(self), pcryptosession.param().abi(), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn DecoderEnableDownsampling(&self, pdecoder: P0, inputcolorspace: super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE, poutputdesc: *const D3D11_VIDEO_SAMPLE_DESC, referenceframecount: u32) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DecoderEnableDownsampling)(windows_core::Interface::as_raw(self), pdecoder.param().abi(), inputcolorspace, poutputdesc, referenceframecount).ok() } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn DecoderUpdateDownsampling(&self, pdecoder: P0, poutputdesc: *const D3D11_VIDEO_SAMPLE_DESC) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DecoderUpdateDownsampling)(windows_core::Interface::as_raw(self), pdecoder.param().abi(), poutputdesc).ok() } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn VideoProcessorSetOutputColorSpace1(&self, pvideoprocessor: P0, colorspace: super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetOutputColorSpace1)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), colorspace) } + } + pub unsafe fn VideoProcessorSetOutputShaderUsage(&self, pvideoprocessor: P0, shaderusage: bool) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetOutputShaderUsage)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), shaderusage.into()) } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn VideoProcessorGetOutputColorSpace1(&self, pvideoprocessor: P0) -> super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).VideoProcessorGetOutputColorSpace1)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), &mut result__); + result__ + } + } + pub unsafe fn VideoProcessorGetOutputShaderUsage(&self, pvideoprocessor: P0) -> windows_core::BOOL + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).VideoProcessorGetOutputShaderUsage)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), &mut result__); + result__ + } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn VideoProcessorSetStreamColorSpace1(&self, pvideoprocessor: P0, streamindex: u32, colorspace: super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamColorSpace1)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, colorspace) } + } + pub unsafe fn VideoProcessorSetStreamMirror(&self, pvideoprocessor: P0, streamindex: u32, enable: bool, fliphorizontal: bool, flipvertical: bool) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamMirror)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, enable.into(), fliphorizontal.into(), flipvertical.into()) } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn VideoProcessorGetStreamColorSpace1(&self, pvideoprocessor: P0, streamindex: u32) -> super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).VideoProcessorGetStreamColorSpace1)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, &mut result__); + result__ + } + } + pub unsafe fn VideoProcessorGetStreamMirror(&self, pvideoprocessor: P0, streamindex: u32, penable: *mut windows_core::BOOL, pfliphorizontal: *mut windows_core::BOOL, pflipvertical: *mut windows_core::BOOL) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetStreamMirror)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, penable as _, pfliphorizontal as _, pflipvertical as _) } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn VideoProcessorGetBehaviorHints(&self, pvideoprocessor: P0, outputwidth: u32, outputheight: u32, outputformat: super::Dxgi::Common::DXGI_FORMAT, pstreams: &[D3D11_VIDEO_PROCESSOR_STREAM_BEHAVIOR_HINT]) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).VideoProcessorGetBehaviorHints)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), outputwidth, outputheight, outputformat, pstreams.len().try_into().unwrap(), core::mem::transmute(pstreams.as_ptr()), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11VideoContext1_Vtbl { @@ -28906,20 +115487,20 @@ unsafe impl Send for ID3D11VideoContext1 {} unsafe impl Sync for ID3D11VideoContext1 {} #[cfg(feature = "Win32_Graphics_Dxgi_Common")] pub trait ID3D11VideoContext1_Impl: ID3D11VideoContext_Impl { - fn SubmitDecoderBuffers1(&self, pdecoder: windows_core::Ref, numbuffers: u32, pbufferdesc: *const D3D11_VIDEO_DECODER_BUFFER_DESC1) -> windows_core::Result<()>; - fn GetDataForNewHardwareKey(&self, pcryptosession: windows_core::Ref, privateinputsize: u32, pprivatinputdata: *const core::ffi::c_void) -> windows_core::Result; - fn CheckCryptoSessionStatus(&self, pcryptosession: windows_core::Ref) -> windows_core::Result; - fn DecoderEnableDownsampling(&self, pdecoder: windows_core::Ref, inputcolorspace: super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE, poutputdesc: *const D3D11_VIDEO_SAMPLE_DESC, referenceframecount: u32) -> windows_core::Result<()>; - fn DecoderUpdateDownsampling(&self, pdecoder: windows_core::Ref, poutputdesc: *const D3D11_VIDEO_SAMPLE_DESC) -> windows_core::Result<()>; - fn VideoProcessorSetOutputColorSpace1(&self, pvideoprocessor: windows_core::Ref, colorspace: super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE); - fn VideoProcessorSetOutputShaderUsage(&self, pvideoprocessor: windows_core::Ref, shaderusage: windows_core::BOOL); - fn VideoProcessorGetOutputColorSpace1(&self, pvideoprocessor: windows_core::Ref, pcolorspace: *mut super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE); - fn VideoProcessorGetOutputShaderUsage(&self, pvideoprocessor: windows_core::Ref, pshaderusage: *mut windows_core::BOOL); - fn VideoProcessorSetStreamColorSpace1(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, colorspace: super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE); - fn VideoProcessorSetStreamMirror(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, enable: windows_core::BOOL, fliphorizontal: windows_core::BOOL, flipvertical: windows_core::BOOL); - fn VideoProcessorGetStreamColorSpace1(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, pcolorspace: *mut super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE); - fn VideoProcessorGetStreamMirror(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, penable: *mut windows_core::BOOL, pfliphorizontal: *mut windows_core::BOOL, pflipvertical: *mut windows_core::BOOL); - fn VideoProcessorGetBehaviorHints(&self, pvideoprocessor: windows_core::Ref, outputwidth: u32, outputheight: u32, outputformat: super::Dxgi::Common::DXGI_FORMAT, streamcount: u32, pstreams: *const D3D11_VIDEO_PROCESSOR_STREAM_BEHAVIOR_HINT) -> windows_core::Result; + fn SubmitDecoderBuffers1(&self, pdecoder: windows_core::Ref<'_, ID3D11VideoDecoder>, numbuffers: u32, pbufferdesc: *const D3D11_VIDEO_DECODER_BUFFER_DESC1) -> windows_core::Result<()>; + fn GetDataForNewHardwareKey(&self, pcryptosession: windows_core::Ref<'_, ID3D11CryptoSession>, privateinputsize: u32, pprivatinputdata: *const core::ffi::c_void) -> windows_core::Result; + fn CheckCryptoSessionStatus(&self, pcryptosession: windows_core::Ref<'_, ID3D11CryptoSession>) -> windows_core::Result; + fn DecoderEnableDownsampling(&self, pdecoder: windows_core::Ref<'_, ID3D11VideoDecoder>, inputcolorspace: super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE, poutputdesc: *const D3D11_VIDEO_SAMPLE_DESC, referenceframecount: u32) -> windows_core::Result<()>; + fn DecoderUpdateDownsampling(&self, pdecoder: windows_core::Ref<'_, ID3D11VideoDecoder>, poutputdesc: *const D3D11_VIDEO_SAMPLE_DESC) -> windows_core::Result<()>; + fn VideoProcessorSetOutputColorSpace1(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, colorspace: super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE); + fn VideoProcessorSetOutputShaderUsage(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, shaderusage: windows_core::BOOL); + fn VideoProcessorGetOutputColorSpace1(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, pcolorspace: *mut super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE); + fn VideoProcessorGetOutputShaderUsage(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, pshaderusage: *mut windows_core::BOOL); + fn VideoProcessorSetStreamColorSpace1(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, colorspace: super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE); + fn VideoProcessorSetStreamMirror(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, enable: windows_core::BOOL, fliphorizontal: windows_core::BOOL, flipvertical: windows_core::BOOL); + fn VideoProcessorGetStreamColorSpace1(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, pcolorspace: *mut super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE); + fn VideoProcessorGetStreamMirror(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, penable: *mut windows_core::BOOL, pfliphorizontal: *mut windows_core::BOOL, pflipvertical: *mut windows_core::BOOL); + fn VideoProcessorGetBehaviorHints(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, outputwidth: u32, outputheight: u32, outputformat: super::Dxgi::Common::DXGI_FORMAT, streamcount: u32, pstreams: *const D3D11_VIDEO_PROCESSOR_STREAM_BEHAVIOR_HINT) -> windows_core::Result; } #[cfg(feature = "Win32_Graphics_Dxgi_Common")] impl ID3D11VideoContext1_Vtbl { @@ -29058,6 +115639,36 @@ impl core::ops::Deref for ID3D11VideoContext2 { } } windows_core::imp::interface_hierarchy!(ID3D11VideoContext2, windows_core::IUnknown, ID3D11DeviceChild, ID3D11VideoContext, ID3D11VideoContext1); +impl ID3D11VideoContext2 { + #[cfg(feature = "Win32_Graphics_Dxgi")] + pub unsafe fn VideoProcessorSetOutputHDRMetaData(&self, pvideoprocessor: P0, r#type: super::Dxgi::DXGI_HDR_METADATA_TYPE, size: u32, phdrmetadata: Option<*const core::ffi::c_void>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetOutputHDRMetaData)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), r#type, size, phdrmetadata.unwrap_or(core::mem::zeroed()) as _) } + } + #[cfg(feature = "Win32_Graphics_Dxgi")] + pub unsafe fn VideoProcessorGetOutputHDRMetaData(&self, pvideoprocessor: P0, ptype: *mut super::Dxgi::DXGI_HDR_METADATA_TYPE, size: u32, pmetadata: Option<*mut core::ffi::c_void>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetOutputHDRMetaData)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), ptype as _, size, pmetadata.unwrap_or(core::mem::zeroed()) as _) } + } + #[cfg(feature = "Win32_Graphics_Dxgi")] + pub unsafe fn VideoProcessorSetStreamHDRMetaData(&self, pvideoprocessor: P0, streamindex: u32, r#type: super::Dxgi::DXGI_HDR_METADATA_TYPE, size: u32, phdrmetadata: Option<*const core::ffi::c_void>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorSetStreamHDRMetaData)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, r#type, size, phdrmetadata.unwrap_or(core::mem::zeroed()) as _) } + } + #[cfg(feature = "Win32_Graphics_Dxgi")] + pub unsafe fn VideoProcessorGetStreamHDRMetaData(&self, pvideoprocessor: P0, streamindex: u32, ptype: *mut super::Dxgi::DXGI_HDR_METADATA_TYPE, size: u32, pmetadata: Option<*mut core::ffi::c_void>) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).VideoProcessorGetStreamHDRMetaData)(windows_core::Interface::as_raw(self), pvideoprocessor.param().abi(), streamindex, ptype as _, size, pmetadata.unwrap_or(core::mem::zeroed()) as _) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11VideoContext2_Vtbl { @@ -29083,10 +115694,10 @@ unsafe impl Send for ID3D11VideoContext2 {} unsafe impl Sync for ID3D11VideoContext2 {} #[cfg(feature = "Win32_Graphics_Dxgi_Common")] pub trait ID3D11VideoContext2_Impl: ID3D11VideoContext1_Impl { - fn VideoProcessorSetOutputHDRMetaData(&self, pvideoprocessor: windows_core::Ref, r#type: super::Dxgi::DXGI_HDR_METADATA_TYPE, size: u32, phdrmetadata: *const core::ffi::c_void); - fn VideoProcessorGetOutputHDRMetaData(&self, pvideoprocessor: windows_core::Ref, ptype: *mut super::Dxgi::DXGI_HDR_METADATA_TYPE, size: u32, pmetadata: *mut core::ffi::c_void); - fn VideoProcessorSetStreamHDRMetaData(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, r#type: super::Dxgi::DXGI_HDR_METADATA_TYPE, size: u32, phdrmetadata: *const core::ffi::c_void); - fn VideoProcessorGetStreamHDRMetaData(&self, pvideoprocessor: windows_core::Ref, streamindex: u32, ptype: *mut super::Dxgi::DXGI_HDR_METADATA_TYPE, size: u32, pmetadata: *mut core::ffi::c_void); + fn VideoProcessorSetOutputHDRMetaData(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, r#type: super::Dxgi::DXGI_HDR_METADATA_TYPE, size: u32, phdrmetadata: *const core::ffi::c_void); + fn VideoProcessorGetOutputHDRMetaData(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, ptype: *mut super::Dxgi::DXGI_HDR_METADATA_TYPE, size: u32, pmetadata: *mut core::ffi::c_void); + fn VideoProcessorSetStreamHDRMetaData(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, r#type: super::Dxgi::DXGI_HDR_METADATA_TYPE, size: u32, phdrmetadata: *const core::ffi::c_void); + fn VideoProcessorGetStreamHDRMetaData(&self, pvideoprocessor: windows_core::Ref<'_, ID3D11VideoProcessor>, streamindex: u32, ptype: *mut super::Dxgi::DXGI_HDR_METADATA_TYPE, size: u32, pmetadata: *mut core::ffi::c_void); } #[cfg(feature = "Win32_Graphics_Dxgi_Common")] impl ID3D11VideoContext2_Vtbl { @@ -29137,6 +115748,21 @@ impl core::ops::Deref for ID3D11VideoContext3 { } } windows_core::imp::interface_hierarchy!(ID3D11VideoContext3, windows_core::IUnknown, ID3D11DeviceChild, ID3D11VideoContext, ID3D11VideoContext1, ID3D11VideoContext2); +impl ID3D11VideoContext3 { + pub unsafe fn DecoderBeginFrame1(&self, pdecoder: P0, pview: P1, contentkeysize: u32, pcontentkey: Option<*const core::ffi::c_void>, numcomponenthistograms: u32, phistogramoffsets: Option<*const u32>, pphistogrambuffers: Option<*const Option>) -> windows_core::Result<()> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DecoderBeginFrame1)(windows_core::Interface::as_raw(self), pdecoder.param().abi(), pview.param().abi(), contentkeysize, pcontentkey.unwrap_or(core::mem::zeroed()) as _, numcomponenthistograms, phistogramoffsets.unwrap_or(core::mem::zeroed()) as _, pphistogrambuffers.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn SubmitDecoderBuffers2(&self, pdecoder: P0, pbufferdesc: &[D3D11_VIDEO_DECODER_BUFFER_DESC2]) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SubmitDecoderBuffers2)(windows_core::Interface::as_raw(self), pdecoder.param().abi(), pbufferdesc.len().try_into().unwrap(), core::mem::transmute(pbufferdesc.as_ptr())).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11VideoContext3_Vtbl { @@ -29148,8 +115774,8 @@ unsafe impl Send for ID3D11VideoContext3 {} unsafe impl Sync for ID3D11VideoContext3 {} #[cfg(feature = "Win32_Graphics_Dxgi_Common")] pub trait ID3D11VideoContext3_Impl: ID3D11VideoContext2_Impl { - fn DecoderBeginFrame1(&self, pdecoder: windows_core::Ref, pview: windows_core::Ref, contentkeysize: u32, pcontentkey: *const core::ffi::c_void, numcomponenthistograms: u32, phistogramoffsets: *const u32, pphistogrambuffers: *const Option) -> windows_core::Result<()>; - fn SubmitDecoderBuffers2(&self, pdecoder: windows_core::Ref, numbuffers: u32, pbufferdesc: *const D3D11_VIDEO_DECODER_BUFFER_DESC2) -> windows_core::Result<()>; + fn DecoderBeginFrame1(&self, pdecoder: windows_core::Ref<'_, ID3D11VideoDecoder>, pview: windows_core::Ref<'_, ID3D11VideoDecoderOutputView>, contentkeysize: u32, pcontentkey: *const core::ffi::c_void, numcomponenthistograms: u32, phistogramoffsets: *const u32, pphistogrambuffers: *const Option) -> windows_core::Result<()>; + fn SubmitDecoderBuffers2(&self, pdecoder: windows_core::Ref<'_, ID3D11VideoDecoder>, numbuffers: u32, pbufferdesc: *const D3D11_VIDEO_DECODER_BUFFER_DESC2) -> windows_core::Result<()>; } #[cfg(feature = "Win32_Graphics_Dxgi_Common")] impl ID3D11VideoContext3_Vtbl { @@ -29186,6 +115812,18 @@ impl core::ops::Deref for ID3D11VideoDecoder { } } windows_core::imp::interface_hierarchy!(ID3D11VideoDecoder, windows_core::IUnknown, ID3D11DeviceChild); +impl ID3D11VideoDecoder { + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn GetCreationParameters(&self, pvideodesc: *mut D3D11_VIDEO_DECODER_DESC, pconfig: *mut D3D11_VIDEO_DECODER_CONFIG) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetCreationParameters)(windows_core::Interface::as_raw(self), pvideodesc as _, pconfig as _).ok() } + } + pub unsafe fn GetDriverHandle(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDriverHandle)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11VideoDecoder_Vtbl { @@ -29283,6 +115921,15 @@ impl core::ops::Deref for ID3D11VideoProcessor { } } windows_core::imp::interface_hierarchy!(ID3D11VideoProcessor, windows_core::IUnknown, ID3D11DeviceChild); +impl ID3D11VideoProcessor { + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn GetContentDesc(&self, pdesc: *mut D3D11_VIDEO_PROCESSOR_CONTENT_DESC) { + unsafe { (windows_core::Interface::vtable(self).GetContentDesc)(windows_core::Interface::as_raw(self), pdesc as _) } + } + pub unsafe fn GetRateConversionCaps(&self, pcaps: *mut D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS) { + unsafe { (windows_core::Interface::vtable(self).GetRateConversionCaps)(windows_core::Interface::as_raw(self), pcaps as _) } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11VideoProcessor_Vtbl { @@ -29335,6 +115982,35 @@ impl core::ops::Deref for ID3D11VideoProcessorEnumerator { } } windows_core::imp::interface_hierarchy!(ID3D11VideoProcessorEnumerator, windows_core::IUnknown, ID3D11DeviceChild); +impl ID3D11VideoProcessorEnumerator { + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn GetVideoProcessorContentDesc(&self, pcontentdesc: *mut D3D11_VIDEO_PROCESSOR_CONTENT_DESC) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetVideoProcessorContentDesc)(windows_core::Interface::as_raw(self), pcontentdesc as _).ok() } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CheckVideoProcessorFormat(&self, format: super::Dxgi::Common::DXGI_FORMAT) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CheckVideoProcessorFormat)(windows_core::Interface::as_raw(self), format, &mut result__).map(|| result__) + } + } + pub unsafe fn GetVideoProcessorCaps(&self, pcaps: *mut D3D11_VIDEO_PROCESSOR_CAPS) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetVideoProcessorCaps)(windows_core::Interface::as_raw(self), pcaps as _).ok() } + } + pub unsafe fn GetVideoProcessorRateConversionCaps(&self, typeindex: u32, pcaps: *mut D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetVideoProcessorRateConversionCaps)(windows_core::Interface::as_raw(self), typeindex, pcaps as _).ok() } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn GetVideoProcessorCustomRate(&self, typeindex: u32, customrateindex: u32, prate: *mut D3D11_VIDEO_PROCESSOR_CUSTOM_RATE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetVideoProcessorCustomRate)(windows_core::Interface::as_raw(self), typeindex, customrateindex, prate as _).ok() } + } + pub unsafe fn GetVideoProcessorFilterRange(&self, filter: D3D11_VIDEO_PROCESSOR_FILTER) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetVideoProcessorFilterRange)(windows_core::Interface::as_raw(self), filter, &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11VideoProcessorEnumerator_Vtbl { @@ -29441,6 +116117,15 @@ impl core::ops::Deref for ID3D11VideoProcessorEnumerator1 { } } windows_core::imp::interface_hierarchy!(ID3D11VideoProcessorEnumerator1, windows_core::IUnknown, ID3D11DeviceChild, ID3D11VideoProcessorEnumerator); +impl ID3D11VideoProcessorEnumerator1 { + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CheckVideoProcessorFormatConversion(&self, inputformat: super::Dxgi::Common::DXGI_FORMAT, inputcolorspace: super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE, outputformat: super::Dxgi::Common::DXGI_FORMAT, outputcolorspace: super::Dxgi::Common::DXGI_COLOR_SPACE_TYPE) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CheckVideoProcessorFormatConversion)(windows_core::Interface::as_raw(self), inputformat, inputcolorspace, outputformat, outputcolorspace, &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct ID3D11VideoProcessorEnumerator1_Vtbl { @@ -29594,7 +116279,7 @@ pub struct ID3D11View_Vtbl { unsafe impl Send for ID3D11View {} unsafe impl Sync for ID3D11View {} pub trait ID3D11View_Impl: ID3D11DeviceChild_Impl { - fn GetResource(&self, ppresource: windows_core::OutRef); + fn GetResource(&self, ppresource: windows_core::OutRef<'_, ID3D11Resource>); } impl ID3D11View_Vtbl { pub const fn new() -> Self { @@ -29637,6 +116322,7 @@ impl ID3DDeviceContextState_Vtbl { } impl windows_core::RuntimeName for ID3DDeviceContextState {} } +#[cfg(feature = "Win32_Graphics_Dwm")] pub mod Dwm{ #[cfg(feature = "Win32_UI_Controls")] #[inline] @@ -29674,6 +116360,7 @@ pub struct DWM_SYSTEMBACKDROP_TYPE(pub i32); #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct DWM_WINDOW_CORNER_PREFERENCE(pub i32); } +#[cfg(feature = "Win32_Graphics_Dxgi")] pub mod Dxgi{ #[inline] pub unsafe fn CreateDXGIFactory2(flags: DXGI_CREATE_FACTORY_FLAGS) -> windows_core::Result @@ -30343,13 +117030,25 @@ impl core::ops::Deref for IDXGIAdapter { } windows_core::imp::interface_hierarchy!(IDXGIAdapter, windows_core::IUnknown, IDXGIObject); impl IDXGIAdapter { + pub unsafe fn EnumOutputs(&self, output: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).EnumOutputs)(windows_core::Interface::as_raw(self), output, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub unsafe fn GetDesc(&self) -> windows_core::Result { unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(self).GetDesc)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) } } + pub unsafe fn CheckInterfaceSupport(&self, interfacename: *const windows_core::GUID) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CheckInterfaceSupport)(windows_core::Interface::as_raw(self), interfacename, &mut result__).map(|| result__) + } } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIAdapter_Vtbl { @@ -30423,6 +117122,14 @@ impl core::ops::Deref for IDXGIAdapter1 { } } windows_core::imp::interface_hierarchy!(IDXGIAdapter1, windows_core::IUnknown, IDXGIObject, IDXGIAdapter); +impl IDXGIAdapter1 { + pub unsafe fn GetDesc1(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDesc1)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIAdapter1_Vtbl { @@ -30463,6 +117170,14 @@ impl core::ops::Deref for IDXGIAdapter2 { } } windows_core::imp::interface_hierarchy!(IDXGIAdapter2, windows_core::IUnknown, IDXGIObject, IDXGIAdapter, IDXGIAdapter1); +impl IDXGIAdapter2 { + pub unsafe fn GetDesc2(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDesc2)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIAdapter2_Vtbl { @@ -30503,6 +117218,32 @@ impl core::ops::Deref for IDXGIAdapter3 { } } windows_core::imp::interface_hierarchy!(IDXGIAdapter3, windows_core::IUnknown, IDXGIObject, IDXGIAdapter, IDXGIAdapter1, IDXGIAdapter2); +impl IDXGIAdapter3 { + pub unsafe fn RegisterHardwareContentProtectionTeardownStatusEvent(&self, hevent: super::super::Foundation::HANDLE) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).RegisterHardwareContentProtectionTeardownStatusEvent)(windows_core::Interface::as_raw(self), hevent, &mut result__).map(|| result__) + } + } + pub unsafe fn UnregisterHardwareContentProtectionTeardownStatus(&self, dwcookie: u32) { + unsafe { (windows_core::Interface::vtable(self).UnregisterHardwareContentProtectionTeardownStatus)(windows_core::Interface::as_raw(self), dwcookie) } + } + pub unsafe fn QueryVideoMemoryInfo(&self, nodeindex: u32, memorysegmentgroup: DXGI_MEMORY_SEGMENT_GROUP, pvideomemoryinfo: *mut DXGI_QUERY_VIDEO_MEMORY_INFO) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).QueryVideoMemoryInfo)(windows_core::Interface::as_raw(self), nodeindex, memorysegmentgroup, pvideomemoryinfo as _).ok() } + } + pub unsafe fn SetVideoMemoryReservation(&self, nodeindex: u32, memorysegmentgroup: DXGI_MEMORY_SEGMENT_GROUP, reservation: u64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetVideoMemoryReservation)(windows_core::Interface::as_raw(self), nodeindex, memorysegmentgroup, reservation).ok() } + } + pub unsafe fn RegisterVideoMemoryBudgetChangeNotificationEvent(&self, hevent: super::super::Foundation::HANDLE) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).RegisterVideoMemoryBudgetChangeNotificationEvent)(windows_core::Interface::as_raw(self), hevent, &mut result__).map(|| result__) + } + } + pub unsafe fn UnregisterVideoMemoryBudgetChangeNotification(&self, dwcookie: u32) { + unsafe { (windows_core::Interface::vtable(self).UnregisterVideoMemoryBudgetChangeNotification)(windows_core::Interface::as_raw(self), dwcookie) } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIAdapter3_Vtbl { @@ -30597,6 +117338,14 @@ impl core::ops::Deref for IDXGIAdapter4 { } } windows_core::imp::interface_hierarchy!(IDXGIAdapter4, windows_core::IUnknown, IDXGIObject, IDXGIAdapter, IDXGIAdapter1, IDXGIAdapter2, IDXGIAdapter3); +impl IDXGIAdapter4 { + pub unsafe fn GetDesc3(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDesc3)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIAdapter4_Vtbl { @@ -30637,6 +117386,30 @@ impl core::ops::Deref for IDXGIDevice { } } windows_core::imp::interface_hierarchy!(IDXGIDevice, windows_core::IUnknown, IDXGIObject); +impl IDXGIDevice { + pub unsafe fn GetAdapter(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetAdapter)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CreateSurface(&self, pdesc: *const DXGI_SURFACE_DESC, usage: DXGI_USAGE, psharedresource: Option<*const DXGI_SHARED_RESOURCE>, ppsurface: &mut [Option]) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CreateSurface)(windows_core::Interface::as_raw(self), pdesc, ppsurface.len().try_into().unwrap(), usage, psharedresource.unwrap_or(core::mem::zeroed()) as _, core::mem::transmute(ppsurface.as_ptr())).ok() } + } + pub unsafe fn QueryResourceResidency(&self, ppresources: *const Option, presidencystatus: *mut DXGI_RESIDENCY, numresources: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).QueryResourceResidency)(windows_core::Interface::as_raw(self), core::mem::transmute(ppresources), presidencystatus as _, numresources).ok() } + } + pub unsafe fn SetGPUThreadPriority(&self, priority: i32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetGPUThreadPriority)(windows_core::Interface::as_raw(self), priority).ok() } + } + pub unsafe fn GetGPUThreadPriority(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetGPUThreadPriority)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIDevice_Vtbl { @@ -30732,7 +117505,13 @@ impl IDXGIDevice1 { pub unsafe fn SetMaximumFrameLatency(&self, maxlatency: u32) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetMaximumFrameLatency)(windows_core::Interface::as_raw(self), maxlatency).ok() } } + pub unsafe fn GetMaximumFrameLatency(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMaximumFrameLatency)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIDevice1_Vtbl { @@ -30788,6 +117567,17 @@ impl core::ops::Deref for IDXGIDevice2 { } } windows_core::imp::interface_hierarchy!(IDXGIDevice2, windows_core::IUnknown, IDXGIObject, IDXGIDevice, IDXGIDevice1); +impl IDXGIDevice2 { + pub unsafe fn OfferResources(&self, ppresources: &[Option], priority: DXGI_OFFER_RESOURCE_PRIORITY) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).OfferResources)(windows_core::Interface::as_raw(self), ppresources.len().try_into().unwrap(), core::mem::transmute(ppresources.as_ptr()), priority).ok() } + } + pub unsafe fn ReclaimResources(&self, numresources: u32, ppresources: *const Option, pdiscarded: Option<*mut windows_core::BOOL>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).ReclaimResources)(windows_core::Interface::as_raw(self), numresources, core::mem::transmute(ppresources), pdiscarded.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn EnqueueSetEvent(&self, hevent: super::super::Foundation::HANDLE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).EnqueueSetEvent)(windows_core::Interface::as_raw(self), hevent).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIDevice2_Vtbl { @@ -30846,6 +117636,11 @@ impl core::ops::Deref for IDXGIDevice3 { } } windows_core::imp::interface_hierarchy!(IDXGIDevice3, windows_core::IUnknown, IDXGIObject, IDXGIDevice, IDXGIDevice1, IDXGIDevice2); +impl IDXGIDevice3 { + pub unsafe fn Trim(&self) { + unsafe { (windows_core::Interface::vtable(self).Trim)(windows_core::Interface::as_raw(self)) } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIDevice3_Vtbl { @@ -30883,6 +117678,14 @@ impl core::ops::Deref for IDXGIDevice4 { } } windows_core::imp::interface_hierarchy!(IDXGIDevice4, windows_core::IUnknown, IDXGIObject, IDXGIDevice, IDXGIDevice1, IDXGIDevice2, IDXGIDevice3); +impl IDXGIDevice4 { + pub unsafe fn OfferResources1(&self, ppresources: &[Option], priority: DXGI_OFFER_RESOURCE_PRIORITY, flags: DXGI_OFFER_RESOURCE_FLAGS) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).OfferResources1)(windows_core::Interface::as_raw(self), ppresources.len().try_into().unwrap(), core::mem::transmute(ppresources.as_ptr()), priority, flags.0 as _).ok() } + } + pub unsafe fn ReclaimResources1(&self, numresources: u32, ppresources: *const Option, presults: *mut DXGI_RECLAIM_RESOURCE_RESULTS) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).ReclaimResources1)(windows_core::Interface::as_raw(self), numresources, core::mem::transmute(ppresources), presults as _).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIDevice4_Vtbl { @@ -30932,6 +117735,15 @@ impl core::ops::Deref for IDXGIDeviceSubObject { } } windows_core::imp::interface_hierarchy!(IDXGIDeviceSubObject, windows_core::IUnknown, IDXGIObject); +impl IDXGIDeviceSubObject { + pub unsafe fn GetDevice(&self) -> windows_core::Result + where + T: windows_core::Interface, + { + let mut result__ = core::ptr::null_mut(); + unsafe { (windows_core::Interface::vtable(self).GetDevice)(windows_core::Interface::as_raw(self), &T::IID, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIDeviceSubObject_Vtbl { @@ -30973,7 +117785,29 @@ impl IDXGIFactory { (windows_core::Interface::vtable(self).EnumAdapters)(windows_core::Interface::as_raw(self), adapter, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub unsafe fn MakeWindowAssociation(&self, windowhandle: super::super::Foundation::HWND, flags: DXGI_MWA_FLAGS) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).MakeWindowAssociation)(windows_core::Interface::as_raw(self), windowhandle, flags).ok() } } + pub unsafe fn GetWindowAssociation(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetWindowAssociation)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CreateSwapChain(&self, pdevice: P0, pdesc: *const DXGI_SWAP_CHAIN_DESC, ppswapchain: *mut Option) -> windows_core::HRESULT + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CreateSwapChain)(windows_core::Interface::as_raw(self), pdevice.param().abi(), pdesc, core::mem::transmute(ppswapchain)) } + } + pub unsafe fn CreateSoftwareAdapter(&self, module: super::super::Foundation::HMODULE) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateSoftwareAdapter)(windows_core::Interface::as_raw(self), module, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIFactory_Vtbl { @@ -30994,7 +117828,7 @@ pub trait IDXGIFactory_Impl: IDXGIObject_Impl { fn EnumAdapters(&self, adapter: u32) -> windows_core::Result; fn MakeWindowAssociation(&self, windowhandle: super::super::Foundation::HWND, flags: DXGI_MWA_FLAGS) -> windows_core::Result<()>; fn GetWindowAssociation(&self) -> windows_core::Result; - fn CreateSwapChain(&self, pdevice: windows_core::Ref, pdesc: *const DXGI_SWAP_CHAIN_DESC, ppswapchain: windows_core::OutRef) -> windows_core::HRESULT; + fn CreateSwapChain(&self, pdevice: windows_core::Ref<'_, windows_core::IUnknown>, pdesc: *const DXGI_SWAP_CHAIN_DESC, ppswapchain: windows_core::OutRef<'_, IDXGISwapChain>) -> windows_core::HRESULT; fn CreateSoftwareAdapter(&self, module: super::super::Foundation::HMODULE) -> windows_core::Result; } #[cfg(feature = "Win32_Graphics_Dxgi_Common")] @@ -31071,6 +117905,17 @@ impl core::ops::Deref for IDXGIFactory1 { } } windows_core::imp::interface_hierarchy!(IDXGIFactory1, windows_core::IUnknown, IDXGIObject, IDXGIFactory); +impl IDXGIFactory1 { + pub unsafe fn EnumAdapters1(&self, adapter: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).EnumAdapters1)(windows_core::Interface::as_raw(self), adapter, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn IsCurrent(&self) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).IsCurrent)(windows_core::Interface::as_raw(self)) } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIFactory1_Vtbl { @@ -31123,6 +117968,9 @@ impl core::ops::Deref for IDXGIFactory2 { } windows_core::imp::interface_hierarchy!(IDXGIFactory2, windows_core::IUnknown, IDXGIObject, IDXGIFactory, IDXGIFactory1); impl IDXGIFactory2 { + pub unsafe fn IsWindowedStereoEnabled(&self) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).IsWindowedStereoEnabled)(windows_core::Interface::as_raw(self)) } + } #[cfg(feature = "Win32_Graphics_Dxgi_Common")] pub unsafe fn CreateSwapChainForHwnd(&self, pdevice: P0, hwnd: super::super::Foundation::HWND, pdesc: *const DXGI_SWAP_CHAIN_DESC1, pfullscreendesc: Option<*const DXGI_SWAP_CHAIN_FULLSCREEN_DESC>, prestricttooutput: P4) -> windows_core::Result where @@ -31134,7 +117982,66 @@ impl IDXGIFactory2 { (windows_core::Interface::vtable(self).CreateSwapChainForHwnd)(windows_core::Interface::as_raw(self), pdevice.param().abi(), hwnd, pdesc, pfullscreendesc.unwrap_or(core::mem::zeroed()) as _, prestricttooutput.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CreateSwapChainForCoreWindow(&self, pdevice: P0, pwindow: P1, pdesc: *const DXGI_SWAP_CHAIN_DESC1, prestricttooutput: P3) -> windows_core::Result + where + P0: windows_core::Param, + P1: windows_core::Param, + P3: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateSwapChainForCoreWindow)(windows_core::Interface::as_raw(self), pdevice.param().abi(), pwindow.param().abi(), pdesc, prestricttooutput.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub unsafe fn GetSharedResourceAdapterLuid(&self, hresource: super::super::Foundation::HANDLE) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetSharedResourceAdapterLuid)(windows_core::Interface::as_raw(self), hresource, &mut result__).map(|| result__) + } + } + pub unsafe fn RegisterStereoStatusWindow(&self, windowhandle: super::super::Foundation::HWND, wmsg: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).RegisterStereoStatusWindow)(windows_core::Interface::as_raw(self), windowhandle, wmsg, &mut result__).map(|| result__) + } + } + pub unsafe fn RegisterStereoStatusEvent(&self, hevent: super::super::Foundation::HANDLE) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).RegisterStereoStatusEvent)(windows_core::Interface::as_raw(self), hevent, &mut result__).map(|| result__) + } + } + pub unsafe fn UnregisterStereoStatus(&self, dwcookie: u32) { + unsafe { (windows_core::Interface::vtable(self).UnregisterStereoStatus)(windows_core::Interface::as_raw(self), dwcookie) } + } + pub unsafe fn RegisterOcclusionStatusWindow(&self, windowhandle: super::super::Foundation::HWND, wmsg: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).RegisterOcclusionStatusWindow)(windows_core::Interface::as_raw(self), windowhandle, wmsg, &mut result__).map(|| result__) + } + } + pub unsafe fn RegisterOcclusionStatusEvent(&self, hevent: super::super::Foundation::HANDLE) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).RegisterOcclusionStatusEvent)(windows_core::Interface::as_raw(self), hevent, &mut result__).map(|| result__) + } + } + pub unsafe fn UnregisterOcclusionStatus(&self, dwcookie: u32) { + unsafe { (windows_core::Interface::vtable(self).UnregisterOcclusionStatus)(windows_core::Interface::as_raw(self), dwcookie) } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CreateSwapChainForComposition(&self, pdevice: P0, pdesc: *const DXGI_SWAP_CHAIN_DESC1, prestricttooutput: P2) -> windows_core::Result + where + P0: windows_core::Param, + P2: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateSwapChainForComposition)(windows_core::Interface::as_raw(self), pdevice.param().abi(), pdesc, prestricttooutput.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIFactory2_Vtbl { @@ -31165,8 +118072,8 @@ unsafe impl Sync for IDXGIFactory2 {} #[cfg(feature = "Win32_Graphics_Dxgi_Common")] pub trait IDXGIFactory2_Impl: IDXGIFactory1_Impl { fn IsWindowedStereoEnabled(&self) -> windows_core::BOOL; - fn CreateSwapChainForHwnd(&self, pdevice: windows_core::Ref, hwnd: super::super::Foundation::HWND, pdesc: *const DXGI_SWAP_CHAIN_DESC1, pfullscreendesc: *const DXGI_SWAP_CHAIN_FULLSCREEN_DESC, prestricttooutput: windows_core::Ref) -> windows_core::Result; - fn CreateSwapChainForCoreWindow(&self, pdevice: windows_core::Ref, pwindow: windows_core::Ref, pdesc: *const DXGI_SWAP_CHAIN_DESC1, prestricttooutput: windows_core::Ref) -> windows_core::Result; + fn CreateSwapChainForHwnd(&self, pdevice: windows_core::Ref<'_, windows_core::IUnknown>, hwnd: super::super::Foundation::HWND, pdesc: *const DXGI_SWAP_CHAIN_DESC1, pfullscreendesc: *const DXGI_SWAP_CHAIN_FULLSCREEN_DESC, prestricttooutput: windows_core::Ref<'_, IDXGIOutput>) -> windows_core::Result; + fn CreateSwapChainForCoreWindow(&self, pdevice: windows_core::Ref<'_, windows_core::IUnknown>, pwindow: windows_core::Ref<'_, windows_core::IUnknown>, pdesc: *const DXGI_SWAP_CHAIN_DESC1, prestricttooutput: windows_core::Ref<'_, IDXGIOutput>) -> windows_core::Result; fn GetSharedResourceAdapterLuid(&self, hresource: super::super::Foundation::HANDLE) -> windows_core::Result; fn RegisterStereoStatusWindow(&self, windowhandle: super::super::Foundation::HWND, wmsg: u32) -> windows_core::Result; fn RegisterStereoStatusEvent(&self, hevent: super::super::Foundation::HANDLE) -> windows_core::Result; @@ -31174,7 +118081,7 @@ pub trait IDXGIFactory2_Impl: IDXGIFactory1_Impl { fn RegisterOcclusionStatusWindow(&self, windowhandle: super::super::Foundation::HWND, wmsg: u32) -> windows_core::Result; fn RegisterOcclusionStatusEvent(&self, hevent: super::super::Foundation::HANDLE) -> windows_core::Result; fn UnregisterOcclusionStatus(&self, dwcookie: u32); - fn CreateSwapChainForComposition(&self, pdevice: windows_core::Ref, pdesc: *const DXGI_SWAP_CHAIN_DESC1, prestricttooutput: windows_core::Ref) -> windows_core::Result; + fn CreateSwapChainForComposition(&self, pdevice: windows_core::Ref<'_, windows_core::IUnknown>, pdesc: *const DXGI_SWAP_CHAIN_DESC1, prestricttooutput: windows_core::Ref<'_, IDXGIOutput>) -> windows_core::Result; } #[cfg(feature = "Win32_Graphics_Dxgi_Common")] impl IDXGIFactory2_Vtbl { @@ -31322,6 +118229,11 @@ impl core::ops::Deref for IDXGIFactory3 { } } windows_core::imp::interface_hierarchy!(IDXGIFactory3, windows_core::IUnknown, IDXGIObject, IDXGIFactory, IDXGIFactory1, IDXGIFactory2); +impl IDXGIFactory3 { + pub unsafe fn GetCreationFlags(&self) -> DXGI_CREATE_FACTORY_FLAGS { + unsafe { (windows_core::Interface::vtable(self).GetCreationFlags)(windows_core::Interface::as_raw(self)) } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIFactory3_Vtbl { @@ -31359,6 +118271,22 @@ impl core::ops::Deref for IDXGIFactory4 { } } windows_core::imp::interface_hierarchy!(IDXGIFactory4, windows_core::IUnknown, IDXGIObject, IDXGIFactory, IDXGIFactory1, IDXGIFactory2, IDXGIFactory3); +impl IDXGIFactory4 { + pub unsafe fn EnumAdapterByLuid(&self, adapterluid: super::super::Foundation::LUID) -> windows_core::Result + where + T: windows_core::Interface, + { + let mut result__ = core::ptr::null_mut(); + unsafe { (windows_core::Interface::vtable(self).EnumAdapterByLuid)(windows_core::Interface::as_raw(self), core::mem::transmute(adapterluid), &T::IID, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } + } + pub unsafe fn EnumWarpAdapter(&self) -> windows_core::Result + where + T: windows_core::Interface, + { + let mut result__ = core::ptr::null_mut(); + unsafe { (windows_core::Interface::vtable(self).EnumWarpAdapter)(windows_core::Interface::as_raw(self), &T::IID, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIFactory4_Vtbl { @@ -31408,6 +118336,11 @@ impl core::ops::Deref for IDXGIFactory5 { } } windows_core::imp::interface_hierarchy!(IDXGIFactory5, windows_core::IUnknown, IDXGIObject, IDXGIFactory, IDXGIFactory1, IDXGIFactory2, IDXGIFactory3, IDXGIFactory4); +impl IDXGIFactory5 { + pub unsafe fn CheckFeatureSupport(&self, feature: DXGI_FEATURE, pfeaturesupportdata: *mut core::ffi::c_void, featuresupportdatasize: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CheckFeatureSupport)(windows_core::Interface::as_raw(self), feature, pfeaturesupportdata as _, featuresupportdatasize).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIFactory5_Vtbl { @@ -31445,6 +118378,15 @@ impl core::ops::Deref for IDXGIFactory6 { } } windows_core::imp::interface_hierarchy!(IDXGIFactory6, windows_core::IUnknown, IDXGIObject, IDXGIFactory, IDXGIFactory1, IDXGIFactory2, IDXGIFactory3, IDXGIFactory4, IDXGIFactory5); +impl IDXGIFactory6 { + pub unsafe fn EnumAdapterByGpuPreference(&self, adapter: u32, gpupreference: DXGI_GPU_PREFERENCE) -> windows_core::Result + where + T: windows_core::Interface, + { + let mut result__ = core::ptr::null_mut(); + unsafe { (windows_core::Interface::vtable(self).EnumAdapterByGpuPreference)(windows_core::Interface::as_raw(self), adapter, gpupreference, &T::IID, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIFactory6_Vtbl { @@ -31482,6 +118424,17 @@ impl core::ops::Deref for IDXGIFactory7 { } } windows_core::imp::interface_hierarchy!(IDXGIFactory7, windows_core::IUnknown, IDXGIObject, IDXGIFactory, IDXGIFactory1, IDXGIFactory2, IDXGIFactory3, IDXGIFactory4, IDXGIFactory5, IDXGIFactory6); +impl IDXGIFactory7 { + pub unsafe fn RegisterAdaptersChangedEvent(&self, hevent: super::super::Foundation::HANDLE) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).RegisterAdaptersChangedEvent)(windows_core::Interface::as_raw(self), hevent, &mut result__).map(|| result__) + } + } + pub unsafe fn UnregisterAdaptersChangedEvent(&self, dwcookie: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).UnregisterAdaptersChangedEvent)(windows_core::Interface::as_raw(self), dwcookie).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIFactory7_Vtbl { @@ -31537,6 +118490,14 @@ impl core::ops::Deref for IDXGIKeyedMutex { } } windows_core::imp::interface_hierarchy!(IDXGIKeyedMutex, windows_core::IUnknown, IDXGIObject, IDXGIDeviceSubObject); +impl IDXGIKeyedMutex { + pub unsafe fn AcquireSync(&self, key: u64, dwmilliseconds: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).AcquireSync)(windows_core::Interface::as_raw(self), key, dwmilliseconds).ok() } + } + pub unsafe fn ReleaseSync(&self, key: u64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).ReleaseSync)(windows_core::Interface::as_raw(self), key).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIKeyedMutex_Vtbl { @@ -31577,6 +118538,27 @@ impl IDXGIKeyedMutex_Vtbl { impl windows_core::RuntimeName for IDXGIKeyedMutex {} windows_core::imp::define_interface!(IDXGIObject, IDXGIObject_Vtbl, 0xaec22fb8_76f3_4639_9be0_28eb43a67a2e); windows_core::imp::interface_hierarchy!(IDXGIObject, windows_core::IUnknown); +impl IDXGIObject { + pub unsafe fn SetPrivateData(&self, name: *const windows_core::GUID, datasize: u32, pdata: *const core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetPrivateData)(windows_core::Interface::as_raw(self), name, datasize, pdata).ok() } + } + pub unsafe fn SetPrivateDataInterface(&self, name: *const windows_core::GUID, punknown: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetPrivateDataInterface)(windows_core::Interface::as_raw(self), name, punknown.param().abi()).ok() } + } + pub unsafe fn GetPrivateData(&self, name: *const windows_core::GUID, pdatasize: *mut u32, pdata: *mut core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetPrivateData)(windows_core::Interface::as_raw(self), name, pdatasize as _, pdata as _).ok() } + } + pub unsafe fn GetParent(&self) -> windows_core::Result + where + T: windows_core::Interface, + { + let mut result__ = core::ptr::null_mut(); + unsafe { (windows_core::Interface::vtable(self).GetParent)(windows_core::Interface::as_raw(self), &T::IID, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIObject_Vtbl { @@ -31590,7 +118572,7 @@ unsafe impl Send for IDXGIObject {} unsafe impl Sync for IDXGIObject {} pub trait IDXGIObject_Impl: windows_core::IUnknownImpl { fn SetPrivateData(&self, name: *const windows_core::GUID, datasize: u32, pdata: *const core::ffi::c_void) -> windows_core::Result<()>; - fn SetPrivateDataInterface(&self, name: *const windows_core::GUID, punknown: windows_core::Ref) -> windows_core::Result<()>; + fn SetPrivateDataInterface(&self, name: *const windows_core::GUID, punknown: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; fn GetPrivateData(&self, name: *const windows_core::GUID, pdatasize: *mut u32, pdata: *mut core::ffi::c_void) -> windows_core::Result<()>; fn GetParent(&self, riid: *const windows_core::GUID, ppparent: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; } @@ -31649,7 +118631,57 @@ impl IDXGIOutput { (windows_core::Interface::vtable(self).GetDesc)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) } } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn GetDisplayModeList(&self, enumformat: Common::DXGI_FORMAT, flags: DXGI_ENUM_MODES, pnummodes: *mut u32, pdesc: Option<*mut Common::DXGI_MODE_DESC>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetDisplayModeList)(windows_core::Interface::as_raw(self), enumformat, flags, pnummodes as _, pdesc.unwrap_or(core::mem::zeroed()) as _).ok() } } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn FindClosestMatchingMode(&self, pmodetomatch: *const Common::DXGI_MODE_DESC, pclosestmatch: *mut Common::DXGI_MODE_DESC, pconcerneddevice: P2) -> windows_core::Result<()> + where + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).FindClosestMatchingMode)(windows_core::Interface::as_raw(self), pmodetomatch, pclosestmatch as _, pconcerneddevice.param().abi()).ok() } + } + pub unsafe fn WaitForVBlank(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).WaitForVBlank)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn TakeOwnership(&self, pdevice: P0, exclusive: bool) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).TakeOwnership)(windows_core::Interface::as_raw(self), pdevice.param().abi(), exclusive.into()).ok() } + } + pub unsafe fn ReleaseOwnership(&self) { + unsafe { (windows_core::Interface::vtable(self).ReleaseOwnership)(windows_core::Interface::as_raw(self)) } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn GetGammaControlCapabilities(&self, pgammacaps: *mut Common::DXGI_GAMMA_CONTROL_CAPABILITIES) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetGammaControlCapabilities)(windows_core::Interface::as_raw(self), pgammacaps as _).ok() } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn SetGammaControl(&self, parray: *const Common::DXGI_GAMMA_CONTROL) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetGammaControl)(windows_core::Interface::as_raw(self), parray).ok() } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn GetGammaControl(&self, parray: *mut Common::DXGI_GAMMA_CONTROL) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetGammaControl)(windows_core::Interface::as_raw(self), parray as _).ok() } + } + pub unsafe fn SetDisplaySurface(&self, pscanoutsurface: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetDisplaySurface)(windows_core::Interface::as_raw(self), pscanoutsurface.param().abi()).ok() } + } + pub unsafe fn GetDisplaySurfaceData(&self, pdestination: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).GetDisplaySurfaceData)(windows_core::Interface::as_raw(self), pdestination.param().abi()).ok() } + } + pub unsafe fn GetFrameStatistics(&self, pstats: *mut DXGI_FRAME_STATISTICS) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetFrameStatistics)(windows_core::Interface::as_raw(self), pstats as _).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIOutput_Vtbl { @@ -31691,15 +118723,15 @@ unsafe impl Sync for IDXGIOutput {} pub trait IDXGIOutput_Impl: IDXGIObject_Impl { fn GetDesc(&self) -> windows_core::Result; fn GetDisplayModeList(&self, enumformat: Common::DXGI_FORMAT, flags: DXGI_ENUM_MODES, pnummodes: *mut u32, pdesc: *mut Common::DXGI_MODE_DESC) -> windows_core::Result<()>; - fn FindClosestMatchingMode(&self, pmodetomatch: *const Common::DXGI_MODE_DESC, pclosestmatch: *mut Common::DXGI_MODE_DESC, pconcerneddevice: windows_core::Ref) -> windows_core::Result<()>; + fn FindClosestMatchingMode(&self, pmodetomatch: *const Common::DXGI_MODE_DESC, pclosestmatch: *mut Common::DXGI_MODE_DESC, pconcerneddevice: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; fn WaitForVBlank(&self) -> windows_core::Result<()>; - fn TakeOwnership(&self, pdevice: windows_core::Ref, exclusive: windows_core::BOOL) -> windows_core::Result<()>; + fn TakeOwnership(&self, pdevice: windows_core::Ref<'_, windows_core::IUnknown>, exclusive: windows_core::BOOL) -> windows_core::Result<()>; fn ReleaseOwnership(&self); fn GetGammaControlCapabilities(&self, pgammacaps: *mut Common::DXGI_GAMMA_CONTROL_CAPABILITIES) -> windows_core::Result<()>; fn SetGammaControl(&self, parray: *const Common::DXGI_GAMMA_CONTROL) -> windows_core::Result<()>; fn GetGammaControl(&self, parray: *mut Common::DXGI_GAMMA_CONTROL) -> windows_core::Result<()>; - fn SetDisplaySurface(&self, pscanoutsurface: windows_core::Ref) -> windows_core::Result<()>; - fn GetDisplaySurfaceData(&self, pdestination: windows_core::Ref) -> windows_core::Result<()>; + fn SetDisplaySurface(&self, pscanoutsurface: windows_core::Ref<'_, IDXGISurface>) -> windows_core::Result<()>; + fn GetDisplaySurfaceData(&self, pdestination: windows_core::Ref<'_, IDXGISurface>) -> windows_core::Result<()>; fn GetFrameStatistics(&self, pstats: *mut DXGI_FRAME_STATISTICS) -> windows_core::Result<()>; } #[cfg(all(feature = "Win32_Graphics_Dxgi_Common", feature = "Win32_Graphics_Gdi"))] @@ -31813,6 +118845,34 @@ impl core::ops::Deref for IDXGIOutput1 { } } windows_core::imp::interface_hierarchy!(IDXGIOutput1, windows_core::IUnknown, IDXGIObject, IDXGIOutput); +impl IDXGIOutput1 { + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn GetDisplayModeList1(&self, enumformat: Common::DXGI_FORMAT, flags: DXGI_ENUM_MODES, pnummodes: *mut u32, pdesc: Option<*mut DXGI_MODE_DESC1>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetDisplayModeList1)(windows_core::Interface::as_raw(self), enumformat, flags, pnummodes as _, pdesc.unwrap_or(core::mem::zeroed()) as _).ok() } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn FindClosestMatchingMode1(&self, pmodetomatch: *const DXGI_MODE_DESC1, pclosestmatch: *mut DXGI_MODE_DESC1, pconcerneddevice: P2) -> windows_core::Result<()> + where + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).FindClosestMatchingMode1)(windows_core::Interface::as_raw(self), pmodetomatch, pclosestmatch as _, pconcerneddevice.param().abi()).ok() } + } + pub unsafe fn GetDisplaySurfaceData1(&self, pdestination: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).GetDisplaySurfaceData1)(windows_core::Interface::as_raw(self), pdestination.param().abi()).ok() } + } + pub unsafe fn DuplicateOutput(&self, pdevice: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).DuplicateOutput)(windows_core::Interface::as_raw(self), pdevice.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIOutput1_Vtbl { @@ -31833,9 +118893,9 @@ unsafe impl Sync for IDXGIOutput1 {} #[cfg(all(feature = "Win32_Graphics_Dxgi_Common", feature = "Win32_Graphics_Gdi"))] pub trait IDXGIOutput1_Impl: IDXGIOutput_Impl { fn GetDisplayModeList1(&self, enumformat: Common::DXGI_FORMAT, flags: DXGI_ENUM_MODES, pnummodes: *mut u32, pdesc: *mut DXGI_MODE_DESC1) -> windows_core::Result<()>; - fn FindClosestMatchingMode1(&self, pmodetomatch: *const DXGI_MODE_DESC1, pclosestmatch: *mut DXGI_MODE_DESC1, pconcerneddevice: windows_core::Ref) -> windows_core::Result<()>; - fn GetDisplaySurfaceData1(&self, pdestination: windows_core::Ref) -> windows_core::Result<()>; - fn DuplicateOutput(&self, pdevice: windows_core::Ref) -> windows_core::Result; + fn FindClosestMatchingMode1(&self, pmodetomatch: *const DXGI_MODE_DESC1, pclosestmatch: *mut DXGI_MODE_DESC1, pconcerneddevice: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; + fn GetDisplaySurfaceData1(&self, pdestination: windows_core::Ref<'_, IDXGIResource>) -> windows_core::Result<()>; + fn DuplicateOutput(&self, pdevice: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result; } #[cfg(all(feature = "Win32_Graphics_Dxgi_Common", feature = "Win32_Graphics_Gdi"))] impl IDXGIOutput1_Vtbl { @@ -31892,6 +118952,11 @@ impl core::ops::Deref for IDXGIOutput2 { } } windows_core::imp::interface_hierarchy!(IDXGIOutput2, windows_core::IUnknown, IDXGIObject, IDXGIOutput, IDXGIOutput1); +impl IDXGIOutput2 { + pub unsafe fn SupportsOverlays(&self) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).SupportsOverlays)(windows_core::Interface::as_raw(self)) } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIOutput2_Vtbl { @@ -31929,6 +118994,18 @@ impl core::ops::Deref for IDXGIOutput3 { } } windows_core::imp::interface_hierarchy!(IDXGIOutput3, windows_core::IUnknown, IDXGIObject, IDXGIOutput, IDXGIOutput1, IDXGIOutput2); +impl IDXGIOutput3 { + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CheckOverlaySupport(&self, enumformat: Common::DXGI_FORMAT, pconcerneddevice: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CheckOverlaySupport)(windows_core::Interface::as_raw(self), enumformat, pconcerneddevice.param().abi(), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIOutput3_Vtbl { @@ -31942,7 +119019,7 @@ unsafe impl Send for IDXGIOutput3 {} unsafe impl Sync for IDXGIOutput3 {} #[cfg(all(feature = "Win32_Graphics_Dxgi_Common", feature = "Win32_Graphics_Gdi"))] pub trait IDXGIOutput3_Impl: IDXGIOutput2_Impl { - fn CheckOverlaySupport(&self, enumformat: Common::DXGI_FORMAT, pconcerneddevice: windows_core::Ref) -> windows_core::Result; + fn CheckOverlaySupport(&self, enumformat: Common::DXGI_FORMAT, pconcerneddevice: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result; } #[cfg(all(feature = "Win32_Graphics_Dxgi_Common", feature = "Win32_Graphics_Gdi"))] impl IDXGIOutput3_Vtbl { @@ -31975,6 +119052,18 @@ impl core::ops::Deref for IDXGIOutput4 { } } windows_core::imp::interface_hierarchy!(IDXGIOutput4, windows_core::IUnknown, IDXGIObject, IDXGIOutput, IDXGIOutput1, IDXGIOutput2, IDXGIOutput3); +impl IDXGIOutput4 { + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CheckOverlayColorSpaceSupport(&self, format: Common::DXGI_FORMAT, colorspace: Common::DXGI_COLOR_SPACE_TYPE, pconcerneddevice: P2) -> windows_core::Result + where + P2: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CheckOverlayColorSpaceSupport)(windows_core::Interface::as_raw(self), format, colorspace, pconcerneddevice.param().abi(), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIOutput4_Vtbl { @@ -31988,7 +119077,7 @@ unsafe impl Send for IDXGIOutput4 {} unsafe impl Sync for IDXGIOutput4 {} #[cfg(all(feature = "Win32_Graphics_Dxgi_Common", feature = "Win32_Graphics_Gdi"))] pub trait IDXGIOutput4_Impl: IDXGIOutput3_Impl { - fn CheckOverlayColorSpaceSupport(&self, format: Common::DXGI_FORMAT, colorspace: Common::DXGI_COLOR_SPACE_TYPE, pconcerneddevice: windows_core::Ref) -> windows_core::Result; + fn CheckOverlayColorSpaceSupport(&self, format: Common::DXGI_FORMAT, colorspace: Common::DXGI_COLOR_SPACE_TYPE, pconcerneddevice: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result; } #[cfg(all(feature = "Win32_Graphics_Dxgi_Common", feature = "Win32_Graphics_Gdi"))] impl IDXGIOutput4_Vtbl { @@ -32021,6 +119110,18 @@ impl core::ops::Deref for IDXGIOutput5 { } } windows_core::imp::interface_hierarchy!(IDXGIOutput5, windows_core::IUnknown, IDXGIObject, IDXGIOutput, IDXGIOutput1, IDXGIOutput2, IDXGIOutput3, IDXGIOutput4); +impl IDXGIOutput5 { + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn DuplicateOutput1(&self, pdevice: P0, flags: u32, psupportedformats: &[Common::DXGI_FORMAT]) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).DuplicateOutput1)(windows_core::Interface::as_raw(self), pdevice.param().abi(), flags, psupportedformats.len().try_into().unwrap(), core::mem::transmute(psupportedformats.as_ptr()), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIOutput5_Vtbl { @@ -32034,7 +119135,7 @@ unsafe impl Send for IDXGIOutput5 {} unsafe impl Sync for IDXGIOutput5 {} #[cfg(all(feature = "Win32_Graphics_Dxgi_Common", feature = "Win32_Graphics_Gdi"))] pub trait IDXGIOutput5_Impl: IDXGIOutput4_Impl { - fn DuplicateOutput1(&self, pdevice: windows_core::Ref, flags: u32, supportedformatscount: u32, psupportedformats: *const Common::DXGI_FORMAT) -> windows_core::Result; + fn DuplicateOutput1(&self, pdevice: windows_core::Ref<'_, windows_core::IUnknown>, flags: u32, supportedformatscount: u32, psupportedformats: *const Common::DXGI_FORMAT) -> windows_core::Result; } #[cfg(all(feature = "Win32_Graphics_Dxgi_Common", feature = "Win32_Graphics_Gdi"))] impl IDXGIOutput5_Vtbl { @@ -32067,6 +119168,21 @@ impl core::ops::Deref for IDXGIOutput6 { } } windows_core::imp::interface_hierarchy!(IDXGIOutput6, windows_core::IUnknown, IDXGIObject, IDXGIOutput, IDXGIOutput1, IDXGIOutput2, IDXGIOutput3, IDXGIOutput4, IDXGIOutput5); +impl IDXGIOutput6 { + #[cfg(all(feature = "Win32_Graphics_Dxgi_Common", feature = "Win32_Graphics_Gdi"))] + pub unsafe fn GetDesc1(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDesc1)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn CheckHardwareCompositionSupport(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CheckHardwareCompositionSupport)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIOutput6_Vtbl { @@ -32140,7 +119256,31 @@ impl IDXGIOutputDuplication { result__ } } + pub unsafe fn AcquireNextFrame(&self, timeoutinmilliseconds: u32, pframeinfo: *mut DXGI_OUTDUPL_FRAME_INFO, ppdesktopresource: *mut Option) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).AcquireNextFrame)(windows_core::Interface::as_raw(self), timeoutinmilliseconds, pframeinfo as _, core::mem::transmute(ppdesktopresource)).ok() } } + pub unsafe fn GetFrameDirtyRects(&self, dirtyrectsbuffersize: u32, pdirtyrectsbuffer: *mut super::super::Foundation::RECT, pdirtyrectsbuffersizerequired: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetFrameDirtyRects)(windows_core::Interface::as_raw(self), dirtyrectsbuffersize, pdirtyrectsbuffer as _, pdirtyrectsbuffersizerequired as _).ok() } + } + pub unsafe fn GetFrameMoveRects(&self, moverectsbuffersize: u32, pmoverectbuffer: *mut DXGI_OUTDUPL_MOVE_RECT, pmoverectsbuffersizerequired: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetFrameMoveRects)(windows_core::Interface::as_raw(self), moverectsbuffersize, pmoverectbuffer as _, pmoverectsbuffersizerequired as _).ok() } + } + pub unsafe fn GetFramePointerShape(&self, pointershapebuffersize: u32, ppointershapebuffer: *mut core::ffi::c_void, ppointershapebuffersizerequired: *mut u32, ppointershapeinfo: *mut DXGI_OUTDUPL_POINTER_SHAPE_INFO) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetFramePointerShape)(windows_core::Interface::as_raw(self), pointershapebuffersize, ppointershapebuffer as _, ppointershapebuffersizerequired as _, ppointershapeinfo as _).ok() } + } + pub unsafe fn MapDesktopSurface(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).MapDesktopSurface)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn UnMapDesktopSurface(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).UnMapDesktopSurface)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn ReleaseFrame(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).ReleaseFrame)(windows_core::Interface::as_raw(self)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIOutputDuplication_Vtbl { @@ -32162,7 +119302,7 @@ unsafe impl Sync for IDXGIOutputDuplication {} #[cfg(feature = "Win32_Graphics_Dxgi_Common")] pub trait IDXGIOutputDuplication_Impl: IDXGIObject_Impl { fn GetDesc(&self, pdesc: *mut DXGI_OUTDUPL_DESC); - fn AcquireNextFrame(&self, timeoutinmilliseconds: u32, pframeinfo: *mut DXGI_OUTDUPL_FRAME_INFO, ppdesktopresource: windows_core::OutRef) -> windows_core::Result<()>; + fn AcquireNextFrame(&self, timeoutinmilliseconds: u32, pframeinfo: *mut DXGI_OUTDUPL_FRAME_INFO, ppdesktopresource: windows_core::OutRef<'_, IDXGIResource>) -> windows_core::Result<()>; fn GetFrameDirtyRects(&self, dirtyrectsbuffersize: u32, pdirtyrectsbuffer: *mut super::super::Foundation::RECT, pdirtyrectsbuffersizerequired: *mut u32) -> windows_core::Result<()>; fn GetFrameMoveRects(&self, moverectsbuffersize: u32, pmoverectbuffer: *mut DXGI_OUTDUPL_MOVE_RECT, pmoverectsbuffersizerequired: *mut u32) -> windows_core::Result<()>; fn GetFramePointerShape(&self, pointershapebuffersize: u32, ppointershapebuffer: *mut core::ffi::c_void, ppointershapebuffersizerequired: *mut u32, ppointershapeinfo: *mut DXGI_OUTDUPL_POINTER_SHAPE_INFO) -> windows_core::Result<()>; @@ -32260,7 +119400,22 @@ impl IDXGIResource { (windows_core::Interface::vtable(self).GetSharedHandle)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) } } + pub unsafe fn GetUsage(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetUsage)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } } + pub unsafe fn SetEvictionPriority(&self, evictionpriority: DXGI_RESOURCE_PRIORITY) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetEvictionPriority)(windows_core::Interface::as_raw(self), evictionpriority).ok() } + } + pub unsafe fn GetEvictionPriority(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetEvictionPriority)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIResource_Vtbl { @@ -32343,6 +119498,24 @@ impl core::ops::Deref for IDXGIResource1 { } } windows_core::imp::interface_hierarchy!(IDXGIResource1, windows_core::IUnknown, IDXGIObject, IDXGIDeviceSubObject, IDXGIResource); +impl IDXGIResource1 { + pub unsafe fn CreateSubresourceSurface(&self, index: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateSubresourceSurface)(windows_core::Interface::as_raw(self), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(feature = "Win32_Security")] + pub unsafe fn CreateSharedHandle(&self, pattributes: Option<*const super::super::Security::SECURITY_ATTRIBUTES>, dwaccess: u32, lpname: P2) -> windows_core::Result + where + P2: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateSharedHandle)(windows_core::Interface::as_raw(self), pattributes.unwrap_or(core::mem::zeroed()) as _, dwaccess, lpname.param().abi(), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGIResource1_Vtbl { @@ -32489,6 +119662,18 @@ impl core::ops::Deref for IDXGISurface1 { } } windows_core::imp::interface_hierarchy!(IDXGISurface1, windows_core::IUnknown, IDXGIObject, IDXGIDeviceSubObject, IDXGISurface); +impl IDXGISurface1 { + #[cfg(feature = "Win32_Graphics_Gdi")] + pub unsafe fn GetDC(&self, discard: bool) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDC)(windows_core::Interface::as_raw(self), discard.into(), &mut result__).map(|| result__) + } + } + pub unsafe fn ReleaseDC(&self, pdirtyrect: Option<*const super::super::Foundation::RECT>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).ReleaseDC)(windows_core::Interface::as_raw(self), pdirtyrect.unwrap_or(core::mem::zeroed()) as _).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGISurface1_Vtbl { @@ -32600,6 +119785,15 @@ impl IDXGISwapChain { let mut result__ = core::ptr::null_mut(); unsafe { (windows_core::Interface::vtable(self).GetBuffer)(windows_core::Interface::as_raw(self), buffer, &T::IID, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub unsafe fn SetFullscreenState(&self, fullscreen: bool, ptarget: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetFullscreenState)(windows_core::Interface::as_raw(self), fullscreen.into(), ptarget.param().abi()).ok() } + } + pub unsafe fn GetFullscreenState(&self, pfullscreen: Option<*mut windows_core::BOOL>, pptarget: Option<*mut Option>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetFullscreenState)(windows_core::Interface::as_raw(self), pfullscreen.unwrap_or(core::mem::zeroed()) as _, pptarget.unwrap_or(core::mem::zeroed()) as _).ok() } + } #[cfg(feature = "Win32_Graphics_Dxgi_Common")] pub unsafe fn GetDesc(&self) -> windows_core::Result { unsafe { @@ -32611,7 +119805,26 @@ impl IDXGISwapChain { pub unsafe fn ResizeBuffers(&self, buffercount: u32, width: u32, height: u32, newformat: Common::DXGI_FORMAT, swapchainflags: DXGI_SWAP_CHAIN_FLAG) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).ResizeBuffers)(windows_core::Interface::as_raw(self), buffercount, width, height, newformat, swapchainflags.0 as _).ok() } } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn ResizeTarget(&self, pnewtargetparameters: *const Common::DXGI_MODE_DESC) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).ResizeTarget)(windows_core::Interface::as_raw(self), pnewtargetparameters).ok() } } + pub unsafe fn GetContainingOutput(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetContainingOutput)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetFrameStatistics(&self, pstats: *mut DXGI_FRAME_STATISTICS) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetFrameStatistics)(windows_core::Interface::as_raw(self), pstats as _).ok() } + } + pub unsafe fn GetLastPresentCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetLastPresentCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGISwapChain_Vtbl { @@ -32642,8 +119855,8 @@ unsafe impl Sync for IDXGISwapChain {} pub trait IDXGISwapChain_Impl: IDXGIDeviceSubObject_Impl { fn Present(&self, syncinterval: u32, flags: DXGI_PRESENT) -> windows_core::HRESULT; fn GetBuffer(&self, buffer: u32, riid: *const windows_core::GUID, ppsurface: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; - fn SetFullscreenState(&self, fullscreen: windows_core::BOOL, ptarget: windows_core::Ref) -> windows_core::Result<()>; - fn GetFullscreenState(&self, pfullscreen: *mut windows_core::BOOL, pptarget: windows_core::OutRef) -> windows_core::Result<()>; + fn SetFullscreenState(&self, fullscreen: windows_core::BOOL, ptarget: windows_core::Ref<'_, IDXGIOutput>) -> windows_core::Result<()>; + fn GetFullscreenState(&self, pfullscreen: *mut windows_core::BOOL, pptarget: windows_core::OutRef<'_, IDXGIOutput>) -> windows_core::Result<()>; fn GetDesc(&self) -> windows_core::Result; fn ResizeBuffers(&self, buffercount: u32, width: u32, height: u32, newformat: Common::DXGI_FORMAT, swapchainflags: &DXGI_SWAP_CHAIN_FLAG) -> windows_core::Result<()>; fn ResizeTarget(&self, pnewtargetparameters: *const Common::DXGI_MODE_DESC) -> windows_core::Result<()>; @@ -32761,10 +119974,66 @@ impl core::ops::Deref for IDXGISwapChain1 { } windows_core::imp::interface_hierarchy!(IDXGISwapChain1, windows_core::IUnknown, IDXGIObject, IDXGIDeviceSubObject, IDXGISwapChain); impl IDXGISwapChain1 { + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn GetDesc1(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDesc1)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn GetFullscreenDesc(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetFullscreenDesc)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetHwnd(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetHwnd)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetCoreWindow(&self) -> windows_core::Result + where + T: windows_core::Interface, + { + let mut result__ = core::ptr::null_mut(); + unsafe { (windows_core::Interface::vtable(self).GetCoreWindow)(windows_core::Interface::as_raw(self), &T::IID, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } + } + pub unsafe fn Present1(&self, syncinterval: u32, presentflags: DXGI_PRESENT, ppresentparameters: *const DXGI_PRESENT_PARAMETERS) -> windows_core::HRESULT { + unsafe { (windows_core::Interface::vtable(self).Present1)(windows_core::Interface::as_raw(self), syncinterval, presentflags, ppresentparameters) } + } + pub unsafe fn IsTemporaryMonoSupported(&self) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).IsTemporaryMonoSupported)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetRestrictToOutput(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetRestrictToOutput)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub unsafe fn SetBackgroundColor(&self, pcolor: *const DXGI_RGBA) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetBackgroundColor)(windows_core::Interface::as_raw(self), pcolor).ok() } } + pub unsafe fn GetBackgroundColor(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetBackgroundColor)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn SetRotation(&self, rotation: Common::DXGI_MODE_ROTATION) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetRotation)(windows_core::Interface::as_raw(self), rotation).ok() } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn GetRotation(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetRotation)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGISwapChain1_Vtbl { @@ -32944,13 +120213,31 @@ impl core::ops::Deref for IDXGISwapChain2 { } windows_core::imp::interface_hierarchy!(IDXGISwapChain2, windows_core::IUnknown, IDXGIObject, IDXGIDeviceSubObject, IDXGISwapChain, IDXGISwapChain1); impl IDXGISwapChain2 { + pub unsafe fn SetSourceSize(&self, width: u32, height: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetSourceSize)(windows_core::Interface::as_raw(self), width, height).ok() } + } + pub unsafe fn GetSourceSize(&self, pwidth: *mut u32, pheight: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetSourceSize)(windows_core::Interface::as_raw(self), pwidth as _, pheight as _).ok() } + } pub unsafe fn SetMaximumFrameLatency(&self, maxlatency: u32) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetMaximumFrameLatency)(windows_core::Interface::as_raw(self), maxlatency).ok() } } + pub unsafe fn GetMaximumFrameLatency(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMaximumFrameLatency)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } pub unsafe fn GetFrameLatencyWaitableObject(&self) -> super::super::Foundation::HANDLE { unsafe { (windows_core::Interface::vtable(self).GetFrameLatencyWaitableObject)(windows_core::Interface::as_raw(self)) } } + pub unsafe fn SetMatrixTransform(&self, pmatrix: *const DXGI_MATRIX_3X2_F) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetMatrixTransform)(windows_core::Interface::as_raw(self), pmatrix).ok() } } + pub unsafe fn GetMatrixTransform(&self, pmatrix: *mut DXGI_MATRIX_3X2_F) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetMatrixTransform)(windows_core::Interface::as_raw(self), pmatrix as _).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGISwapChain2_Vtbl { @@ -33051,6 +120338,26 @@ impl core::ops::Deref for IDXGISwapChain3 { } } windows_core::imp::interface_hierarchy!(IDXGISwapChain3, windows_core::IUnknown, IDXGIObject, IDXGIDeviceSubObject, IDXGISwapChain, IDXGISwapChain1, IDXGISwapChain2); +impl IDXGISwapChain3 { + pub unsafe fn GetCurrentBackBufferIndex(&self) -> u32 { + unsafe { (windows_core::Interface::vtable(self).GetCurrentBackBufferIndex)(windows_core::Interface::as_raw(self)) } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn CheckColorSpaceSupport(&self, colorspace: Common::DXGI_COLOR_SPACE_TYPE) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CheckColorSpaceSupport)(windows_core::Interface::as_raw(self), colorspace, &mut result__).map(|| result__) + } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn SetColorSpace1(&self, colorspace: Common::DXGI_COLOR_SPACE_TYPE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetColorSpace1)(windows_core::Interface::as_raw(self), colorspace).ok() } + } + #[cfg(feature = "Win32_Graphics_Dxgi_Common")] + pub unsafe fn ResizeBuffers1(&self, buffercount: u32, width: u32, height: u32, format: Common::DXGI_FORMAT, swapchainflags: DXGI_SWAP_CHAIN_FLAG, pcreationnodemask: *const u32, pppresentqueue: *const Option) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).ResizeBuffers1)(windows_core::Interface::as_raw(self), buffercount, width, height, format, swapchainflags.0 as _, pcreationnodemask, core::mem::transmute(pppresentqueue)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGISwapChain3_Vtbl { @@ -33133,6 +120440,11 @@ impl core::ops::Deref for IDXGISwapChain4 { } } windows_core::imp::interface_hierarchy!(IDXGISwapChain4, windows_core::IUnknown, IDXGIObject, IDXGIDeviceSubObject, IDXGISwapChain, IDXGISwapChain1, IDXGISwapChain2, IDXGISwapChain3); +impl IDXGISwapChain4 { + pub unsafe fn SetHDRMetaData(&self, r#type: DXGI_HDR_METADATA_TYPE, pmetadata: Option<&[u8]>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetHDRMetaData)(windows_core::Interface::as_raw(self), r#type, pmetadata.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(pmetadata.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr()))).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IDXGISwapChain4_Vtbl { @@ -33162,6 +120474,7 @@ impl IDXGISwapChain4_Vtbl { } #[cfg(feature = "Win32_Graphics_Dxgi_Common")] impl windows_core::RuntimeName for IDXGISwapChain4 {} +#[cfg(feature = "Win32_Graphics_Dxgi_Common")] pub mod Common{ #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -33258,6 +120571,7 @@ pub struct DXGI_SAMPLE_DESC { } } } +#[cfg(feature = "Win32_Graphics_Gdi")] pub mod Gdi{ #[inline] pub unsafe fn CreateSolidBrush(color: super::super::Foundation::COLORREF) -> HBRUSH { @@ -33558,7 +120872,9 @@ pub const MONITOR_DEFAULTTONEAREST: MONITOR_FROM_FLAGS = MONITOR_FROM_FLAGS(2u32 pub struct MONITOR_FROM_FLAGS(pub u32); } } +#[cfg(feature = "Win32_Media")] pub mod Media{ +#[cfg(feature = "Win32_Media_Audio")] pub mod Audio{ #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -33670,7 +120986,13 @@ impl IAudioCaptureClient { pub unsafe fn ReleaseBuffer(&self, numframesread: u32) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).ReleaseBuffer)(windows_core::Interface::as_raw(self), numframesread).ok() } } + pub unsafe fn GetNextPacketSize(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetNextPacketSize)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } } +} #[repr(C)] #[doc(hidden)] pub struct IAudioCaptureClient_Vtbl { @@ -33734,12 +121056,21 @@ impl IAudioClient { (windows_core::Interface::vtable(self).GetBufferSize)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) } } + pub unsafe fn GetStreamLatency(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamLatency)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } pub unsafe fn GetCurrentPadding(&self) -> windows_core::Result { unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(self).GetCurrentPadding)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) } } + pub unsafe fn IsFormatSupported(&self, sharemode: AUDCLNT_SHAREMODE, pformat: *const WAVEFORMATEX, ppclosestmatch: Option<*mut *mut WAVEFORMATEX>) -> windows_core::HRESULT { + unsafe { (windows_core::Interface::vtable(self).IsFormatSupported)(windows_core::Interface::as_raw(self), sharemode, pformat, ppclosestmatch.unwrap_or(core::mem::zeroed()) as _) } + } pub unsafe fn GetMixFormat(&self) -> windows_core::Result<*mut WAVEFORMATEX> { unsafe { let mut result__ = core::mem::zeroed(); @@ -33755,6 +121086,9 @@ impl IAudioClient { pub unsafe fn Stop(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Stop)(windows_core::Interface::as_raw(self)).ok() } } + pub unsafe fn Reset(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Reset)(windows_core::Interface::as_raw(self)).ok() } + } pub unsafe fn SetEventHandle(&self, eventhandle: super::super::Foundation::HANDLE) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetEventHandle)(windows_core::Interface::as_raw(self), eventhandle).ok() } } @@ -33924,6 +121258,20 @@ impl core::ops::Deref for IAudioClient2 { } } windows_core::imp::interface_hierarchy!(IAudioClient2, windows_core::IUnknown, IAudioClient); +impl IAudioClient2 { + pub unsafe fn IsOffloadCapable(&self, category: AUDIO_STREAM_CATEGORY) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).IsOffloadCapable)(windows_core::Interface::as_raw(self), category, &mut result__).map(|| result__) + } + } + pub unsafe fn SetClientProperties(&self, pproperties: *const AudioClientProperties) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetClientProperties)(windows_core::Interface::as_raw(self), pproperties).ok() } + } + pub unsafe fn GetBufferSizeLimits(&self, pformat: *const WAVEFORMATEX, beventdriven: bool, phnsminbufferduration: *mut i64, phnsmaxbufferduration: *mut i64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetBufferSizeLimits)(windows_core::Interface::as_raw(self), pformat, beventdriven.into(), phnsminbufferduration as _, phnsmaxbufferduration as _).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IAudioClient2_Vtbl { @@ -33987,6 +121335,9 @@ impl IAudioClient3 { pub unsafe fn GetSharedModeEnginePeriod(&self, pformat: *const WAVEFORMATEX, pdefaultperiodinframes: *mut u32, pfundamentalperiodinframes: *mut u32, pminperiodinframes: *mut u32, pmaxperiodinframes: *mut u32) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).GetSharedModeEnginePeriod)(windows_core::Interface::as_raw(self), pformat, pdefaultperiodinframes as _, pfundamentalperiodinframes as _, pminperiodinframes as _, pmaxperiodinframes as _).ok() } } + pub unsafe fn GetCurrentSharedModeEnginePeriod(&self, ppformat: *mut *mut WAVEFORMATEX, pcurrentperiodinframes: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetCurrentSharedModeEnginePeriod)(windows_core::Interface::as_raw(self), ppformat as _, pcurrentperiodinframes as _).ok() } + } pub unsafe fn InitializeSharedAudioStream(&self, streamflags: u32, periodinframes: u32, pformat: *const WAVEFORMATEX, audiosessionguid: Option<*const windows_core::GUID>) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).InitializeSharedAudioStream)(windows_core::Interface::as_raw(self), streamflags, periodinframes, pformat, audiosessionguid.unwrap_or(core::mem::zeroed()) as _).ok() } } @@ -34115,7 +121466,13 @@ impl IMMDevice { (windows_core::Interface::vtable(self).GetId)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) } } + pub unsafe fn GetState(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetState)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } } +} #[repr(C)] #[doc(hidden)] pub struct IMMDevice_Vtbl { @@ -34272,13 +121629,28 @@ impl IMMDeviceEnumerator { (windows_core::Interface::vtable(self).GetDefaultAudioEndpoint)(windows_core::Interface::as_raw(self), dataflow, role, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub unsafe fn GetDevice(&self, pwstrid: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDevice)(windows_core::Interface::as_raw(self), pwstrid.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub unsafe fn RegisterEndpointNotificationCallback(&self, pclient: P0) -> windows_core::Result<()> where P0: windows_core::Param, { unsafe { (windows_core::Interface::vtable(self).RegisterEndpointNotificationCallback)(windows_core::Interface::as_raw(self), pclient.param().abi()).ok() } } + pub unsafe fn UnregisterEndpointNotificationCallback(&self, pclient: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).UnregisterEndpointNotificationCallback)(windows_core::Interface::as_raw(self), pclient.param().abi()).ok() } } +} #[repr(C)] #[doc(hidden)] pub struct IMMDeviceEnumerator_Vtbl { @@ -34293,8 +121665,8 @@ pub trait IMMDeviceEnumerator_Impl: windows_core::IUnknownImpl { fn EnumAudioEndpoints(&self, dataflow: EDataFlow, dwstatemask: DEVICE_STATE) -> windows_core::Result; fn GetDefaultAudioEndpoint(&self, dataflow: EDataFlow, role: ERole) -> windows_core::Result; fn GetDevice(&self, pwstrid: &windows_core::PCWSTR) -> windows_core::Result; - fn RegisterEndpointNotificationCallback(&self, pclient: windows_core::Ref) -> windows_core::Result<()>; - fn UnregisterEndpointNotificationCallback(&self, pclient: windows_core::Ref) -> windows_core::Result<()>; + fn RegisterEndpointNotificationCallback(&self, pclient: windows_core::Ref<'_, IMMNotificationClient>) -> windows_core::Result<()>; + fn UnregisterEndpointNotificationCallback(&self, pclient: windows_core::Ref<'_, IMMNotificationClient>) -> windows_core::Result<()>; } impl IMMDeviceEnumerator_Vtbl { pub const fn new() -> Self { @@ -34362,6 +121734,38 @@ impl IMMDeviceEnumerator_Vtbl { impl windows_core::RuntimeName for IMMDeviceEnumerator {} windows_core::imp::define_interface!(IMMNotificationClient, IMMNotificationClient_Vtbl, 0x7991eec9_7e89_4d85_8390_6c703cec60c0); windows_core::imp::interface_hierarchy!(IMMNotificationClient, windows_core::IUnknown); +impl IMMNotificationClient { + pub unsafe fn OnDeviceStateChanged(&self, pwstrdeviceid: P0, dwnewstate: DEVICE_STATE) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).OnDeviceStateChanged)(windows_core::Interface::as_raw(self), pwstrdeviceid.param().abi(), dwnewstate).ok() } + } + pub unsafe fn OnDeviceAdded(&self, pwstrdeviceid: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).OnDeviceAdded)(windows_core::Interface::as_raw(self), pwstrdeviceid.param().abi()).ok() } + } + pub unsafe fn OnDeviceRemoved(&self, pwstrdeviceid: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).OnDeviceRemoved)(windows_core::Interface::as_raw(self), pwstrdeviceid.param().abi()).ok() } + } + pub unsafe fn OnDefaultDeviceChanged(&self, flow: EDataFlow, role: ERole, pwstrdefaultdeviceid: P2) -> windows_core::Result<()> + where + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).OnDefaultDeviceChanged)(windows_core::Interface::as_raw(self), flow, role, pwstrdefaultdeviceid.param().abi()).ok() } + } + pub unsafe fn OnPropertyValueChanged(&self, pwstrdeviceid: P0, key: super::super::Foundation::PROPERTYKEY) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).OnPropertyValueChanged)(windows_core::Interface::as_raw(self), pwstrdeviceid.param().abi(), core::mem::transmute(key)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMMNotificationClient_Vtbl { @@ -34427,6 +121831,38 @@ impl IMMNotificationClient_Vtbl { impl windows_core::RuntimeName for IMMNotificationClient {} windows_core::imp::define_interface!(ISpatialAudioMetadataItems, ISpatialAudioMetadataItems_Vtbl, 0xbcd7c78f_3098_4f22_b547_a2f25a381269); windows_core::imp::interface_hierarchy!(ISpatialAudioMetadataItems, windows_core::IUnknown); +impl ISpatialAudioMetadataItems { + pub unsafe fn GetFrameCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetFrameCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetItemCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetItemCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetMaxItemCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMaxItemCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetMaxValueBufferLength(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMaxValueBufferLength)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetInfo(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetInfo)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct ISpatialAudioMetadataItems_Vtbl { @@ -34570,15 +122006,24 @@ pub const eCapture: EDataFlow = EDataFlow(1i32); pub const eConsole: ERole = ERole(0i32); pub const eRender: EDataFlow = EDataFlow(0i32); } +#[cfg(feature = "Win32_Media_KernelStreaming")] pub mod KernelStreaming{ pub const WAVE_FORMAT_EXTENSIBLE: u32 = 65534u32; } +#[cfg(feature = "Win32_Media_MediaFoundation")] pub mod MediaFoundation{ #[inline] pub unsafe fn MFCreateAttributes(ppmfattributes: *mut Option, cinitialsize: u32) -> windows_core::Result<()> { windows_core::link!("mfplat.dll" "system" fn MFCreateAttributes(ppmfattributes : *mut * mut core::ffi::c_void, cinitialsize : u32) -> windows_core::HRESULT); unsafe { MFCreateAttributes(core::mem::transmute(ppmfattributes), cinitialsize).ok() } } +#[inline] +pub unsafe fn MFCreateDXGIDeviceManager(resettoken: *mut u32, ppdevicemanager: *mut Option) -> windows_core::Result<()> { + windows_core::link!("mfplat.dll" "system" fn MFCreateDXGIDeviceManager(resettoken : *mut u32, ppdevicemanager : *mut * mut core::ffi::c_void) -> windows_core::HRESULT); + unsafe { MFCreateDXGIDeviceManager(resettoken as _, core::mem::transmute(ppdevicemanager)).ok() } +} +#[cfg(feature = "Win32_System_Com")] +#[inline] pub unsafe fn MFCreateMFByteStreamOnStream(pstream: P0) -> windows_core::Result where P0: windows_core::Param, @@ -34589,6 +122034,44 @@ where MFCreateMFByteStreamOnStream(pstream.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } +#[inline] +pub unsafe fn MFCreateMediaType() -> windows_core::Result { + windows_core::link!("mfplat.dll" "system" fn MFCreateMediaType(ppmftype : *mut * mut core::ffi::c_void) -> windows_core::HRESULT); + unsafe { + let mut result__ = core::mem::zeroed(); + MFCreateMediaType(&mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } +} +#[inline] +pub unsafe fn MFCreateMemoryBuffer(cbmaxlength: u32) -> windows_core::Result { + windows_core::link!("mfplat.dll" "system" fn MFCreateMemoryBuffer(cbmaxlength : u32, ppbuffer : *mut * mut core::ffi::c_void) -> windows_core::HRESULT); + unsafe { + let mut result__ = core::mem::zeroed(); + MFCreateMemoryBuffer(cbmaxlength, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } +} +#[inline] +pub unsafe fn MFCreateSample() -> windows_core::Result { + windows_core::link!("mfplat.dll" "system" fn MFCreateSample(ppimfsample : *mut * mut core::ffi::c_void) -> windows_core::HRESULT); + unsafe { + let mut result__ = core::mem::zeroed(); + MFCreateSample(&mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } +} +#[inline] +pub unsafe fn MFCreateSinkWriterFromURL(pwszoutputurl: P0, pbytestream: P1, pattributes: P2) -> windows_core::Result +where + P0: windows_core::Param, + P1: windows_core::Param, + P2: windows_core::Param, +{ + windows_core::link!("mfreadwrite.dll" "system" fn MFCreateSinkWriterFromURL(pwszoutputurl : windows_core::PCWSTR, pbytestream : * mut core::ffi::c_void, pattributes : * mut core::ffi::c_void, ppsinkwriter : *mut * mut core::ffi::c_void) -> windows_core::HRESULT); + unsafe { + let mut result__ = core::mem::zeroed(); + MFCreateSinkWriterFromURL(pwszoutputurl.param().abi(), pbytestream.param().abi(), pattributes.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } +} +#[inline] pub unsafe fn MFCreateSourceReaderFromByteStream(pbytestream: P0, pattributes: P1) -> windows_core::Result where P0: windows_core::Param, @@ -34600,20 +122083,6 @@ where MFCreateSourceReaderFromByteStream(pbytestream.param().abi(), pattributes.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } -pub const MF_BYTESTREAM_CONTENT_TYPE: windows_core::GUID = windows_core::GUID::from_u128(0xfc358288_3cb6_460c_a424_b6681260375a); -#[inline] -pub unsafe fn MFCreateDXGIDeviceManager(resettoken: *mut u32, ppdevicemanager: *mut Option) -> windows_core::Result<()> { - windows_core::link!("mfplat.dll" "system" fn MFCreateDXGIDeviceManager(resettoken : *mut u32, ppdevicemanager : *mut * mut core::ffi::c_void) -> windows_core::HRESULT); - unsafe { MFCreateDXGIDeviceManager(resettoken as _, core::mem::transmute(ppdevicemanager)).ok() } -} -#[inline] -pub unsafe fn MFCreateMediaType() -> windows_core::Result { - windows_core::link!("mfplat.dll" "system" fn MFCreateMediaType(ppmftype : *mut * mut core::ffi::c_void) -> windows_core::HRESULT); - unsafe { - let mut result__ = core::mem::zeroed(); - MFCreateMediaType(&mut result__).and_then(|| windows_core::Type::from_abi(result__)) - } -} #[inline] pub unsafe fn MFCreateSourceReaderFromMediaSource(pmediasource: P0, pattributes: P1) -> windows_core::Result where @@ -34657,6 +122126,7 @@ pub unsafe fn MFStartup(version: u32, dwflags: u32) -> windows_core::Result<()> unsafe { MFStartup(version, dwflags).ok() } } pub const CLSID_MFMediaEngineClassFactory: windows_core::GUID = windows_core::GUID::from_u128(0xb44392da_499b_446b_a4cb_005fead0e6d5); +pub const CODECAPI_AVEncMPVGOPSize: windows_core::GUID = windows_core::GUID::from_u128(0x95f31b26_95a4_41aa_9303_246a7fc6eef1); #[repr(C)] #[derive(Clone, Debug, Default, PartialEq)] pub struct DEVICE_INFO { @@ -34666,8 +122136,317 @@ pub struct DEVICE_INFO { pub pModelName: core::mem::ManuallyDrop, pub pIconURL: core::mem::ManuallyDrop, } +windows_core::imp::define_interface!(ICodecAPI, ICodecAPI_Vtbl, 0x901db4c7_31ce_41a2_85dc_8fa0bf41b8da); +windows_core::imp::interface_hierarchy!(ICodecAPI, windows_core::IUnknown); +impl ICodecAPI { + pub unsafe fn IsSupported(&self, api: *const windows_core::GUID) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).IsSupported)(windows_core::Interface::as_raw(self), api).ok() } + } + pub unsafe fn IsModifiable(&self, api: *const windows_core::GUID) -> windows_core::HRESULT { + unsafe { (windows_core::Interface::vtable(self).IsModifiable)(windows_core::Interface::as_raw(self), api) } + } + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetParameterRange(&self, api: *const windows_core::GUID, valuemin: *mut super::super::System::Variant::VARIANT, valuemax: *mut super::super::System::Variant::VARIANT, steppingdelta: *mut super::super::System::Variant::VARIANT) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetParameterRange)(windows_core::Interface::as_raw(self), api, core::mem::transmute(valuemin), core::mem::transmute(valuemax), core::mem::transmute(steppingdelta)).ok() } + } + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetParameterValues(&self, api: *const windows_core::GUID, values: *mut *mut super::super::System::Variant::VARIANT, valuescount: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetParameterValues)(windows_core::Interface::as_raw(self), api, values as _, valuescount as _).ok() } + } + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetDefaultValue(&self, api: *const windows_core::GUID) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDefaultValue)(windows_core::Interface::as_raw(self), api, &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetValue(&self, api: *const windows_core::GUID) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetValue)(windows_core::Interface::as_raw(self), api, &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn SetValue(&self, api: *const windows_core::GUID, value: *const super::super::System::Variant::VARIANT) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetValue)(windows_core::Interface::as_raw(self), api, core::mem::transmute(value)).ok() } + } + pub unsafe fn RegisterForEvent(&self, api: *const windows_core::GUID, userdata: isize) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RegisterForEvent)(windows_core::Interface::as_raw(self), api, userdata).ok() } + } + pub unsafe fn UnregisterForEvent(&self, api: *const windows_core::GUID) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).UnregisterForEvent)(windows_core::Interface::as_raw(self), api).ok() } + } + pub unsafe fn SetAllDefaults(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetAllDefaults)(windows_core::Interface::as_raw(self)).ok() } + } + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn SetValueWithNotify(&self, api: *const windows_core::GUID, value: *const super::super::System::Variant::VARIANT, changedparam: *mut *mut windows_core::GUID, changedparamcount: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetValueWithNotify)(windows_core::Interface::as_raw(self), api, core::mem::transmute(value), changedparam as _, changedparamcount as _).ok() } + } + pub unsafe fn SetAllDefaultsWithNotify(&self, changedparam: *mut *mut windows_core::GUID, changedparamcount: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetAllDefaultsWithNotify)(windows_core::Interface::as_raw(self), changedparam as _, changedparamcount as _).ok() } + } + #[cfg(feature = "Win32_System_Com")] + pub unsafe fn GetAllSettings(&self, __midl__icodecapi0000: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).GetAllSettings)(windows_core::Interface::as_raw(self), __midl__icodecapi0000.param().abi()).ok() } + } + #[cfg(feature = "Win32_System_Com")] + pub unsafe fn SetAllSettings(&self, __midl__icodecapi0001: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetAllSettings)(windows_core::Interface::as_raw(self), __midl__icodecapi0001.param().abi()).ok() } + } + #[cfg(feature = "Win32_System_Com")] + pub unsafe fn SetAllSettingsWithNotify(&self, __midl__icodecapi0002: P0, changedparam: *mut *mut windows_core::GUID, changedparamcount: *mut u32) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetAllSettingsWithNotify)(windows_core::Interface::as_raw(self), __midl__icodecapi0002.param().abi(), changedparam as _, changedparamcount as _).ok() } + } +} +#[repr(C)] +#[doc(hidden)] +pub struct ICodecAPI_Vtbl { + pub base__: windows_core::IUnknown_Vtbl, + pub IsSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID) -> windows_core::HRESULT, + pub IsModifiable: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID) -> windows_core::HRESULT, + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub GetParameterRange: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, *mut super::super::System::Variant::VARIANT, *mut super::super::System::Variant::VARIANT, *mut super::super::System::Variant::VARIANT) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant")))] + GetParameterRange: usize, + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub GetParameterValues: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, *mut *mut super::super::System::Variant::VARIANT, *mut u32) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant")))] + GetParameterValues: usize, + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub GetDefaultValue: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, *mut super::super::System::Variant::VARIANT) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant")))] + GetDefaultValue: usize, + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub GetValue: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, *mut super::super::System::Variant::VARIANT) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant")))] + GetValue: usize, + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub SetValue: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, *const super::super::System::Variant::VARIANT) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant")))] + SetValue: usize, + pub RegisterForEvent: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, isize) -> windows_core::HRESULT, + pub UnregisterForEvent: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID) -> windows_core::HRESULT, + pub SetAllDefaults: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub SetValueWithNotify: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, *const super::super::System::Variant::VARIANT, *mut *mut windows_core::GUID, *mut u32) -> windows_core::HRESULT, + #[cfg(not(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant")))] + SetValueWithNotify: usize, + pub SetAllDefaultsWithNotify: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut windows_core::GUID, *mut u32) -> windows_core::HRESULT, + #[cfg(feature = "Win32_System_Com")] + pub GetAllSettings: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Win32_System_Com"))] + GetAllSettings: usize, + #[cfg(feature = "Win32_System_Com")] + pub SetAllSettings: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + #[cfg(not(feature = "Win32_System_Com"))] + SetAllSettings: usize, + #[cfg(feature = "Win32_System_Com")] + pub SetAllSettingsWithNotify: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut windows_core::GUID, *mut u32) -> windows_core::HRESULT, + #[cfg(not(feature = "Win32_System_Com"))] + SetAllSettingsWithNotify: usize, +} +#[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] +pub trait ICodecAPI_Impl: windows_core::IUnknownImpl { + fn IsSupported(&self, api: *const windows_core::GUID) -> windows_core::Result<()>; + fn IsModifiable(&self, api: *const windows_core::GUID) -> windows_core::HRESULT; + fn GetParameterRange(&self, api: *const windows_core::GUID, valuemin: *mut super::super::System::Variant::VARIANT, valuemax: *mut super::super::System::Variant::VARIANT, steppingdelta: *mut super::super::System::Variant::VARIANT) -> windows_core::Result<()>; + fn GetParameterValues(&self, api: *const windows_core::GUID, values: *mut *mut super::super::System::Variant::VARIANT, valuescount: *mut u32) -> windows_core::Result<()>; + fn GetDefaultValue(&self, api: *const windows_core::GUID) -> windows_core::Result; + fn GetValue(&self, api: *const windows_core::GUID) -> windows_core::Result; + fn SetValue(&self, api: *const windows_core::GUID, value: *const super::super::System::Variant::VARIANT) -> windows_core::Result<()>; + fn RegisterForEvent(&self, api: *const windows_core::GUID, userdata: isize) -> windows_core::Result<()>; + fn UnregisterForEvent(&self, api: *const windows_core::GUID) -> windows_core::Result<()>; + fn SetAllDefaults(&self) -> windows_core::Result<()>; + fn SetValueWithNotify(&self, api: *const windows_core::GUID, value: *const super::super::System::Variant::VARIANT, changedparam: *mut *mut windows_core::GUID, changedparamcount: *mut u32) -> windows_core::Result<()>; + fn SetAllDefaultsWithNotify(&self, changedparam: *mut *mut windows_core::GUID, changedparamcount: *mut u32) -> windows_core::Result<()>; + fn GetAllSettings(&self, __midl__icodecapi0000: windows_core::Ref<'_, super::super::System::Com::IStream>) -> windows_core::Result<()>; + fn SetAllSettings(&self, __midl__icodecapi0001: windows_core::Ref<'_, super::super::System::Com::IStream>) -> windows_core::Result<()>; + fn SetAllSettingsWithNotify(&self, __midl__icodecapi0002: windows_core::Ref<'_, super::super::System::Com::IStream>, changedparam: *mut *mut windows_core::GUID, changedparamcount: *mut u32) -> windows_core::Result<()>; +} +#[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] +impl ICodecAPI_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn IsSupported(this: *mut core::ffi::c_void, api: *const windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICodecAPI_Impl::IsSupported(this, core::mem::transmute_copy(&api)).into() + } + } + unsafe extern "system" fn IsModifiable(this: *mut core::ffi::c_void, api: *const windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICodecAPI_Impl::IsModifiable(this, core::mem::transmute_copy(&api)) + } + } + unsafe extern "system" fn GetParameterRange(this: *mut core::ffi::c_void, api: *const windows_core::GUID, valuemin: *mut super::super::System::Variant::VARIANT, valuemax: *mut super::super::System::Variant::VARIANT, steppingdelta: *mut super::super::System::Variant::VARIANT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICodecAPI_Impl::GetParameterRange(this, core::mem::transmute_copy(&api), core::mem::transmute_copy(&valuemin), core::mem::transmute_copy(&valuemax), core::mem::transmute_copy(&steppingdelta)).into() + } + } + unsafe extern "system" fn GetParameterValues(this: *mut core::ffi::c_void, api: *const windows_core::GUID, values: *mut *mut super::super::System::Variant::VARIANT, valuescount: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICodecAPI_Impl::GetParameterValues(this, core::mem::transmute_copy(&api), core::mem::transmute_copy(&values), core::mem::transmute_copy(&valuescount)).into() + } + } + unsafe extern "system" fn GetDefaultValue(this: *mut core::ffi::c_void, api: *const windows_core::GUID, value: *mut super::super::System::Variant::VARIANT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICodecAPI_Impl::GetDefaultValue(this, core::mem::transmute_copy(&api)) { + Ok(ok__) => { + value.write(core::mem::transmute(ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn GetValue(this: *mut core::ffi::c_void, api: *const windows_core::GUID, value: *mut super::super::System::Variant::VARIANT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match ICodecAPI_Impl::GetValue(this, core::mem::transmute_copy(&api)) { + Ok(ok__) => { + value.write(core::mem::transmute(ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetValue(this: *mut core::ffi::c_void, api: *const windows_core::GUID, value: *const super::super::System::Variant::VARIANT) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICodecAPI_Impl::SetValue(this, core::mem::transmute_copy(&api), core::mem::transmute_copy(&value)).into() + } + } + unsafe extern "system" fn RegisterForEvent(this: *mut core::ffi::c_void, api: *const windows_core::GUID, userdata: isize) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICodecAPI_Impl::RegisterForEvent(this, core::mem::transmute_copy(&api), core::mem::transmute_copy(&userdata)).into() + } + } + unsafe extern "system" fn UnregisterForEvent(this: *mut core::ffi::c_void, api: *const windows_core::GUID) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICodecAPI_Impl::UnregisterForEvent(this, core::mem::transmute_copy(&api)).into() + } + } + unsafe extern "system" fn SetAllDefaults(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICodecAPI_Impl::SetAllDefaults(this).into() + } + } + unsafe extern "system" fn SetValueWithNotify(this: *mut core::ffi::c_void, api: *const windows_core::GUID, value: *const super::super::System::Variant::VARIANT, changedparam: *mut *mut windows_core::GUID, changedparamcount: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICodecAPI_Impl::SetValueWithNotify(this, core::mem::transmute_copy(&api), core::mem::transmute_copy(&value), core::mem::transmute_copy(&changedparam), core::mem::transmute_copy(&changedparamcount)).into() + } + } + unsafe extern "system" fn SetAllDefaultsWithNotify(this: *mut core::ffi::c_void, changedparam: *mut *mut windows_core::GUID, changedparamcount: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICodecAPI_Impl::SetAllDefaultsWithNotify(this, core::mem::transmute_copy(&changedparam), core::mem::transmute_copy(&changedparamcount)).into() + } + } + unsafe extern "system" fn GetAllSettings(this: *mut core::ffi::c_void, __midl__icodecapi0000: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICodecAPI_Impl::GetAllSettings(this, core::mem::transmute_copy(&__midl__icodecapi0000)).into() + } + } + unsafe extern "system" fn SetAllSettings(this: *mut core::ffi::c_void, __midl__icodecapi0001: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICodecAPI_Impl::SetAllSettings(this, core::mem::transmute_copy(&__midl__icodecapi0001)).into() + } + } + unsafe extern "system" fn SetAllSettingsWithNotify(this: *mut core::ffi::c_void, __midl__icodecapi0002: *mut core::ffi::c_void, changedparam: *mut *mut windows_core::GUID, changedparamcount: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + ICodecAPI_Impl::SetAllSettingsWithNotify(this, core::mem::transmute_copy(&__midl__icodecapi0002), core::mem::transmute_copy(&changedparam), core::mem::transmute_copy(&changedparamcount)).into() + } + } + Self { + base__: windows_core::IUnknown_Vtbl::new::(), + IsSupported: IsSupported::, + IsModifiable: IsModifiable::, + GetParameterRange: GetParameterRange::, + GetParameterValues: GetParameterValues::, + GetDefaultValue: GetDefaultValue::, + GetValue: GetValue::, + SetValue: SetValue::, + RegisterForEvent: RegisterForEvent::, + UnregisterForEvent: UnregisterForEvent::, + SetAllDefaults: SetAllDefaults::, + SetValueWithNotify: SetValueWithNotify::, + SetAllDefaultsWithNotify: SetAllDefaultsWithNotify::, + GetAllSettings: GetAllSettings::, + SetAllSettings: SetAllSettings::, + SetAllSettingsWithNotify: SetAllSettingsWithNotify::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +#[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] +impl windows_core::RuntimeName for ICodecAPI {} windows_core::imp::define_interface!(IMFASFMutualExclusion, IMFASFMutualExclusion_Vtbl, 0x12558291_e399_11d5_bc2a_00b0d0f3f4ab); windows_core::imp::interface_hierarchy!(IMFASFMutualExclusion, windows_core::IUnknown); +impl IMFASFMutualExclusion { + pub unsafe fn GetType(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetType)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn SetType(&self, guidtype: *const windows_core::GUID) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetType)(windows_core::Interface::as_raw(self), guidtype).ok() } + } + pub unsafe fn GetRecordCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetRecordCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetStreamsForRecord(&self, dwrecordnumber: u32, pwstreamnumarray: *mut u16, pcstreams: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetStreamsForRecord)(windows_core::Interface::as_raw(self), dwrecordnumber, pwstreamnumarray as _, pcstreams as _).ok() } + } + pub unsafe fn AddStreamForRecord(&self, dwrecordnumber: u32, wstreamnumber: u16) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).AddStreamForRecord)(windows_core::Interface::as_raw(self), dwrecordnumber, wstreamnumber).ok() } + } + pub unsafe fn RemoveStreamFromRecord(&self, dwrecordnumber: u32, wstreamnumber: u16) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveStreamFromRecord)(windows_core::Interface::as_raw(self), dwrecordnumber, wstreamnumber).ok() } + } + pub unsafe fn RemoveRecord(&self, dwrecordnumber: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveRecord)(windows_core::Interface::as_raw(self), dwrecordnumber).ok() } + } + pub unsafe fn AddRecord(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).AddRecord)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn Clone(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Clone)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFASFMutualExclusion_Vtbl { @@ -34799,6 +122578,95 @@ impl core::ops::Deref for IMFASFProfile { } } windows_core::imp::interface_hierarchy!(IMFASFProfile, windows_core::IUnknown, IMFAttributes); +impl IMFASFProfile { + pub unsafe fn GetStreamCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetStream(&self, dwstreamindex: u32, pwstreamnumber: *mut u16, ppistream: *mut Option) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetStream)(windows_core::Interface::as_raw(self), dwstreamindex, pwstreamnumber as _, core::mem::transmute(ppistream)).ok() } + } + pub unsafe fn GetStreamByNumber(&self, wstreamnumber: u16) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamByNumber)(windows_core::Interface::as_raw(self), wstreamnumber, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn SetStream(&self, pistream: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetStream)(windows_core::Interface::as_raw(self), pistream.param().abi()).ok() } + } + pub unsafe fn RemoveStream(&self, wstreamnumber: u16) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveStream)(windows_core::Interface::as_raw(self), wstreamnumber).ok() } + } + pub unsafe fn CreateStream(&self, pimediatype: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateStream)(windows_core::Interface::as_raw(self), pimediatype.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetMutualExclusionCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMutualExclusionCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetMutualExclusion(&self, dwmutexindex: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMutualExclusion)(windows_core::Interface::as_raw(self), dwmutexindex, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn AddMutualExclusion(&self, pimutex: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).AddMutualExclusion)(windows_core::Interface::as_raw(self), pimutex.param().abi()).ok() } + } + pub unsafe fn RemoveMutualExclusion(&self, dwmutexindex: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveMutualExclusion)(windows_core::Interface::as_raw(self), dwmutexindex).ok() } + } + pub unsafe fn CreateMutualExclusion(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateMutualExclusion)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetStreamPrioritization(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamPrioritization)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn AddStreamPrioritization(&self, pistreamprioritization: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).AddStreamPrioritization)(windows_core::Interface::as_raw(self), pistreamprioritization.param().abi()).ok() } + } + pub unsafe fn RemoveStreamPrioritization(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveStreamPrioritization)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn CreateStreamPrioritization(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateStreamPrioritization)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn Clone(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Clone)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFASFProfile_Vtbl { @@ -34823,18 +122691,18 @@ pub struct IMFASFProfile_Vtbl { #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub trait IMFASFProfile_Impl: IMFAttributes_Impl { fn GetStreamCount(&self) -> windows_core::Result; - fn GetStream(&self, dwstreamindex: u32, pwstreamnumber: *mut u16, ppistream: windows_core::OutRef) -> windows_core::Result<()>; + fn GetStream(&self, dwstreamindex: u32, pwstreamnumber: *mut u16, ppistream: windows_core::OutRef<'_, IMFASFStreamConfig>) -> windows_core::Result<()>; fn GetStreamByNumber(&self, wstreamnumber: u16) -> windows_core::Result; - fn SetStream(&self, pistream: windows_core::Ref) -> windows_core::Result<()>; + fn SetStream(&self, pistream: windows_core::Ref<'_, IMFASFStreamConfig>) -> windows_core::Result<()>; fn RemoveStream(&self, wstreamnumber: u16) -> windows_core::Result<()>; - fn CreateStream(&self, pimediatype: windows_core::Ref) -> windows_core::Result; + fn CreateStream(&self, pimediatype: windows_core::Ref<'_, IMFMediaType>) -> windows_core::Result; fn GetMutualExclusionCount(&self) -> windows_core::Result; fn GetMutualExclusion(&self, dwmutexindex: u32) -> windows_core::Result; - fn AddMutualExclusion(&self, pimutex: windows_core::Ref) -> windows_core::Result<()>; + fn AddMutualExclusion(&self, pimutex: windows_core::Ref<'_, IMFASFMutualExclusion>) -> windows_core::Result<()>; fn RemoveMutualExclusion(&self, dwmutexindex: u32) -> windows_core::Result<()>; fn CreateMutualExclusion(&self) -> windows_core::Result; fn GetStreamPrioritization(&self) -> windows_core::Result; - fn AddStreamPrioritization(&self, pistreamprioritization: windows_core::Ref) -> windows_core::Result<()>; + fn AddStreamPrioritization(&self, pistreamprioritization: windows_core::Ref<'_, IMFASFStreamPrioritization>) -> windows_core::Result<()>; fn RemoveStreamPrioritization(&self) -> windows_core::Result<()>; fn CreateStreamPrioritization(&self) -> windows_core::Result; fn Clone(&self) -> windows_core::Result; @@ -35026,6 +122894,53 @@ impl core::ops::Deref for IMFASFStreamConfig { } } windows_core::imp::interface_hierarchy!(IMFASFStreamConfig, windows_core::IUnknown, IMFAttributes); +impl IMFASFStreamConfig { + pub unsafe fn GetStreamType(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamType)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetStreamNumber(&self) -> u16 { + unsafe { (windows_core::Interface::vtable(self).GetStreamNumber)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn SetStreamNumber(&self, wstreamnum: u16) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetStreamNumber)(windows_core::Interface::as_raw(self), wstreamnum).ok() } + } + pub unsafe fn GetMediaType(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMediaType)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn SetMediaType(&self, pimediatype: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetMediaType)(windows_core::Interface::as_raw(self), pimediatype.param().abi()).ok() } + } + pub unsafe fn GetPayloadExtensionCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetPayloadExtensionCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetPayloadExtension(&self, wpayloadextensionnumber: u16, pguidextensionsystemid: *mut windows_core::GUID, pcbextensiondatasize: *mut u16, pbextensionsysteminfo: *mut u8, pcbextensionsysteminfo: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetPayloadExtension)(windows_core::Interface::as_raw(self), wpayloadextensionnumber, pguidextensionsystemid as _, pcbextensiondatasize as _, pbextensionsysteminfo as _, pcbextensionsysteminfo as _).ok() } + } + pub unsafe fn AddPayloadExtension(&self, guidextensionsystemid: windows_core::GUID, cbextensiondatasize: u16, pbextensionsysteminfo: &[u8]) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).AddPayloadExtension)(windows_core::Interface::as_raw(self), core::mem::transmute(guidextensionsystemid), cbextensiondatasize, core::mem::transmute(pbextensionsysteminfo.as_ptr()), pbextensionsysteminfo.len().try_into().unwrap()).ok() } + } + pub unsafe fn RemoveAllPayloadExtensions(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveAllPayloadExtensions)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn Clone(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Clone)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFASFStreamConfig_Vtbl { @@ -35047,7 +122962,7 @@ pub trait IMFASFStreamConfig_Impl: IMFAttributes_Impl { fn GetStreamNumber(&self) -> u16; fn SetStreamNumber(&self, wstreamnum: u16) -> windows_core::Result<()>; fn GetMediaType(&self) -> windows_core::Result; - fn SetMediaType(&self, pimediatype: windows_core::Ref) -> windows_core::Result<()>; + fn SetMediaType(&self, pimediatype: windows_core::Ref<'_, IMFMediaType>) -> windows_core::Result<()>; fn GetPayloadExtensionCount(&self) -> windows_core::Result; fn GetPayloadExtension(&self, wpayloadextensionnumber: u16, pguidextensionsystemid: *mut windows_core::GUID, pcbextensiondatasize: *mut u16, pbextensionsysteminfo: *mut u8, pcbextensionsysteminfo: *mut u32) -> windows_core::Result<()>; fn AddPayloadExtension(&self, guidextensionsystemid: &windows_core::GUID, cbextensiondatasize: u16, pbextensionsysteminfo: *const u8, cbextensionsysteminfo: u32) -> windows_core::Result<()>; @@ -35163,6 +123078,29 @@ impl IMFASFStreamConfig_Vtbl { impl windows_core::RuntimeName for IMFASFStreamConfig {} windows_core::imp::define_interface!(IMFASFStreamPrioritization, IMFASFStreamPrioritization_Vtbl, 0x699bdc27_bbaf_49ff_8e38_9c39c9b5e088); windows_core::imp::interface_hierarchy!(IMFASFStreamPrioritization, windows_core::IUnknown); +impl IMFASFStreamPrioritization { + pub unsafe fn GetStreamCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetStream(&self, dwstreamindex: u32, pwstreamnumber: *mut u16, pwstreamflags: *mut u16) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetStream)(windows_core::Interface::as_raw(self), dwstreamindex, pwstreamnumber as _, pwstreamflags as _).ok() } + } + pub unsafe fn AddStream(&self, wstreamnumber: u16, wstreamflags: u16) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).AddStream)(windows_core::Interface::as_raw(self), wstreamnumber, wstreamflags).ok() } + } + pub unsafe fn RemoveStream(&self, dwstreamindex: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveStream)(windows_core::Interface::as_raw(self), dwstreamindex).ok() } + } + pub unsafe fn Clone(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Clone)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFASFStreamPrioritization_Vtbl { @@ -35254,7 +123192,13 @@ impl IMFActivate { let mut result__ = core::ptr::null_mut(); unsafe { (windows_core::Interface::vtable(self).ActivateObject)(windows_core::Interface::as_raw(self), &T::IID, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub unsafe fn ShutdownObject(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).ShutdownObject)(windows_core::Interface::as_raw(self)).ok() } } + pub unsafe fn DetachObject(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).DetachObject)(windows_core::Interface::as_raw(self)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFActivate_Vtbl { @@ -35305,6 +123249,17 @@ impl IMFActivate_Vtbl { impl windows_core::RuntimeName for IMFActivate {} windows_core::imp::define_interface!(IMFAsyncCallback, IMFAsyncCallback_Vtbl, 0xa27003cf_2354_4f2a_8d6a_ab7cff15437e); windows_core::imp::interface_hierarchy!(IMFAsyncCallback, windows_core::IUnknown); +impl IMFAsyncCallback { + pub unsafe fn GetParameters(&self, pdwflags: *mut u32, pdwqueue: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetParameters)(windows_core::Interface::as_raw(self), pdwflags as _, pdwqueue as _).ok() } + } + pub unsafe fn Invoke(&self, pasyncresult: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).Invoke)(windows_core::Interface::as_raw(self), pasyncresult.param().abi()).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFAsyncCallback_Vtbl { @@ -35314,7 +123269,7 @@ pub struct IMFAsyncCallback_Vtbl { } pub trait IMFAsyncCallback_Impl: windows_core::IUnknownImpl { fn GetParameters(&self, pdwflags: *mut u32, pdwqueue: *mut u32) -> windows_core::Result<()>; - fn Invoke(&self, pasyncresult: windows_core::Ref) -> windows_core::Result<()>; + fn Invoke(&self, pasyncresult: windows_core::Ref<'_, IMFAsyncResult>) -> windows_core::Result<()>; } impl IMFAsyncCallback_Vtbl { pub const fn new() -> Self { @@ -35349,6 +123304,14 @@ impl core::ops::Deref for IMFAsyncCallbackLogging { } } windows_core::imp::interface_hierarchy!(IMFAsyncCallbackLogging, windows_core::IUnknown, IMFAsyncCallback); +impl IMFAsyncCallbackLogging { + pub unsafe fn GetObjectPointer(&self) -> *mut core::ffi::c_void { + unsafe { (windows_core::Interface::vtable(self).GetObjectPointer)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetObjectTag(&self) -> u32 { + unsafe { (windows_core::Interface::vtable(self).GetObjectTag)(windows_core::Interface::as_raw(self)) } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFAsyncCallbackLogging_Vtbl { @@ -35387,6 +123350,29 @@ impl IMFAsyncCallbackLogging_Vtbl { impl windows_core::RuntimeName for IMFAsyncCallbackLogging {} windows_core::imp::define_interface!(IMFAsyncResult, IMFAsyncResult_Vtbl, 0xac6b7889_0740_4d51_8619_905994a55cc6); windows_core::imp::interface_hierarchy!(IMFAsyncResult, windows_core::IUnknown); +impl IMFAsyncResult { + pub unsafe fn GetState(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetState)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetStatus(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetStatus)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn SetStatus(&self, hrstatus: windows_core::HRESULT) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetStatus)(windows_core::Interface::as_raw(self), hrstatus).ok() } + } + pub unsafe fn GetObject(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetObject)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetStateNoAddRef(&self) -> Option { + unsafe { (windows_core::Interface::vtable(self).GetStateNoAddRef)(windows_core::Interface::as_raw(self)) } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFAsyncResult_Vtbl { @@ -35465,6 +123451,32 @@ impl windows_core::RuntimeName for IMFAsyncResult {} windows_core::imp::define_interface!(IMFAttributes, IMFAttributes_Vtbl, 0x2cd2d921_c447_44a7_a13c_4adabfc247e3); windows_core::imp::interface_hierarchy!(IMFAttributes, windows_core::IUnknown); impl IMFAttributes { + #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] + pub unsafe fn GetItem(&self, guidkey: *const windows_core::GUID, pvalue: Option<*mut super::super::System::Com::StructuredStorage::PROPVARIANT>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetItem)(windows_core::Interface::as_raw(self), guidkey, pvalue.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn GetItemType(&self, guidkey: *const windows_core::GUID) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetItemType)(windows_core::Interface::as_raw(self), guidkey, &mut result__).map(|| result__) + } + } + #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] + pub unsafe fn CompareItem(&self, guidkey: *const windows_core::GUID, value: *const super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CompareItem)(windows_core::Interface::as_raw(self), guidkey, core::mem::transmute(value), &mut result__).map(|| result__) + } + } + pub unsafe fn Compare(&self, ptheirs: P0, matchtype: MF_ATTRIBUTES_MATCH_TYPE) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Compare)(windows_core::Interface::as_raw(self), ptheirs.param().abi(), matchtype, &mut result__).map(|| result__) + } + } pub unsafe fn GetUINT32(&self, guidkey: *const windows_core::GUID) -> windows_core::Result { unsafe { let mut result__ = core::mem::zeroed(); @@ -35477,20 +123489,58 @@ impl IMFAttributes { (windows_core::Interface::vtable(self).GetUINT64)(windows_core::Interface::as_raw(self), guidkey, &mut result__).map(|| result__) } } + pub unsafe fn GetDouble(&self, guidkey: *const windows_core::GUID) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDouble)(windows_core::Interface::as_raw(self), guidkey, &mut result__).map(|| result__) + } + } pub unsafe fn GetGUID(&self, guidkey: *const windows_core::GUID) -> windows_core::Result { unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(self).GetGUID)(windows_core::Interface::as_raw(self), guidkey, &mut result__).map(|| result__) } } + pub unsafe fn GetStringLength(&self, guidkey: *const windows_core::GUID) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStringLength)(windows_core::Interface::as_raw(self), guidkey, &mut result__).map(|| result__) + } + } + pub unsafe fn GetString(&self, guidkey: *const windows_core::GUID, pwszvalue: &mut [u16], pcchlength: Option<*mut u32>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetString)(windows_core::Interface::as_raw(self), guidkey, core::mem::transmute(pwszvalue.as_ptr()), pwszvalue.len().try_into().unwrap(), pcchlength.unwrap_or(core::mem::zeroed()) as _).ok() } + } pub unsafe fn GetAllocatedString(&self, guidkey: *const windows_core::GUID, ppwszvalue: *mut windows_core::PWSTR, pcchlength: *mut u32) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).GetAllocatedString)(windows_core::Interface::as_raw(self), guidkey, ppwszvalue as _, pcchlength as _).ok() } } - pub unsafe fn SetString(&self, guidkey: *const windows_core::GUID, wszvalue: P0) -> windows_core::Result<()> + pub unsafe fn GetBlobSize(&self, guidkey: *const windows_core::GUID) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetBlobSize)(windows_core::Interface::as_raw(self), guidkey, &mut result__).map(|| result__) + } + } + pub unsafe fn GetBlob(&self, guidkey: *const windows_core::GUID, pbuf: &mut [u8], pcbblobsize: Option<*mut u32>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetBlob)(windows_core::Interface::as_raw(self), guidkey, core::mem::transmute(pbuf.as_ptr()), pbuf.len().try_into().unwrap(), pcbblobsize.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn GetAllocatedBlob(&self, guidkey: *const windows_core::GUID, ppbuf: *mut *mut u8, pcbsize: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetAllocatedBlob)(windows_core::Interface::as_raw(self), guidkey, ppbuf as _, pcbsize as _).ok() } + } + pub unsafe fn GetUnknown(&self, guidkey: *const windows_core::GUID) -> windows_core::Result where - P0: windows_core::Param, + T: windows_core::Interface, { - unsafe { (windows_core::Interface::vtable(self).SetString)(windows_core::Interface::as_raw(self), guidkey, wszvalue.param().abi()).ok() } + let mut result__ = core::ptr::null_mut(); + unsafe { (windows_core::Interface::vtable(self).GetUnknown)(windows_core::Interface::as_raw(self), guidkey, &T::IID, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } + } + #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] + pub unsafe fn SetItem(&self, guidkey: *const windows_core::GUID, value: *const super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetItem)(windows_core::Interface::as_raw(self), guidkey, core::mem::transmute(value)).ok() } + } + pub unsafe fn DeleteItem(&self, guidkey: *const windows_core::GUID) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).DeleteItem)(windows_core::Interface::as_raw(self), guidkey).ok() } + } + pub unsafe fn DeleteAllItems(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).DeleteAllItems)(windows_core::Interface::as_raw(self)).ok() } } pub unsafe fn SetUINT32(&self, guidkey: *const windows_core::GUID, unvalue: u32) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetUINT32)(windows_core::Interface::as_raw(self), guidkey, unvalue).ok() } @@ -35498,22 +123548,50 @@ impl IMFAttributes { pub unsafe fn SetUINT64(&self, guidkey: *const windows_core::GUID, unvalue: u64) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetUINT64)(windows_core::Interface::as_raw(self), guidkey, unvalue).ok() } } + pub unsafe fn SetDouble(&self, guidkey: *const windows_core::GUID, fvalue: f64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetDouble)(windows_core::Interface::as_raw(self), guidkey, fvalue).ok() } + } pub unsafe fn SetGUID(&self, guidkey: *const windows_core::GUID, guidvalue: *const windows_core::GUID) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetGUID)(windows_core::Interface::as_raw(self), guidkey, guidvalue).ok() } } + pub unsafe fn SetString(&self, guidkey: *const windows_core::GUID, wszvalue: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetString)(windows_core::Interface::as_raw(self), guidkey, wszvalue.param().abi()).ok() } + } + pub unsafe fn SetBlob(&self, guidkey: *const windows_core::GUID, pbuf: &[u8]) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetBlob)(windows_core::Interface::as_raw(self), guidkey, core::mem::transmute(pbuf.as_ptr()), pbuf.len().try_into().unwrap()).ok() } + } pub unsafe fn SetUnknown(&self, guidkey: *const windows_core::GUID, punknown: P1) -> windows_core::Result<()> where P1: windows_core::Param, { unsafe { (windows_core::Interface::vtable(self).SetUnknown)(windows_core::Interface::as_raw(self), guidkey, punknown.param().abi()).ok() } } + pub unsafe fn LockStore(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).LockStore)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn UnlockStore(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).UnlockStore)(windows_core::Interface::as_raw(self)).ok() } + } pub unsafe fn GetCount(&self) -> windows_core::Result { unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(self).GetCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) } } + #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] + pub unsafe fn GetItemByIndex(&self, unindex: u32, pguidkey: *mut windows_core::GUID, pvalue: Option<*mut super::super::System::Com::StructuredStorage::PROPVARIANT>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetItemByIndex)(windows_core::Interface::as_raw(self), unindex, pguidkey as _, pvalue.unwrap_or(core::mem::zeroed()) as _).ok() } } + pub unsafe fn CopyAllItems(&self, pdest: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CopyAllItems)(windows_core::Interface::as_raw(self), pdest.param().abi()).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFAttributes_Vtbl { @@ -35566,7 +123644,7 @@ pub trait IMFAttributes_Impl: windows_core::IUnknownImpl { fn GetItem(&self, guidkey: *const windows_core::GUID, pvalue: *mut super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result<()>; fn GetItemType(&self, guidkey: *const windows_core::GUID) -> windows_core::Result; fn CompareItem(&self, guidkey: *const windows_core::GUID, value: *const super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result; - fn Compare(&self, ptheirs: windows_core::Ref, matchtype: MF_ATTRIBUTES_MATCH_TYPE) -> windows_core::Result; + fn Compare(&self, ptheirs: windows_core::Ref<'_, IMFAttributes>, matchtype: MF_ATTRIBUTES_MATCH_TYPE) -> windows_core::Result; fn GetUINT32(&self, guidkey: *const windows_core::GUID) -> windows_core::Result; fn GetUINT64(&self, guidkey: *const windows_core::GUID) -> windows_core::Result; fn GetDouble(&self, guidkey: *const windows_core::GUID) -> windows_core::Result; @@ -35587,12 +123665,12 @@ pub trait IMFAttributes_Impl: windows_core::IUnknownImpl { fn SetGUID(&self, guidkey: *const windows_core::GUID, guidvalue: *const windows_core::GUID) -> windows_core::Result<()>; fn SetString(&self, guidkey: *const windows_core::GUID, wszvalue: &windows_core::PCWSTR) -> windows_core::Result<()>; fn SetBlob(&self, guidkey: *const windows_core::GUID, pbuf: *const u8, cbbufsize: u32) -> windows_core::Result<()>; - fn SetUnknown(&self, guidkey: *const windows_core::GUID, punknown: windows_core::Ref) -> windows_core::Result<()>; + fn SetUnknown(&self, guidkey: *const windows_core::GUID, punknown: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; fn LockStore(&self) -> windows_core::Result<()>; fn UnlockStore(&self) -> windows_core::Result<()>; fn GetCount(&self) -> windows_core::Result; fn GetItemByIndex(&self, unindex: u32, pguidkey: *mut windows_core::GUID, pvalue: *mut super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result<()>; - fn CopyAllItems(&self, pdest: windows_core::Ref) -> windows_core::Result<()>; + fn CopyAllItems(&self, pdest: windows_core::Ref<'_, IMFAttributes>) -> windows_core::Result<()>; } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] impl IMFAttributes_Vtbl { @@ -35885,6 +123963,12 @@ impl core::ops::Deref for IMFAudioMediaType { } } windows_core::imp::interface_hierarchy!(IMFAudioMediaType, windows_core::IUnknown, IMFAttributes, IMFMediaType); +impl IMFAudioMediaType { + #[cfg(feature = "Win32_Media_Audio")] + pub unsafe fn GetAudioFormat(&self) -> *mut super::Audio::WAVEFORMATEX { + unsafe { (windows_core::Interface::vtable(self).GetAudioFormat)(windows_core::Interface::as_raw(self)) } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFAudioMediaType_Vtbl { @@ -35918,9 +124002,77 @@ impl windows_core::RuntimeName for IMFAudioMediaType {} windows_core::imp::define_interface!(IMFByteStream, IMFByteStream_Vtbl, 0xad4c1b00_4bf7_422f_9175_756693d9130d); windows_core::imp::interface_hierarchy!(IMFByteStream, windows_core::IUnknown); impl IMFByteStream { + pub unsafe fn GetCapabilities(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetCapabilities)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetLength(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetLength)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn SetLength(&self, qwlength: u64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetLength)(windows_core::Interface::as_raw(self), qwlength).ok() } + } + pub unsafe fn GetCurrentPosition(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetCurrentPosition)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } pub unsafe fn SetCurrentPosition(&self, qwposition: u64) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetCurrentPosition)(windows_core::Interface::as_raw(self), qwposition).ok() } } + pub unsafe fn IsEndOfStream(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).IsEndOfStream)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn Read(&self, pb: &mut [u8], pcbread: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Read)(windows_core::Interface::as_raw(self), core::mem::transmute(pb.as_ptr()), pb.len().try_into().unwrap(), pcbread as _).ok() } + } + pub unsafe fn BeginRead(&self, pb: &mut [u8], pcallback: P2, punkstate: P3) -> windows_core::Result<()> + where + P2: windows_core::Param, + P3: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).BeginRead)(windows_core::Interface::as_raw(self), core::mem::transmute(pb.as_ptr()), pb.len().try_into().unwrap(), pcallback.param().abi(), punkstate.param().abi()).ok() } + } + pub unsafe fn EndRead(&self, presult: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).EndRead)(windows_core::Interface::as_raw(self), presult.param().abi(), &mut result__).map(|| result__) + } + } + pub unsafe fn Write(&self, pb: &[u8]) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Write)(windows_core::Interface::as_raw(self), core::mem::transmute(pb.as_ptr()), pb.len().try_into().unwrap(), &mut result__).map(|| result__) + } + } + pub unsafe fn BeginWrite(&self, pb: &[u8], pcallback: P2, punkstate: P3) -> windows_core::Result<()> + where + P2: windows_core::Param, + P3: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).BeginWrite)(windows_core::Interface::as_raw(self), core::mem::transmute(pb.as_ptr()), pb.len().try_into().unwrap(), pcallback.param().abi(), punkstate.param().abi()).ok() } + } + pub unsafe fn EndWrite(&self, presult: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).EndWrite)(windows_core::Interface::as_raw(self), presult.param().abi(), &mut result__).map(|| result__) + } + } pub unsafe fn Seek(&self, seekorigin: MFBYTESTREAM_SEEK_ORIGIN, llseekoffset: i64, dwseekflags: u32) -> windows_core::Result { unsafe { let mut result__ = core::mem::zeroed(); @@ -35962,11 +124114,11 @@ pub trait IMFByteStream_Impl: windows_core::IUnknownImpl { fn SetCurrentPosition(&self, qwposition: u64) -> windows_core::Result<()>; fn IsEndOfStream(&self) -> windows_core::Result; fn Read(&self, pb: *mut u8, cb: u32, pcbread: *mut u32) -> windows_core::Result<()>; - fn BeginRead(&self, pb: *mut u8, cb: u32, pcallback: windows_core::Ref, punkstate: windows_core::Ref) -> windows_core::Result<()>; - fn EndRead(&self, presult: windows_core::Ref) -> windows_core::Result; + fn BeginRead(&self, pb: *mut u8, cb: u32, pcallback: windows_core::Ref<'_, IMFAsyncCallback>, punkstate: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; + fn EndRead(&self, presult: windows_core::Ref<'_, IMFAsyncResult>) -> windows_core::Result; fn Write(&self, pb: *const u8, cb: u32) -> windows_core::Result; - fn BeginWrite(&self, pb: *const u8, cb: u32, pcallback: windows_core::Ref, punkstate: windows_core::Ref) -> windows_core::Result<()>; - fn EndWrite(&self, presult: windows_core::Ref) -> windows_core::Result; + fn BeginWrite(&self, pb: *const u8, cb: u32, pcallback: windows_core::Ref<'_, IMFAsyncCallback>, punkstate: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; + fn EndWrite(&self, presult: windows_core::Ref<'_, IMFAsyncResult>) -> windows_core::Result; fn Seek(&self, seekorigin: MFBYTESTREAM_SEEK_ORIGIN, llseekoffset: i64, dwseekflags: u32) -> windows_core::Result; fn Flush(&self) -> windows_core::Result<()>; fn Close(&self) -> windows_core::Result<()>; @@ -36137,6 +124289,23 @@ impl IMFByteStream_Vtbl { impl windows_core::RuntimeName for IMFByteStream {} windows_core::imp::define_interface!(IMFCameraControlDefaults, IMFCameraControlDefaults_Vtbl, 0x75510662_b034_48f4_88a7_8de61daa4af9); windows_core::imp::interface_hierarchy!(IMFCameraControlDefaults, windows_core::IUnknown); +impl IMFCameraControlDefaults { + pub unsafe fn GetType(&self) -> MF_CAMERA_CONTROL_CONFIGURATION_TYPE { + unsafe { (windows_core::Interface::vtable(self).GetType)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetRangeInfo(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetRangeInfo)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn LockControlData(&self, control: *mut *mut core::ffi::c_void, controlsize: *mut u32, data: Option<*mut *mut core::ffi::c_void>, datasize: Option<*mut u32>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).LockControlData)(windows_core::Interface::as_raw(self), control as _, controlsize as _, data.unwrap_or(core::mem::zeroed()) as _, datasize.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn UnlockControlData(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).UnlockControlData)(windows_core::Interface::as_raw(self)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFCameraControlDefaults_Vtbl { @@ -36205,6 +124374,35 @@ impl core::ops::Deref for IMFCameraControlDefaultsCollection { } } windows_core::imp::interface_hierarchy!(IMFCameraControlDefaultsCollection, windows_core::IUnknown, IMFAttributes); +impl IMFCameraControlDefaultsCollection { + pub unsafe fn GetControlCount(&self) -> u32 { + unsafe { (windows_core::Interface::vtable(self).GetControlCount)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetControl(&self, index: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetControl)(windows_core::Interface::as_raw(self), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetOrAddExtendedControl(&self, configtype: MF_CAMERA_CONTROL_CONFIGURATION_TYPE, constrolid: u32, streamid: u32, datasize: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetOrAddExtendedControl)(windows_core::Interface::as_raw(self), configtype, constrolid, streamid, datasize, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetOrAddControl(&self, configtype: MF_CAMERA_CONTROL_CONFIGURATION_TYPE, controlset: *const windows_core::GUID, constrolid: u32, controlsize: u32, datasize: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetOrAddControl)(windows_core::Interface::as_raw(self), configtype, controlset, constrolid, controlsize, datasize, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn RemoveControl(&self, controlset: *const windows_core::GUID, constrolid: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveControl)(windows_core::Interface::as_raw(self), controlset, constrolid).ok() } + } + pub unsafe fn RemoveAllControls(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveAllControls)(windows_core::Interface::as_raw(self)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFCameraControlDefaultsCollection_Vtbl { @@ -36301,6 +124499,9 @@ impl windows_core::RuntimeName for IMFCameraControlDefaultsCollection {} windows_core::imp::define_interface!(IMFCameraSyncObject, IMFCameraSyncObject_Vtbl, 0x6338b23a_3042_49d2_a3ea_ec0fed815407); windows_core::imp::interface_hierarchy!(IMFCameraSyncObject, windows_core::IUnknown); impl IMFCameraSyncObject { + pub unsafe fn WaitOnSignal(&self, timeoutinms: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).WaitOnSignal)(windows_core::Interface::as_raw(self), timeoutinms).ok() } + } pub unsafe fn Shutdown(&self) { unsafe { (windows_core::Interface::vtable(self).Shutdown)(windows_core::Interface::as_raw(self)) } } @@ -36344,6 +124545,9 @@ impl windows_core::RuntimeName for IMFCameraSyncObject {} windows_core::imp::define_interface!(IMFCdmSuspendNotify, IMFCdmSuspendNotify_Vtbl, 0x7a5645d2_43bd_47fd_87b7_dcd24cc7d692); windows_core::imp::interface_hierarchy!(IMFCdmSuspendNotify, windows_core::IUnknown); impl IMFCdmSuspendNotify { + pub unsafe fn Begin(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Begin)(windows_core::Interface::as_raw(self)).ok() } + } pub unsafe fn End(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).End)(windows_core::Interface::as_raw(self)).ok() } } @@ -36382,6 +124586,32 @@ impl IMFCdmSuspendNotify_Vtbl { impl windows_core::RuntimeName for IMFCdmSuspendNotify {} windows_core::imp::define_interface!(IMFClock, IMFClock_Vtbl, 0x2eb1e945_18b8_4139_9b1a_d5d584818530); windows_core::imp::interface_hierarchy!(IMFClock, windows_core::IUnknown); +impl IMFClock { + pub unsafe fn GetClockCharacteristics(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetClockCharacteristics)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetCorrelatedTime(&self, dwreserved: u32, pllclocktime: *mut i64, phnssystemtime: *mut i64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetCorrelatedTime)(windows_core::Interface::as_raw(self), dwreserved, pllclocktime as _, phnssystemtime as _).ok() } + } + pub unsafe fn GetContinuityKey(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetContinuityKey)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetState(&self, dwreserved: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetState)(windows_core::Interface::as_raw(self), dwreserved, &mut result__).map(|| result__) + } + } + pub unsafe fn GetProperties(&self, pclockproperties: *mut MFCLOCK_PROPERTIES) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetProperties)(windows_core::Interface::as_raw(self), pclockproperties as _).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFClock_Vtbl { @@ -36465,6 +124695,23 @@ impl IMFClock_Vtbl { impl windows_core::RuntimeName for IMFClock {} windows_core::imp::define_interface!(IMFClockStateSink, IMFClockStateSink_Vtbl, 0xf6696e82_74f7_4f3d_a178_8a5e09c3659f); windows_core::imp::interface_hierarchy!(IMFClockStateSink, windows_core::IUnknown); +impl IMFClockStateSink { + pub unsafe fn OnClockStart(&self, hnssystemtime: i64, llclockstartoffset: i64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).OnClockStart)(windows_core::Interface::as_raw(self), hnssystemtime, llclockstartoffset).ok() } + } + pub unsafe fn OnClockStop(&self, hnssystemtime: i64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).OnClockStop)(windows_core::Interface::as_raw(self), hnssystemtime).ok() } + } + pub unsafe fn OnClockPause(&self, hnssystemtime: i64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).OnClockPause)(windows_core::Interface::as_raw(self), hnssystemtime).ok() } + } + pub unsafe fn OnClockRestart(&self, hnssystemtime: i64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).OnClockRestart)(windows_core::Interface::as_raw(self), hnssystemtime).ok() } + } + pub unsafe fn OnClockSetRate(&self, hnssystemtime: i64, flrate: f32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).OnClockSetRate)(windows_core::Interface::as_raw(self), hnssystemtime, flrate).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFClockStateSink_Vtbl { @@ -36530,6 +124777,41 @@ impl IMFClockStateSink_Vtbl { impl windows_core::RuntimeName for IMFClockStateSink {} windows_core::imp::define_interface!(IMFCollection, IMFCollection_Vtbl, 0x5bc8a76b_869a_46a3_9b03_fa218a66aebe); windows_core::imp::interface_hierarchy!(IMFCollection, windows_core::IUnknown); +impl IMFCollection { + pub unsafe fn GetElementCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetElementCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetElement(&self, dwelementindex: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetElement)(windows_core::Interface::as_raw(self), dwelementindex, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn AddElement(&self, punkelement: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).AddElement)(windows_core::Interface::as_raw(self), punkelement.param().abi()).ok() } + } + pub unsafe fn RemoveElement(&self, dwelementindex: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).RemoveElement)(windows_core::Interface::as_raw(self), dwelementindex, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn InsertElementAt(&self, dwindex: u32, punknown: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).InsertElementAt)(windows_core::Interface::as_raw(self), dwindex, punknown.param().abi()).ok() } + } + pub unsafe fn RemoveAllElements(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveAllElements)(windows_core::Interface::as_raw(self)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFCollection_Vtbl { @@ -36544,9 +124826,9 @@ pub struct IMFCollection_Vtbl { pub trait IMFCollection_Impl: windows_core::IUnknownImpl { fn GetElementCount(&self) -> windows_core::Result; fn GetElement(&self, dwelementindex: u32) -> windows_core::Result; - fn AddElement(&self, punkelement: windows_core::Ref) -> windows_core::Result<()>; + fn AddElement(&self, punkelement: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; fn RemoveElement(&self, dwelementindex: u32) -> windows_core::Result; - fn InsertElementAt(&self, dwindex: u32, punknown: windows_core::Ref) -> windows_core::Result<()>; + fn InsertElementAt(&self, dwindex: u32, punknown: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; fn RemoveAllElements(&self) -> windows_core::Result<()>; } impl IMFCollection_Vtbl { @@ -36632,6 +124914,9 @@ impl IMFDXGIBuffer { (windows_core::Interface::vtable(self).GetSubresourceIndex)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) } } + pub unsafe fn GetUnknown(&self, guid: *const windows_core::GUID, riid: *const windows_core::GUID, ppvobject: *mut *mut core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetUnknown)(windows_core::Interface::as_raw(self), guid, riid, ppvobject as _).ok() } + } pub unsafe fn SetUnknown(&self, guid: *const windows_core::GUID, punkdata: P1) -> windows_core::Result<()> where P1: windows_core::Param, @@ -36652,7 +124937,7 @@ pub trait IMFDXGIBuffer_Impl: windows_core::IUnknownImpl { fn GetResource(&self, riid: *const windows_core::GUID, ppvobject: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; fn GetSubresourceIndex(&self) -> windows_core::Result; fn GetUnknown(&self, guid: *const windows_core::GUID, riid: *const windows_core::GUID, ppvobject: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; - fn SetUnknown(&self, guid: *const windows_core::GUID, punkdata: windows_core::Ref) -> windows_core::Result<()>; + fn SetUnknown(&self, guid: *const windows_core::GUID, punkdata: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; } impl IMFDXGIBuffer_Vtbl { pub const fn new() -> Self { @@ -36702,13 +124987,34 @@ impl windows_core::RuntimeName for IMFDXGIBuffer {} windows_core::imp::define_interface!(IMFDXGIDeviceManager, IMFDXGIDeviceManager_Vtbl, 0xeb533d5d_2db6_40f8_97a9_494692014f07); windows_core::imp::interface_hierarchy!(IMFDXGIDeviceManager, windows_core::IUnknown); impl IMFDXGIDeviceManager { + pub unsafe fn CloseDeviceHandle(&self, hdevice: super::super::Foundation::HANDLE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CloseDeviceHandle)(windows_core::Interface::as_raw(self), hdevice).ok() } + } + pub unsafe fn GetVideoService(&self, hdevice: super::super::Foundation::HANDLE, riid: *const windows_core::GUID, ppservice: *mut *mut core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetVideoService)(windows_core::Interface::as_raw(self), hdevice, riid, ppservice as _).ok() } + } + pub unsafe fn LockDevice(&self, hdevice: super::super::Foundation::HANDLE, riid: *const windows_core::GUID, ppunkdevice: *mut *mut core::ffi::c_void, fblock: bool) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).LockDevice)(windows_core::Interface::as_raw(self), hdevice, riid, ppunkdevice as _, fblock.into()).ok() } + } + pub unsafe fn OpenDeviceHandle(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).OpenDeviceHandle)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } pub unsafe fn ResetDevice(&self, punkdevice: P0, resettoken: u32) -> windows_core::Result<()> where P0: windows_core::Param, { unsafe { (windows_core::Interface::vtable(self).ResetDevice)(windows_core::Interface::as_raw(self), punkdevice.param().abi(), resettoken).ok() } } + pub unsafe fn TestDevice(&self, hdevice: super::super::Foundation::HANDLE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).TestDevice)(windows_core::Interface::as_raw(self), hdevice).ok() } } + pub unsafe fn UnlockDevice(&self, hdevice: super::super::Foundation::HANDLE, fsavestate: bool) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).UnlockDevice)(windows_core::Interface::as_raw(self), hdevice, fsavestate.into()).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFDXGIDeviceManager_Vtbl { @@ -36726,7 +125032,7 @@ pub trait IMFDXGIDeviceManager_Impl: windows_core::IUnknownImpl { fn GetVideoService(&self, hdevice: super::super::Foundation::HANDLE, riid: *const windows_core::GUID, ppservice: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; fn LockDevice(&self, hdevice: super::super::Foundation::HANDLE, riid: *const windows_core::GUID, ppunkdevice: *mut *mut core::ffi::c_void, fblock: windows_core::BOOL) -> windows_core::Result<()>; fn OpenDeviceHandle(&self) -> windows_core::Result; - fn ResetDevice(&self, punkdevice: windows_core::Ref, resettoken: u32) -> windows_core::Result<()>; + fn ResetDevice(&self, punkdevice: windows_core::Ref<'_, windows_core::IUnknown>, resettoken: u32) -> windows_core::Result<()>; fn TestDevice(&self, hdevice: super::super::Foundation::HANDLE) -> windows_core::Result<()>; fn UnlockDevice(&self, hdevice: super::super::Foundation::HANDLE, fsavestate: windows_core::BOOL) -> windows_core::Result<()>; } @@ -36804,6 +125110,21 @@ impl core::ops::Deref for IMFFinalizableMediaSink { } } windows_core::imp::interface_hierarchy!(IMFFinalizableMediaSink, windows_core::IUnknown, IMFMediaSink); +impl IMFFinalizableMediaSink { + pub unsafe fn BeginFinalize(&self, pcallback: P0, punkstate: P1) -> windows_core::Result<()> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).BeginFinalize)(windows_core::Interface::as_raw(self), pcallback.param().abi(), punkstate.param().abi()).ok() } + } + pub unsafe fn EndFinalize(&self, presult: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).EndFinalize)(windows_core::Interface::as_raw(self), presult.param().abi()).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFFinalizableMediaSink_Vtbl { @@ -36812,8 +125133,8 @@ pub struct IMFFinalizableMediaSink_Vtbl { pub EndFinalize: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, } pub trait IMFFinalizableMediaSink_Impl: IMFMediaSink_Impl { - fn BeginFinalize(&self, pcallback: windows_core::Ref, punkstate: windows_core::Ref) -> windows_core::Result<()>; - fn EndFinalize(&self, presult: windows_core::Ref) -> windows_core::Result<()>; + fn BeginFinalize(&self, pcallback: windows_core::Ref<'_, IMFAsyncCallback>, punkstate: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; + fn EndFinalize(&self, presult: windows_core::Ref<'_, IMFAsyncResult>) -> windows_core::Result<()>; } impl IMFFinalizableMediaSink_Vtbl { pub const fn new() -> Self { @@ -36849,7 +125170,22 @@ impl IMFMediaBuffer { pub unsafe fn Unlock(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Unlock)(windows_core::Interface::as_raw(self)).ok() } } + pub unsafe fn GetCurrentLength(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetCurrentLength)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } } + pub unsafe fn SetCurrentLength(&self, cbcurrentlength: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetCurrentLength)(windows_core::Interface::as_raw(self), cbcurrentlength).ok() } + } + pub unsafe fn GetMaxLength(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMaxLength)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaBuffer_Vtbl { @@ -36934,24 +125270,105 @@ impl IMFMediaEngine { (windows_core::Interface::vtable(self).GetError)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub unsafe fn SetErrorCode(&self, error: MF_MEDIA_ENGINE_ERR) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetErrorCode)(windows_core::Interface::as_raw(self), error).ok() } + } + pub unsafe fn SetSourceElements(&self, psrcelements: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetSourceElements)(windows_core::Interface::as_raw(self), psrcelements.param().abi()).ok() } + } pub unsafe fn SetSource(&self, purl: &windows_core::BSTR) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetSource)(windows_core::Interface::as_raw(self), core::mem::transmute_copy(purl)).ok() } } + pub unsafe fn GetCurrentSource(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetCurrentSource)(windows_core::Interface::as_raw(self), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub unsafe fn GetNetworkState(&self) -> u16 { + unsafe { (windows_core::Interface::vtable(self).GetNetworkState)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetPreload(&self) -> MF_MEDIA_ENGINE_PRELOAD { + unsafe { (windows_core::Interface::vtable(self).GetPreload)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn SetPreload(&self, preload: MF_MEDIA_ENGINE_PRELOAD) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetPreload)(windows_core::Interface::as_raw(self), preload).ok() } + } + pub unsafe fn GetBuffered(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetBuffered)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn Load(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Load)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn CanPlayType(&self, r#type: &windows_core::BSTR) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CanPlayType)(windows_core::Interface::as_raw(self), core::mem::transmute_copy(r#type), &mut result__).map(|| result__) + } + } + pub unsafe fn GetReadyState(&self) -> u16 { + unsafe { (windows_core::Interface::vtable(self).GetReadyState)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn IsSeeking(&self) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).IsSeeking)(windows_core::Interface::as_raw(self)) } + } pub unsafe fn GetCurrentTime(&self) -> f64 { unsafe { (windows_core::Interface::vtable(self).GetCurrentTime)(windows_core::Interface::as_raw(self)) } } pub unsafe fn SetCurrentTime(&self, seektime: f64) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetCurrentTime)(windows_core::Interface::as_raw(self), seektime).ok() } } + pub unsafe fn GetStartTime(&self) -> f64 { + unsafe { (windows_core::Interface::vtable(self).GetStartTime)(windows_core::Interface::as_raw(self)) } + } pub unsafe fn GetDuration(&self) -> f64 { unsafe { (windows_core::Interface::vtable(self).GetDuration)(windows_core::Interface::as_raw(self)) } } pub unsafe fn IsPaused(&self) -> windows_core::BOOL { unsafe { (windows_core::Interface::vtable(self).IsPaused)(windows_core::Interface::as_raw(self)) } } + pub unsafe fn GetDefaultPlaybackRate(&self) -> f64 { + unsafe { (windows_core::Interface::vtable(self).GetDefaultPlaybackRate)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn SetDefaultPlaybackRate(&self, rate: f64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetDefaultPlaybackRate)(windows_core::Interface::as_raw(self), rate).ok() } + } + pub unsafe fn GetPlaybackRate(&self) -> f64 { + unsafe { (windows_core::Interface::vtable(self).GetPlaybackRate)(windows_core::Interface::as_raw(self)) } + } pub unsafe fn SetPlaybackRate(&self, rate: f64) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetPlaybackRate)(windows_core::Interface::as_raw(self), rate).ok() } } + pub unsafe fn GetPlayed(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetPlayed)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetSeekable(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetSeekable)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn IsEnded(&self) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).IsEnded)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetAutoPlay(&self) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).GetAutoPlay)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn SetAutoPlay(&self, autoplay: bool) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetAutoPlay)(windows_core::Interface::as_raw(self), autoplay.into()).ok() } + } + pub unsafe fn GetLoop(&self) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).GetLoop)(windows_core::Interface::as_raw(self)) } + } pub unsafe fn SetLoop(&self, r#loop: bool) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetLoop)(windows_core::Interface::as_raw(self), r#loop.into()).ok() } } @@ -36961,15 +125378,30 @@ impl IMFMediaEngine { pub unsafe fn Pause(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Pause)(windows_core::Interface::as_raw(self)).ok() } } + pub unsafe fn GetMuted(&self) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).GetMuted)(windows_core::Interface::as_raw(self)) } + } pub unsafe fn SetMuted(&self, muted: bool) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetMuted)(windows_core::Interface::as_raw(self), muted.into()).ok() } } + pub unsafe fn GetVolume(&self) -> f64 { + unsafe { (windows_core::Interface::vtable(self).GetVolume)(windows_core::Interface::as_raw(self)) } + } pub unsafe fn SetVolume(&self, volume: f64) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetVolume)(windows_core::Interface::as_raw(self), volume).ok() } } + pub unsafe fn HasVideo(&self) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).HasVideo)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn HasAudio(&self) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).HasAudio)(windows_core::Interface::as_raw(self)) } + } pub unsafe fn GetNativeVideoSize(&self, cx: Option<*mut u32>, cy: Option<*mut u32>) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).GetNativeVideoSize)(windows_core::Interface::as_raw(self), cx.unwrap_or(core::mem::zeroed()) as _, cy.unwrap_or(core::mem::zeroed()) as _).ok() } } + pub unsafe fn GetVideoAspectRatio(&self, cx: Option<*mut u32>, cy: Option<*mut u32>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetVideoAspectRatio)(windows_core::Interface::as_raw(self), cx.unwrap_or(core::mem::zeroed()) as _, cy.unwrap_or(core::mem::zeroed()) as _).ok() } + } pub unsafe fn Shutdown(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Shutdown)(windows_core::Interface::as_raw(self)).ok() } } @@ -37036,7 +125468,7 @@ pub struct IMFMediaEngine_Vtbl { pub trait IMFMediaEngine_Impl: windows_core::IUnknownImpl { fn GetError(&self) -> windows_core::Result; fn SetErrorCode(&self, error: MF_MEDIA_ENGINE_ERR) -> windows_core::Result<()>; - fn SetSourceElements(&self, psrcelements: windows_core::Ref) -> windows_core::Result<()>; + fn SetSourceElements(&self, psrcelements: windows_core::Ref<'_, IMFMediaEngineSrcElements>) -> windows_core::Result<()>; fn SetSource(&self, purl: &windows_core::BSTR) -> windows_core::Result<()>; fn GetCurrentSource(&self) -> windows_core::Result; fn GetNetworkState(&self) -> u16; @@ -37074,7 +125506,7 @@ pub trait IMFMediaEngine_Impl: windows_core::IUnknownImpl { fn GetNativeVideoSize(&self, cx: *mut u32, cy: *mut u32) -> windows_core::Result<()>; fn GetVideoAspectRatio(&self, cx: *mut u32, cy: *mut u32) -> windows_core::Result<()>; fn Shutdown(&self) -> windows_core::Result<()>; - fn TransferVideoFrame(&self, pdstsurf: windows_core::Ref, psrc: *const MFVideoNormalizedRect, pdst: *const super::super::Foundation::RECT, pborderclr: *const MFARGB) -> windows_core::Result<()>; + fn TransferVideoFrame(&self, pdstsurf: windows_core::Ref<'_, windows_core::IUnknown>, psrc: *const MFVideoNormalizedRect, pdst: *const super::super::Foundation::RECT, pborderclr: *const MFARGB) -> windows_core::Result<()>; fn OnVideoStreamTick(&self) -> windows_core::Result; } impl IMFMediaEngine_Vtbl { @@ -37436,7 +125868,19 @@ impl IMFMediaEngineClassFactory { (windows_core::Interface::vtable(self).CreateInstance)(windows_core::Interface::as_raw(self), dwflags, pattr.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub unsafe fn CreateTimeRange(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateTimeRange)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub unsafe fn CreateError(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateError)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaEngineClassFactory_Vtbl { @@ -37446,7 +125890,7 @@ pub struct IMFMediaEngineClassFactory_Vtbl { pub CreateError: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, } pub trait IMFMediaEngineClassFactory_Impl: windows_core::IUnknownImpl { - fn CreateInstance(&self, dwflags: u32, pattr: windows_core::Ref) -> windows_core::Result; + fn CreateInstance(&self, dwflags: u32, pattr: windows_core::Ref<'_, IMFAttributes>) -> windows_core::Result; fn CreateTimeRange(&self) -> windows_core::Result; fn CreateError(&self) -> windows_core::Result; } @@ -37508,6 +125952,29 @@ impl core::ops::Deref for IMFMediaEngineClassFactoryEx { } } windows_core::imp::interface_hierarchy!(IMFMediaEngineClassFactoryEx, windows_core::IUnknown, IMFMediaEngineClassFactory); +impl IMFMediaEngineClassFactoryEx { + pub unsafe fn CreateMediaSourceExtension(&self, dwflags: u32, pattr: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateMediaSourceExtension)(windows_core::Interface::as_raw(self), dwflags, pattr.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn CreateMediaKeys(&self, keysystem: &windows_core::BSTR, cdmstorepath: &windows_core::BSTR) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateMediaKeys)(windows_core::Interface::as_raw(self), core::mem::transmute_copy(keysystem), core::mem::transmute_copy(cdmstorepath), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn IsTypeSupported(&self, r#type: &windows_core::BSTR, keysystem: &windows_core::BSTR) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).IsTypeSupported)(windows_core::Interface::as_raw(self), core::mem::transmute_copy(r#type), core::mem::transmute_copy(keysystem), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaEngineClassFactoryEx_Vtbl { @@ -37517,7 +125984,7 @@ pub struct IMFMediaEngineClassFactoryEx_Vtbl { pub IsTypeSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut core::ffi::c_void, *mut windows_core::BOOL) -> windows_core::HRESULT, } pub trait IMFMediaEngineClassFactoryEx_Impl: IMFMediaEngineClassFactory_Impl { - fn CreateMediaSourceExtension(&self, dwflags: u32, pattr: windows_core::Ref) -> windows_core::Result; + fn CreateMediaSourceExtension(&self, dwflags: u32, pattr: windows_core::Ref<'_, IMFAttributes>) -> windows_core::Result; fn CreateMediaKeys(&self, keysystem: &windows_core::BSTR, cdmstorepath: &windows_core::BSTR) -> windows_core::Result; fn IsTypeSupported(&self, r#type: &windows_core::BSTR, keysystem: &windows_core::BSTR) -> windows_core::Result; } @@ -37580,6 +126047,40 @@ impl core::ops::Deref for IMFMediaEngineEx { } windows_core::imp::interface_hierarchy!(IMFMediaEngineEx, windows_core::IUnknown, IMFMediaEngine); impl IMFMediaEngineEx { + pub unsafe fn SetSourceFromByteStream(&self, pbytestream: P0, purl: &windows_core::BSTR) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetSourceFromByteStream)(windows_core::Interface::as_raw(self), pbytestream.param().abi(), core::mem::transmute_copy(purl)).ok() } + } + #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] + pub unsafe fn GetStatistics(&self, statisticid: MF_MEDIA_ENGINE_STATISTIC) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStatistics)(windows_core::Interface::as_raw(self), statisticid, &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub unsafe fn UpdateVideoStream(&self, psrc: Option<*const MFVideoNormalizedRect>, pdst: Option<*const super::super::Foundation::RECT>, pborderclr: Option<*const MFARGB>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).UpdateVideoStream)(windows_core::Interface::as_raw(self), psrc.unwrap_or(core::mem::zeroed()) as _, pdst.unwrap_or(core::mem::zeroed()) as _, pborderclr.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn GetBalance(&self) -> f64 { + unsafe { (windows_core::Interface::vtable(self).GetBalance)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn SetBalance(&self, balance: f64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetBalance)(windows_core::Interface::as_raw(self), balance).ok() } + } + pub unsafe fn IsPlaybackRateSupported(&self, rate: f64) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).IsPlaybackRateSupported)(windows_core::Interface::as_raw(self), rate) } + } + pub unsafe fn FrameStep(&self, forward: bool) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).FrameStep)(windows_core::Interface::as_raw(self), forward.into()).ok() } + } + pub unsafe fn GetResourceCharacteristics(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetResourceCharacteristics)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub unsafe fn GetPresentationAttribute(&self, guidmfattribute: *const windows_core::GUID) -> windows_core::Result { unsafe { @@ -37587,10 +126088,131 @@ impl IMFMediaEngineEx { (windows_core::Interface::vtable(self).GetPresentationAttribute)(windows_core::Interface::as_raw(self), guidmfattribute, &mut result__).map(|| core::mem::transmute(result__)) } } + pub unsafe fn GetNumberOfStreams(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetNumberOfStreams)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] + pub unsafe fn GetStreamAttribute(&self, dwstreamindex: u32, guidmfattribute: *const windows_core::GUID) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamAttribute)(windows_core::Interface::as_raw(self), dwstreamindex, guidmfattribute, &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub unsafe fn GetStreamSelection(&self, dwstreamindex: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamSelection)(windows_core::Interface::as_raw(self), dwstreamindex, &mut result__).map(|| result__) + } + } pub unsafe fn SetStreamSelection(&self, dwstreamindex: u32, enabled: bool) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetStreamSelection)(windows_core::Interface::as_raw(self), dwstreamindex, enabled.into()).ok() } } + pub unsafe fn ApplyStreamSelections(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).ApplyStreamSelections)(windows_core::Interface::as_raw(self)).ok() } } + pub unsafe fn IsProtected(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).IsProtected)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn InsertVideoEffect(&self, peffect: P0, foptional: bool) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).InsertVideoEffect)(windows_core::Interface::as_raw(self), peffect.param().abi(), foptional.into()).ok() } + } + pub unsafe fn InsertAudioEffect(&self, peffect: P0, foptional: bool) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).InsertAudioEffect)(windows_core::Interface::as_raw(self), peffect.param().abi(), foptional.into()).ok() } + } + pub unsafe fn RemoveAllEffects(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveAllEffects)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn SetTimelineMarkerTimer(&self, timetofire: f64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetTimelineMarkerTimer)(windows_core::Interface::as_raw(self), timetofire).ok() } + } + pub unsafe fn GetTimelineMarkerTimer(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTimelineMarkerTimer)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn CancelTimelineMarkerTimer(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).CancelTimelineMarkerTimer)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn IsStereo3D(&self) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).IsStereo3D)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetStereo3DFramePackingMode(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStereo3DFramePackingMode)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn SetStereo3DFramePackingMode(&self, packmode: MF_MEDIA_ENGINE_S3D_PACKING_MODE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetStereo3DFramePackingMode)(windows_core::Interface::as_raw(self), packmode).ok() } + } + pub unsafe fn GetStereo3DRenderMode(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStereo3DRenderMode)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn SetStereo3DRenderMode(&self, outputtype: MF3DVideoOutputType) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetStereo3DRenderMode)(windows_core::Interface::as_raw(self), outputtype).ok() } + } + pub unsafe fn EnableWindowlessSwapchainMode(&self, fenable: bool) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).EnableWindowlessSwapchainMode)(windows_core::Interface::as_raw(self), fenable.into()).ok() } + } + pub unsafe fn GetVideoSwapchainHandle(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetVideoSwapchainHandle)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn EnableHorizontalMirrorMode(&self, fenable: bool) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).EnableHorizontalMirrorMode)(windows_core::Interface::as_raw(self), fenable.into()).ok() } + } + pub unsafe fn GetAudioStreamCategory(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetAudioStreamCategory)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn SetAudioStreamCategory(&self, category: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetAudioStreamCategory)(windows_core::Interface::as_raw(self), category).ok() } + } + pub unsafe fn GetAudioEndpointRole(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetAudioEndpointRole)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn SetAudioEndpointRole(&self, role: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetAudioEndpointRole)(windows_core::Interface::as_raw(self), role).ok() } + } + pub unsafe fn GetRealTimeMode(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetRealTimeMode)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn SetRealTimeMode(&self, fenable: bool) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetRealTimeMode)(windows_core::Interface::as_raw(self), fenable.into()).ok() } + } + pub unsafe fn SetCurrentTimeEx(&self, seektime: f64, seekmode: MF_MEDIA_ENGINE_SEEK_MODE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetCurrentTimeEx)(windows_core::Interface::as_raw(self), seektime, seekmode).ok() } + } + pub unsafe fn EnableTimeUpdateTimer(&self, fenabletimer: bool) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).EnableTimeUpdateTimer)(windows_core::Interface::as_raw(self), fenabletimer.into()).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaEngineEx_Vtbl { @@ -37644,7 +126266,7 @@ pub struct IMFMediaEngineEx_Vtbl { } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub trait IMFMediaEngineEx_Impl: IMFMediaEngine_Impl { - fn SetSourceFromByteStream(&self, pbytestream: windows_core::Ref, purl: &windows_core::BSTR) -> windows_core::Result<()>; + fn SetSourceFromByteStream(&self, pbytestream: windows_core::Ref<'_, IMFByteStream>, purl: &windows_core::BSTR) -> windows_core::Result<()>; fn GetStatistics(&self, statisticid: MF_MEDIA_ENGINE_STATISTIC) -> windows_core::Result; fn UpdateVideoStream(&self, psrc: *const MFVideoNormalizedRect, pdst: *const super::super::Foundation::RECT, pborderclr: *const MFARGB) -> windows_core::Result<()>; fn GetBalance(&self) -> f64; @@ -37659,8 +126281,8 @@ pub trait IMFMediaEngineEx_Impl: IMFMediaEngine_Impl { fn SetStreamSelection(&self, dwstreamindex: u32, enabled: windows_core::BOOL) -> windows_core::Result<()>; fn ApplyStreamSelections(&self) -> windows_core::Result<()>; fn IsProtected(&self) -> windows_core::Result; - fn InsertVideoEffect(&self, peffect: windows_core::Ref, foptional: windows_core::BOOL) -> windows_core::Result<()>; - fn InsertAudioEffect(&self, peffect: windows_core::Ref, foptional: windows_core::BOOL) -> windows_core::Result<()>; + fn InsertVideoEffect(&self, peffect: windows_core::Ref<'_, windows_core::IUnknown>, foptional: windows_core::BOOL) -> windows_core::Result<()>; + fn InsertAudioEffect(&self, peffect: windows_core::Ref<'_, windows_core::IUnknown>, foptional: windows_core::BOOL) -> windows_core::Result<()>; fn RemoveAllEffects(&self) -> windows_core::Result<()>; fn SetTimelineMarkerTimer(&self, timetofire: f64) -> windows_core::Result<()>; fn GetTimelineMarkerTimer(&self) -> windows_core::Result; @@ -38040,6 +126662,11 @@ impl IMFMediaEngineEx_Vtbl { impl windows_core::RuntimeName for IMFMediaEngineEx {} windows_core::imp::define_interface!(IMFMediaEngineNotify, IMFMediaEngineNotify_Vtbl, 0xfee7c112_e776_42b5_9bbf_0048524e2bd5); windows_core::imp::interface_hierarchy!(IMFMediaEngineNotify, windows_core::IUnknown); +impl IMFMediaEngineNotify { + pub unsafe fn EventNotify(&self, event: u32, param1: usize, param2: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).EventNotify)(windows_core::Interface::as_raw(self), event, param1, param2).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaEngineNotify_Vtbl { @@ -38066,6 +126693,35 @@ impl IMFMediaEngineNotify_Vtbl { impl windows_core::RuntimeName for IMFMediaEngineNotify {} windows_core::imp::define_interface!(IMFMediaEngineSrcElements, IMFMediaEngineSrcElements_Vtbl, 0x7a5e5354_b114_4c72_b991_3131d75032ea); windows_core::imp::interface_hierarchy!(IMFMediaEngineSrcElements, windows_core::IUnknown); +impl IMFMediaEngineSrcElements { + pub unsafe fn GetLength(&self) -> u32 { + unsafe { (windows_core::Interface::vtable(self).GetLength)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetURL(&self, index: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetURL)(windows_core::Interface::as_raw(self), index, &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub unsafe fn GetType(&self, index: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetType)(windows_core::Interface::as_raw(self), index, &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub unsafe fn GetMedia(&self, index: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMedia)(windows_core::Interface::as_raw(self), index, &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub unsafe fn AddElement(&self, purl: &windows_core::BSTR, ptype: &windows_core::BSTR, pmedia: &windows_core::BSTR) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).AddElement)(windows_core::Interface::as_raw(self), core::mem::transmute_copy(purl), core::mem::transmute_copy(ptype), core::mem::transmute_copy(pmedia)).ok() } + } + pub unsafe fn RemoveAllElements(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveAllElements)(windows_core::Interface::as_raw(self)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaEngineSrcElements_Vtbl { @@ -38164,6 +126820,17 @@ impl core::ops::Deref for IMFMediaEngineSrcElementsEx { } } windows_core::imp::interface_hierarchy!(IMFMediaEngineSrcElementsEx, windows_core::IUnknown, IMFMediaEngineSrcElements); +impl IMFMediaEngineSrcElementsEx { + pub unsafe fn AddElementEx(&self, purl: &windows_core::BSTR, ptype: &windows_core::BSTR, pmedia: &windows_core::BSTR, keysystem: &windows_core::BSTR) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).AddElementEx)(windows_core::Interface::as_raw(self), core::mem::transmute_copy(purl), core::mem::transmute_copy(ptype), core::mem::transmute_copy(pmedia), core::mem::transmute_copy(keysystem)).ok() } + } + pub unsafe fn GetKeySystem(&self, index: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetKeySystem)(windows_core::Interface::as_raw(self), index, &mut result__).map(|| core::mem::transmute(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaEngineSrcElementsEx_Vtbl { @@ -38212,7 +126879,16 @@ impl IMFMediaError { pub unsafe fn GetErrorCode(&self) -> u16 { unsafe { (windows_core::Interface::vtable(self).GetErrorCode)(windows_core::Interface::as_raw(self)) } } + pub unsafe fn GetExtendedErrorCode(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetExtendedErrorCode)(windows_core::Interface::as_raw(self)).ok() } } + pub unsafe fn SetErrorCode(&self, error: MF_MEDIA_ENGINE_ERR) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetErrorCode)(windows_core::Interface::as_raw(self), error).ok() } + } + pub unsafe fn SetExtendedErrorCode(&self, error: windows_core::HRESULT) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetExtendedErrorCode)(windows_core::Interface::as_raw(self), error).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaError_Vtbl { @@ -38276,6 +126952,24 @@ impl core::ops::Deref for IMFMediaEvent { } windows_core::imp::interface_hierarchy!(IMFMediaEvent, windows_core::IUnknown, IMFAttributes); impl IMFMediaEvent { + pub unsafe fn GetType(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetType)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetExtendedType(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetExtendedType)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetStatus(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStatus)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub unsafe fn GetValue(&self) -> windows_core::Result { unsafe { @@ -38370,6 +127064,34 @@ impl IMFMediaEvent_Vtbl { impl windows_core::RuntimeName for IMFMediaEvent {} windows_core::imp::define_interface!(IMFMediaEventGenerator, IMFMediaEventGenerator_Vtbl, 0x2cd0bd52_bcd5_4b89_b62c_eadc0c031e7d); windows_core::imp::interface_hierarchy!(IMFMediaEventGenerator, windows_core::IUnknown); +impl IMFMediaEventGenerator { + pub unsafe fn GetEvent(&self, dwflags: MEDIA_EVENT_GENERATOR_GET_EVENT_FLAGS) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetEvent)(windows_core::Interface::as_raw(self), dwflags, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn BeginGetEvent(&self, pcallback: P0, punkstate: P1) -> windows_core::Result<()> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).BeginGetEvent)(windows_core::Interface::as_raw(self), pcallback.param().abi(), punkstate.param().abi()).ok() } + } + pub unsafe fn EndGetEvent(&self, presult: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).EndGetEvent)(windows_core::Interface::as_raw(self), presult.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] + pub unsafe fn QueueEvent(&self, met: u32, guidextendedtype: *const windows_core::GUID, hrstatus: windows_core::HRESULT, pvvalue: *const super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).QueueEvent)(windows_core::Interface::as_raw(self), met, guidextendedtype, hrstatus, core::mem::transmute(pvvalue)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaEventGenerator_Vtbl { @@ -38385,8 +127107,8 @@ pub struct IMFMediaEventGenerator_Vtbl { #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub trait IMFMediaEventGenerator_Impl: windows_core::IUnknownImpl { fn GetEvent(&self, dwflags: MEDIA_EVENT_GENERATOR_GET_EVENT_FLAGS) -> windows_core::Result; - fn BeginGetEvent(&self, pcallback: windows_core::Ref, punkstate: windows_core::Ref) -> windows_core::Result<()>; - fn EndGetEvent(&self, presult: windows_core::Ref) -> windows_core::Result; + fn BeginGetEvent(&self, pcallback: windows_core::Ref<'_, IMFAsyncCallback>, punkstate: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; + fn EndGetEvent(&self, presult: windows_core::Ref<'_, IMFAsyncResult>) -> windows_core::Result; fn QueueEvent(&self, met: u32, guidextendedtype: *const windows_core::GUID, hrstatus: windows_core::HRESULT, pvvalue: *const super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result<()>; } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] @@ -38448,6 +127170,21 @@ impl IMFMediaKeySession { pub unsafe fn GetError(&self, code: *mut u16, systemcode: *mut u32) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).GetError)(windows_core::Interface::as_raw(self), code as _, systemcode as _).ok() } } + pub unsafe fn KeySystem(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).KeySystem)(windows_core::Interface::as_raw(self), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub unsafe fn SessionId(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).SessionId)(windows_core::Interface::as_raw(self), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub unsafe fn Update(&self, key: &[u8]) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Update)(windows_core::Interface::as_raw(self), core::mem::transmute(key.as_ptr()), key.len().try_into().unwrap()).ok() } + } pub unsafe fn Close(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Close)(windows_core::Interface::as_raw(self)).ok() } } @@ -38536,6 +127273,27 @@ impl core::ops::Deref for IMFMediaKeySession2 { } windows_core::imp::interface_hierarchy!(IMFMediaKeySession2, windows_core::IUnknown, IMFMediaKeySession); impl IMFMediaKeySession2 { + pub unsafe fn get_KeyStatuses(&self, pkeystatusesarray: *mut *mut MFMediaKeyStatus, pusize: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).get_KeyStatuses)(windows_core::Interface::as_raw(self), pkeystatusesarray as _, pusize as _).ok() } + } + pub unsafe fn Load(&self, bstrsessionid: &windows_core::BSTR) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Load)(windows_core::Interface::as_raw(self), core::mem::transmute_copy(bstrsessionid), &mut result__).map(|| result__) + } + } + pub unsafe fn GenerateRequest(&self, initdatatype: &windows_core::BSTR, pbinitdata: &[u8]) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GenerateRequest)(windows_core::Interface::as_raw(self), core::mem::transmute_copy(initdatatype), core::mem::transmute(pbinitdata.as_ptr()), pbinitdata.len().try_into().unwrap()).ok() } + } + pub unsafe fn Expiration(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Expiration)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn Remove(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Remove)(windows_core::Interface::as_raw(self)).ok() } + } pub unsafe fn Shutdown(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Shutdown)(windows_core::Interface::as_raw(self)).ok() } } @@ -38626,6 +127384,17 @@ impl IMFMediaKeySession2_Vtbl { impl windows_core::RuntimeName for IMFMediaKeySession2 {} windows_core::imp::define_interface!(IMFMediaKeySessionNotify, IMFMediaKeySessionNotify_Vtbl, 0x6a0083f9_8947_4c1d_9ce0_cdee22b23135); windows_core::imp::interface_hierarchy!(IMFMediaKeySessionNotify, windows_core::IUnknown); +impl IMFMediaKeySessionNotify { + pub unsafe fn KeyMessage(&self, destinationurl: &windows_core::BSTR, message: &[u8]) { + unsafe { (windows_core::Interface::vtable(self).KeyMessage)(windows_core::Interface::as_raw(self), core::mem::transmute_copy(destinationurl), core::mem::transmute(message.as_ptr()), message.len().try_into().unwrap()) } + } + pub unsafe fn KeyAdded(&self) { + unsafe { (windows_core::Interface::vtable(self).KeyAdded)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn KeyError(&self, code: u16, systemcode: u32) { + unsafe { (windows_core::Interface::vtable(self).KeyError)(windows_core::Interface::as_raw(self), code, systemcode) } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaKeySessionNotify_Vtbl { @@ -38679,6 +127448,14 @@ impl core::ops::Deref for IMFMediaKeySessionNotify2 { } } windows_core::imp::interface_hierarchy!(IMFMediaKeySessionNotify2, windows_core::IUnknown, IMFMediaKeySessionNotify); +impl IMFMediaKeySessionNotify2 { + pub unsafe fn KeyMessage2(&self, emessagetype: MF_MEDIAKEYSESSION_MESSAGETYPE, destinationurl: &windows_core::BSTR, pbmessage: &[u8]) { + unsafe { (windows_core::Interface::vtable(self).KeyMessage2)(windows_core::Interface::as_raw(self), emessagetype, core::mem::transmute_copy(destinationurl), core::mem::transmute(pbmessage.as_ptr()), pbmessage.len().try_into().unwrap()) } + } + pub unsafe fn KeyStatusChange(&self) { + unsafe { (windows_core::Interface::vtable(self).KeyStatusChange)(windows_core::Interface::as_raw(self)) } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaKeySessionNotify2_Vtbl { @@ -38718,10 +127495,31 @@ impl windows_core::RuntimeName for IMFMediaKeySessionNotify2 {} windows_core::imp::define_interface!(IMFMediaKeys, IMFMediaKeys_Vtbl, 0x5cb31c05_61ff_418f_afda_caaf41421a38); windows_core::imp::interface_hierarchy!(IMFMediaKeys, windows_core::IUnknown); impl IMFMediaKeys { + pub unsafe fn CreateSession(&self, mimetype: &windows_core::BSTR, initdata: Option<&[u8]>, customdata: Option<&[u8]>, notify: P5) -> windows_core::Result + where + P5: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateSession)(windows_core::Interface::as_raw(self), core::mem::transmute_copy(mimetype), core::mem::transmute(initdata.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), initdata.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(customdata.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), customdata.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), notify.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn KeySystem(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).KeySystem)(windows_core::Interface::as_raw(self), &mut result__).map(|| core::mem::transmute(result__)) + } + } pub unsafe fn Shutdown(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Shutdown)(windows_core::Interface::as_raw(self)).ok() } } + pub unsafe fn GetSuspendNotify(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetSuspendNotify)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaKeys_Vtbl { @@ -38732,7 +127530,7 @@ pub struct IMFMediaKeys_Vtbl { pub GetSuspendNotify: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, } pub trait IMFMediaKeys_Impl: windows_core::IUnknownImpl { - fn CreateSession(&self, mimetype: &windows_core::BSTR, initdata: *const u8, cb: u32, customdata: *const u8, cbcustomdata: u32, notify: windows_core::Ref) -> windows_core::Result; + fn CreateSession(&self, mimetype: &windows_core::BSTR, initdata: *const u8, cb: u32, customdata: *const u8, cbcustomdata: u32, notify: windows_core::Ref<'_, IMFMediaKeySessionNotify>) -> windows_core::Result; fn KeySystem(&self) -> windows_core::Result; fn Shutdown(&self) -> windows_core::Result<()>; fn GetSuspendNotify(&self) -> windows_core::Result; @@ -38802,6 +127600,26 @@ impl core::ops::Deref for IMFMediaKeys2 { } } windows_core::imp::interface_hierarchy!(IMFMediaKeys2, windows_core::IUnknown, IMFMediaKeys); +impl IMFMediaKeys2 { + pub unsafe fn CreateSession2(&self, esessiontype: MF_MEDIAKEYSESSION_TYPE, pmfmediakeysessionnotify2: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateSession2)(windows_core::Interface::as_raw(self), esessiontype, pmfmediakeysessionnotify2.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn SetServerCertificate(&self, pbservercertificate: Option<&[u8]>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetServerCertificate)(windows_core::Interface::as_raw(self), core::mem::transmute(pbservercertificate.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), pbservercertificate.as_deref().map_or(0, |slice| slice.len().try_into().unwrap())).ok() } + } + pub unsafe fn GetDOMException(&self, systemcode: windows_core::HRESULT) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDOMException)(windows_core::Interface::as_raw(self), systemcode, &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaKeys2_Vtbl { @@ -38811,7 +127629,7 @@ pub struct IMFMediaKeys2_Vtbl { pub GetDOMException: unsafe extern "system" fn(*mut core::ffi::c_void, windows_core::HRESULT, *mut windows_core::HRESULT) -> windows_core::HRESULT, } pub trait IMFMediaKeys2_Impl: IMFMediaKeys_Impl { - fn CreateSession2(&self, esessiontype: MF_MEDIAKEYSESSION_TYPE, pmfmediakeysessionnotify2: windows_core::Ref) -> windows_core::Result; + fn CreateSession2(&self, esessiontype: MF_MEDIAKEYSESSION_TYPE, pmfmediakeysessionnotify2: windows_core::Ref<'_, IMFMediaKeySessionNotify2>) -> windows_core::Result; fn SetServerCertificate(&self, pbservercertificate: *const u8, cb: u32) -> windows_core::Result<()>; fn GetDOMException(&self, systemcode: windows_core::HRESULT) -> windows_core::Result; } @@ -38868,6 +127686,15 @@ impl core::ops::Deref for IMFMediaSession { } windows_core::imp::interface_hierarchy!(IMFMediaSession, windows_core::IUnknown, IMFMediaEventGenerator); impl IMFMediaSession { + pub unsafe fn SetTopology(&self, dwsettopologyflags: u32, ptopology: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetTopology)(windows_core::Interface::as_raw(self), dwsettopologyflags, ptopology.param().abi()).ok() } + } + pub unsafe fn ClearTopologies(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).ClearTopologies)(windows_core::Interface::as_raw(self)).ok() } + } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub unsafe fn Start(&self, pguidtimeformat: *const windows_core::GUID, pvarstartposition: *const super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Start)(windows_core::Interface::as_raw(self), pguidtimeformat, core::mem::transmute(pvarstartposition)).ok() } @@ -38884,7 +127711,25 @@ impl IMFMediaSession { pub unsafe fn Shutdown(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Shutdown)(windows_core::Interface::as_raw(self)).ok() } } + pub unsafe fn GetClock(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetClock)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub unsafe fn GetSessionCapabilities(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetSessionCapabilities)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetFullTopology(&self, dwgetfulltopologyflags: u32, topoid: u64) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetFullTopology)(windows_core::Interface::as_raw(self), dwgetfulltopologyflags, topoid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaSession_Vtbl { @@ -38905,7 +127750,7 @@ pub struct IMFMediaSession_Vtbl { } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub trait IMFMediaSession_Impl: IMFMediaEventGenerator_Impl { - fn SetTopology(&self, dwsettopologyflags: u32, ptopology: windows_core::Ref) -> windows_core::Result<()>; + fn SetTopology(&self, dwsettopologyflags: u32, ptopology: windows_core::Ref<'_, IMFTopology>) -> windows_core::Result<()>; fn ClearTopologies(&self) -> windows_core::Result<()>; fn Start(&self, pguidtimeformat: *const windows_core::GUID, pvarstartposition: *const super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result<()>; fn Pause(&self) -> windows_core::Result<()>; @@ -39025,6 +127870,11 @@ impl core::ops::Deref for IMFMediaSharingEngine { } } windows_core::imp::interface_hierarchy!(IMFMediaSharingEngine, windows_core::IUnknown, IMFMediaEngine); +impl IMFMediaSharingEngine { + pub unsafe fn GetDevice(&self, pdevice: *mut DEVICE_INFO) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetDevice)(windows_core::Interface::as_raw(self), core::mem::transmute(pdevice)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaSharingEngine_Vtbl { @@ -39052,6 +127902,54 @@ impl windows_core::RuntimeName for IMFMediaSharingEngine {} windows_core::imp::define_interface!(IMFMediaSink, IMFMediaSink_Vtbl, 0x6ef2a660_47c0_4666_b13d_cbb717f2fa2c); windows_core::imp::interface_hierarchy!(IMFMediaSink, windows_core::IUnknown); impl IMFMediaSink { + pub unsafe fn GetCharacteristics(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetCharacteristics)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn AddStreamSink(&self, dwstreamsinkidentifier: u32, pmediatype: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).AddStreamSink)(windows_core::Interface::as_raw(self), dwstreamsinkidentifier, pmediatype.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn RemoveStreamSink(&self, dwstreamsinkidentifier: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveStreamSink)(windows_core::Interface::as_raw(self), dwstreamsinkidentifier).ok() } + } + pub unsafe fn GetStreamSinkCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamSinkCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetStreamSinkByIndex(&self, dwindex: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamSinkByIndex)(windows_core::Interface::as_raw(self), dwindex, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetStreamSinkById(&self, dwstreamsinkidentifier: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamSinkById)(windows_core::Interface::as_raw(self), dwstreamsinkidentifier, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn SetPresentationClock(&self, ppresentationclock: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetPresentationClock)(windows_core::Interface::as_raw(self), ppresentationclock.param().abi()).ok() } + } + pub unsafe fn GetPresentationClock(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetPresentationClock)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub unsafe fn Shutdown(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Shutdown)(windows_core::Interface::as_raw(self)).ok() } } @@ -39072,12 +127970,12 @@ pub struct IMFMediaSink_Vtbl { } pub trait IMFMediaSink_Impl: windows_core::IUnknownImpl { fn GetCharacteristics(&self) -> windows_core::Result; - fn AddStreamSink(&self, dwstreamsinkidentifier: u32, pmediatype: windows_core::Ref) -> windows_core::Result; + fn AddStreamSink(&self, dwstreamsinkidentifier: u32, pmediatype: windows_core::Ref<'_, IMFMediaType>) -> windows_core::Result; fn RemoveStreamSink(&self, dwstreamsinkidentifier: u32) -> windows_core::Result<()>; fn GetStreamSinkCount(&self) -> windows_core::Result; fn GetStreamSinkByIndex(&self, dwindex: u32) -> windows_core::Result; fn GetStreamSinkById(&self, dwstreamsinkidentifier: u32) -> windows_core::Result; - fn SetPresentationClock(&self, ppresentationclock: windows_core::Ref) -> windows_core::Result<()>; + fn SetPresentationClock(&self, ppresentationclock: windows_core::Ref<'_, IMFPresentationClock>) -> windows_core::Result<()>; fn GetPresentationClock(&self) -> windows_core::Result; fn Shutdown(&self) -> windows_core::Result<()>; } @@ -39200,6 +128098,18 @@ impl core::ops::Deref for IMFMediaSource { } windows_core::imp::interface_hierarchy!(IMFMediaSource, windows_core::IUnknown, IMFMediaEventGenerator); impl IMFMediaSource { + pub unsafe fn GetCharacteristics(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetCharacteristics)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn CreatePresentationDescriptor(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreatePresentationDescriptor)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub unsafe fn Start(&self, ppresentationdescriptor: P0, pguidtimeformat: *const windows_core::GUID, pvarstartposition: *const super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result<()> where @@ -39235,7 +128145,7 @@ pub struct IMFMediaSource_Vtbl { pub trait IMFMediaSource_Impl: IMFMediaEventGenerator_Impl { fn GetCharacteristics(&self) -> windows_core::Result; fn CreatePresentationDescriptor(&self) -> windows_core::Result; - fn Start(&self, ppresentationdescriptor: windows_core::Ref, pguidtimeformat: *const windows_core::GUID, pvarstartposition: *const super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result<()>; + fn Start(&self, ppresentationdescriptor: windows_core::Ref<'_, IMFPresentationDescriptor>, pguidtimeformat: *const windows_core::GUID, pvarstartposition: *const super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result<()>; fn Stop(&self) -> windows_core::Result<()>; fn Pause(&self) -> windows_core::Result<()>; fn Shutdown(&self) -> windows_core::Result<()>; @@ -39315,6 +128225,14 @@ impl core::ops::Deref for IMFMediaSource2 { } } windows_core::imp::interface_hierarchy!(IMFMediaSource2, windows_core::IUnknown, IMFMediaEventGenerator, IMFMediaSource, IMFMediaSourceEx); +impl IMFMediaSource2 { + pub unsafe fn SetMediaType(&self, dwstreamid: u32, pmediatype: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetMediaType)(windows_core::Interface::as_raw(self), dwstreamid, pmediatype.param().abi()).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaSource2_Vtbl { @@ -39323,7 +128241,7 @@ pub struct IMFMediaSource2_Vtbl { } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub trait IMFMediaSource2_Impl: IMFMediaSourceEx_Impl { - fn SetMediaType(&self, dwstreamid: u32, pmediatype: windows_core::Ref) -> windows_core::Result<()>; + fn SetMediaType(&self, dwstreamid: u32, pmediatype: windows_core::Ref<'_, IMFMediaType>) -> windows_core::Result<()>; } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] impl IMFMediaSource2_Vtbl { @@ -39350,6 +128268,26 @@ impl core::ops::Deref for IMFMediaSourceEx { } } windows_core::imp::interface_hierarchy!(IMFMediaSourceEx, windows_core::IUnknown, IMFMediaEventGenerator, IMFMediaSource); +impl IMFMediaSourceEx { + pub unsafe fn GetSourceAttributes(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetSourceAttributes)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetStreamAttributes(&self, dwstreamidentifier: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamAttributes)(windows_core::Interface::as_raw(self), dwstreamidentifier, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn SetD3DManager(&self, pmanager: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetD3DManager)(windows_core::Interface::as_raw(self), pmanager.param().abi()).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaSourceEx_Vtbl { @@ -39362,7 +128300,7 @@ pub struct IMFMediaSourceEx_Vtbl { pub trait IMFMediaSourceEx_Impl: IMFMediaSource_Impl { fn GetSourceAttributes(&self) -> windows_core::Result; fn GetStreamAttributes(&self, dwstreamidentifier: u32) -> windows_core::Result; - fn SetD3DManager(&self, pmanager: windows_core::Ref) -> windows_core::Result<()>; + fn SetD3DManager(&self, pmanager: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] impl IMFMediaSourceEx_Vtbl { @@ -39413,10 +128351,46 @@ impl windows_core::RuntimeName for IMFMediaSourceEx {} windows_core::imp::define_interface!(IMFMediaSourceExtension, IMFMediaSourceExtension_Vtbl, 0xe467b94e_a713_4562_a802_816a42e9008a); windows_core::imp::interface_hierarchy!(IMFMediaSourceExtension, windows_core::IUnknown); impl IMFMediaSourceExtension { + pub unsafe fn GetSourceBuffers(&self) -> Option { + unsafe { (windows_core::Interface::vtable(self).GetSourceBuffers)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetActiveSourceBuffers(&self) -> Option { + unsafe { (windows_core::Interface::vtable(self).GetActiveSourceBuffers)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetReadyState(&self) -> MF_MSE_READY { + unsafe { (windows_core::Interface::vtable(self).GetReadyState)(windows_core::Interface::as_raw(self)) } + } pub unsafe fn GetDuration(&self) -> f64 { unsafe { (windows_core::Interface::vtable(self).GetDuration)(windows_core::Interface::as_raw(self)) } } + pub unsafe fn SetDuration(&self, duration: f64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetDuration)(windows_core::Interface::as_raw(self), duration).ok() } } + pub unsafe fn AddSourceBuffer(&self, r#type: &windows_core::BSTR, pnotify: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).AddSourceBuffer)(windows_core::Interface::as_raw(self), core::mem::transmute_copy(r#type), pnotify.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn RemoveSourceBuffer(&self, psourcebuffer: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).RemoveSourceBuffer)(windows_core::Interface::as_raw(self), psourcebuffer.param().abi()).ok() } + } + pub unsafe fn SetEndOfStream(&self, error: MF_MSE_ERROR) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetEndOfStream)(windows_core::Interface::as_raw(self), error).ok() } + } + pub unsafe fn IsTypeSupported(&self, r#type: &windows_core::BSTR) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).IsTypeSupported)(windows_core::Interface::as_raw(self), core::mem::transmute_copy(r#type)) } + } + pub unsafe fn GetSourceBuffer(&self, dwstreamindex: u32) -> Option { + unsafe { (windows_core::Interface::vtable(self).GetSourceBuffer)(windows_core::Interface::as_raw(self), dwstreamindex) } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaSourceExtension_Vtbl { @@ -39438,8 +128412,8 @@ pub trait IMFMediaSourceExtension_Impl: windows_core::IUnknownImpl { fn GetReadyState(&self) -> MF_MSE_READY; fn GetDuration(&self) -> f64; fn SetDuration(&self, duration: f64) -> windows_core::Result<()>; - fn AddSourceBuffer(&self, r#type: &windows_core::BSTR, pnotify: windows_core::Ref) -> windows_core::Result; - fn RemoveSourceBuffer(&self, psourcebuffer: windows_core::Ref) -> windows_core::Result<()>; + fn AddSourceBuffer(&self, r#type: &windows_core::BSTR, pnotify: windows_core::Ref<'_, IMFSourceBufferNotify>) -> windows_core::Result; + fn RemoveSourceBuffer(&self, psourcebuffer: windows_core::Ref<'_, IMFSourceBuffer>) -> windows_core::Result<()>; fn SetEndOfStream(&self, error: MF_MSE_ERROR) -> windows_core::Result<()>; fn IsTypeSupported(&self, r#type: &windows_core::BSTR) -> windows_core::BOOL; fn GetSourceBuffer(&self, dwstreamindex: u32) -> Option; @@ -39539,6 +128513,26 @@ impl core::ops::Deref for IMFMediaStream { } } windows_core::imp::interface_hierarchy!(IMFMediaStream, windows_core::IUnknown, IMFMediaEventGenerator); +impl IMFMediaStream { + pub unsafe fn GetMediaSource(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMediaSource)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetStreamDescriptor(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamDescriptor)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn RequestSample(&self, ptoken: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).RequestSample)(windows_core::Interface::as_raw(self), ptoken.param().abi()).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaStream_Vtbl { @@ -39551,7 +128545,7 @@ pub struct IMFMediaStream_Vtbl { pub trait IMFMediaStream_Impl: IMFMediaEventGenerator_Impl { fn GetMediaSource(&self) -> windows_core::Result; fn GetStreamDescriptor(&self) -> windows_core::Result; - fn RequestSample(&self, ptoken: windows_core::Ref) -> windows_core::Result<()>; + fn RequestSample(&self, ptoken: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] impl IMFMediaStream_Vtbl { @@ -39607,6 +128601,17 @@ impl core::ops::Deref for IMFMediaStream2 { } } windows_core::imp::interface_hierarchy!(IMFMediaStream2, windows_core::IUnknown, IMFMediaEventGenerator, IMFMediaStream); +impl IMFMediaStream2 { + pub unsafe fn SetStreamState(&self, value: MF_STREAM_STATE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetStreamState)(windows_core::Interface::as_raw(self), value).ok() } + } + pub unsafe fn GetStreamState(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamState)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaStream2_Vtbl { @@ -39654,6 +128659,32 @@ impl IMFMediaStream2_Vtbl { impl windows_core::RuntimeName for IMFMediaStream2 {} windows_core::imp::define_interface!(IMFMediaTimeRange, IMFMediaTimeRange_Vtbl, 0xdb71a2fc_078a_414e_9df9_8c2531b0aa6c); windows_core::imp::interface_hierarchy!(IMFMediaTimeRange, windows_core::IUnknown); +impl IMFMediaTimeRange { + pub unsafe fn GetLength(&self) -> u32 { + unsafe { (windows_core::Interface::vtable(self).GetLength)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetStart(&self, index: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStart)(windows_core::Interface::as_raw(self), index, &mut result__).map(|| result__) + } + } + pub unsafe fn GetEnd(&self, index: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetEnd)(windows_core::Interface::as_raw(self), index, &mut result__).map(|| result__) + } + } + pub unsafe fn ContainsTime(&self, time: f64) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).ContainsTime)(windows_core::Interface::as_raw(self), time) } + } + pub unsafe fn AddRange(&self, starttime: f64, endtime: f64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).AddRange)(windows_core::Interface::as_raw(self), starttime, endtime).ok() } + } + pub unsafe fn Clear(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Clear)(windows_core::Interface::as_raw(self)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaTimeRange_Vtbl { @@ -39746,6 +128777,35 @@ impl core::ops::Deref for IMFMediaType { } } windows_core::imp::interface_hierarchy!(IMFMediaType, windows_core::IUnknown, IMFAttributes); +impl IMFMediaType { + pub unsafe fn GetMajorType(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMajorType)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn IsCompressedFormat(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).IsCompressedFormat)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn IsEqual(&self, pimediatype: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).IsEqual)(windows_core::Interface::as_raw(self), pimediatype.param().abi(), &mut result__).map(|| result__) + } + } + pub unsafe fn GetRepresentation(&self, guidrepresentation: windows_core::GUID, ppvrepresentation: *mut *mut core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetRepresentation)(windows_core::Interface::as_raw(self), core::mem::transmute(guidrepresentation), ppvrepresentation as _).ok() } + } + pub unsafe fn FreeRepresentation(&self, guidrepresentation: windows_core::GUID, pvrepresentation: *const core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).FreeRepresentation)(windows_core::Interface::as_raw(self), core::mem::transmute(guidrepresentation), pvrepresentation).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaType_Vtbl { @@ -39760,7 +128820,7 @@ pub struct IMFMediaType_Vtbl { pub trait IMFMediaType_Impl: IMFAttributes_Impl { fn GetMajorType(&self) -> windows_core::Result; fn IsCompressedFormat(&self) -> windows_core::Result; - fn IsEqual(&self, pimediatype: windows_core::Ref) -> windows_core::Result; + fn IsEqual(&self, pimediatype: windows_core::Ref<'_, IMFMediaType>) -> windows_core::Result; fn GetRepresentation(&self, guidrepresentation: &windows_core::GUID, ppvrepresentation: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; fn FreeRepresentation(&self, guidrepresentation: &windows_core::GUID, pvrepresentation: *const core::ffi::c_void) -> windows_core::Result<()>; } @@ -39833,6 +128893,24 @@ impl windows_core::RuntimeName for IMFMediaType {} windows_core::imp::define_interface!(IMFMediaTypeHandler, IMFMediaTypeHandler_Vtbl, 0xe93dcf6c_4b07_4e1e_8123_aa16ed6eadf5); windows_core::imp::interface_hierarchy!(IMFMediaTypeHandler, windows_core::IUnknown); impl IMFMediaTypeHandler { + pub unsafe fn IsMediaTypeSupported(&self, pmediatype: P0, ppmediatype: Option<*mut Option>) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).IsMediaTypeSupported)(windows_core::Interface::as_raw(self), pmediatype.param().abi(), ppmediatype.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn GetMediaTypeCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMediaTypeCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetMediaTypeByIndex(&self, dwindex: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMediaTypeByIndex)(windows_core::Interface::as_raw(self), dwindex, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub unsafe fn SetCurrentMediaType(&self, pmediatype: P0) -> windows_core::Result<()> where P0: windows_core::Param, @@ -39845,7 +128923,13 @@ impl IMFMediaTypeHandler { (windows_core::Interface::vtable(self).GetCurrentMediaType)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub unsafe fn GetMajorType(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMajorType)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } } +} #[repr(C)] #[doc(hidden)] pub struct IMFMediaTypeHandler_Vtbl { @@ -39858,10 +128942,10 @@ pub struct IMFMediaTypeHandler_Vtbl { pub GetMajorType: unsafe extern "system" fn(*mut core::ffi::c_void, *mut windows_core::GUID) -> windows_core::HRESULT, } pub trait IMFMediaTypeHandler_Impl: windows_core::IUnknownImpl { - fn IsMediaTypeSupported(&self, pmediatype: windows_core::Ref, ppmediatype: windows_core::OutRef) -> windows_core::Result<()>; + fn IsMediaTypeSupported(&self, pmediatype: windows_core::Ref<'_, IMFMediaType>, ppmediatype: windows_core::OutRef<'_, IMFMediaType>) -> windows_core::Result<()>; fn GetMediaTypeCount(&self) -> windows_core::Result; fn GetMediaTypeByIndex(&self, dwindex: u32) -> windows_core::Result; - fn SetCurrentMediaType(&self, pmediatype: windows_core::Ref) -> windows_core::Result<()>; + fn SetCurrentMediaType(&self, pmediatype: windows_core::Ref<'_, IMFMediaType>) -> windows_core::Result<()>; fn GetCurrentMediaType(&self) -> windows_core::Result; fn GetMajorType(&self) -> windows_core::Result; } @@ -39950,6 +129034,26 @@ impl core::ops::Deref for IMFOutputPolicy { } } windows_core::imp::interface_hierarchy!(IMFOutputPolicy, windows_core::IUnknown, IMFAttributes); +impl IMFOutputPolicy { + pub unsafe fn GenerateRequiredSchemas(&self, dwattributes: u32, guidoutputsubtype: windows_core::GUID, rgguidprotectionschemassupported: *const windows_core::GUID, cprotectionschemassupported: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GenerateRequiredSchemas)(windows_core::Interface::as_raw(self), dwattributes, core::mem::transmute(guidoutputsubtype), rgguidprotectionschemassupported, cprotectionschemassupported, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetOriginatorID(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetOriginatorID)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetMinimumGRLVersion(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMinimumGRLVersion)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFOutputPolicy_Vtbl { @@ -40024,6 +129128,26 @@ impl core::ops::Deref for IMFOutputSchema { } } windows_core::imp::interface_hierarchy!(IMFOutputSchema, windows_core::IUnknown, IMFAttributes); +impl IMFOutputSchema { + pub unsafe fn GetSchemaType(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetSchemaType)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetConfigurationData(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetConfigurationData)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetOriginatorID(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetOriginatorID)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFOutputSchema_Vtbl { @@ -40099,6 +129223,36 @@ impl core::ops::Deref for IMFPresentationClock { } windows_core::imp::interface_hierarchy!(IMFPresentationClock, windows_core::IUnknown, IMFClock); impl IMFPresentationClock { + pub unsafe fn SetTimeSource(&self, ptimesource: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetTimeSource)(windows_core::Interface::as_raw(self), ptimesource.param().abi()).ok() } + } + pub unsafe fn GetTimeSource(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTimeSource)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetTime(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTime)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn AddClockStateSink(&self, pstatesink: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).AddClockStateSink)(windows_core::Interface::as_raw(self), pstatesink.param().abi()).ok() } + } + pub unsafe fn RemoveClockStateSink(&self, pstatesink: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).RemoveClockStateSink)(windows_core::Interface::as_raw(self), pstatesink.param().abi()).ok() } + } pub unsafe fn Start(&self, llclockstartoffset: i64) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Start)(windows_core::Interface::as_raw(self), llclockstartoffset).ok() } } @@ -40123,11 +129277,11 @@ pub struct IMFPresentationClock_Vtbl { pub Pause: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, } pub trait IMFPresentationClock_Impl: IMFClock_Impl { - fn SetTimeSource(&self, ptimesource: windows_core::Ref) -> windows_core::Result<()>; + fn SetTimeSource(&self, ptimesource: windows_core::Ref<'_, IMFPresentationTimeSource>) -> windows_core::Result<()>; fn GetTimeSource(&self) -> windows_core::Result; fn GetTime(&self) -> windows_core::Result; - fn AddClockStateSink(&self, pstatesink: windows_core::Ref) -> windows_core::Result<()>; - fn RemoveClockStateSink(&self, pstatesink: windows_core::Ref) -> windows_core::Result<()>; + fn AddClockStateSink(&self, pstatesink: windows_core::Ref<'_, IMFClockStateSink>) -> windows_core::Result<()>; + fn RemoveClockStateSink(&self, pstatesink: windows_core::Ref<'_, IMFClockStateSink>) -> windows_core::Result<()>; fn Start(&self, llclockstartoffset: i64) -> windows_core::Result<()>; fn Stop(&self) -> windows_core::Result<()>; fn Pause(&self) -> windows_core::Result<()>; @@ -40219,6 +129373,29 @@ impl core::ops::Deref for IMFPresentationDescriptor { } } windows_core::imp::interface_hierarchy!(IMFPresentationDescriptor, windows_core::IUnknown, IMFAttributes); +impl IMFPresentationDescriptor { + pub unsafe fn GetStreamDescriptorCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamDescriptorCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetStreamDescriptorByIndex(&self, dwindex: u32, pfselected: *mut windows_core::BOOL, ppdescriptor: *mut Option) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetStreamDescriptorByIndex)(windows_core::Interface::as_raw(self), dwindex, pfselected as _, core::mem::transmute(ppdescriptor)).ok() } + } + pub unsafe fn SelectStream(&self, dwdescriptorindex: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SelectStream)(windows_core::Interface::as_raw(self), dwdescriptorindex).ok() } + } + pub unsafe fn DeselectStream(&self, dwdescriptorindex: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).DeselectStream)(windows_core::Interface::as_raw(self), dwdescriptorindex).ok() } + } + pub unsafe fn Clone(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Clone)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFPresentationDescriptor_Vtbl { @@ -40232,7 +129409,7 @@ pub struct IMFPresentationDescriptor_Vtbl { #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub trait IMFPresentationDescriptor_Impl: IMFAttributes_Impl { fn GetStreamDescriptorCount(&self) -> windows_core::Result; - fn GetStreamDescriptorByIndex(&self, dwindex: u32, pfselected: *mut windows_core::BOOL, ppdescriptor: windows_core::OutRef) -> windows_core::Result<()>; + fn GetStreamDescriptorByIndex(&self, dwindex: u32, pfselected: *mut windows_core::BOOL, ppdescriptor: windows_core::OutRef<'_, IMFStreamDescriptor>) -> windows_core::Result<()>; fn SelectStream(&self, dwdescriptorindex: u32) -> windows_core::Result<()>; fn DeselectStream(&self, dwdescriptorindex: u32) -> windows_core::Result<()>; fn Clone(&self) -> windows_core::Result; @@ -40305,6 +129482,14 @@ impl core::ops::Deref for IMFPresentationTimeSource { } } windows_core::imp::interface_hierarchy!(IMFPresentationTimeSource, windows_core::IUnknown, IMFClock); +impl IMFPresentationTimeSource { + pub unsafe fn GetUnderlyingClock(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetUnderlyingClock)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFPresentationTimeSource_Vtbl { @@ -40344,13 +129529,76 @@ impl core::ops::Deref for IMFSample { } windows_core::imp::interface_hierarchy!(IMFSample, windows_core::IUnknown, IMFAttributes); impl IMFSample { + pub unsafe fn GetSampleFlags(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetSampleFlags)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn SetSampleFlags(&self, dwsampleflags: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetSampleFlags)(windows_core::Interface::as_raw(self), dwsampleflags).ok() } + } + pub unsafe fn GetSampleTime(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetSampleTime)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn SetSampleTime(&self, hnssampletime: i64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetSampleTime)(windows_core::Interface::as_raw(self), hnssampletime).ok() } + } + pub unsafe fn GetSampleDuration(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetSampleDuration)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn SetSampleDuration(&self, hnssampleduration: i64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetSampleDuration)(windows_core::Interface::as_raw(self), hnssampleduration).ok() } + } + pub unsafe fn GetBufferCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetBufferCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } pub unsafe fn GetBufferByIndex(&self, dwindex: u32) -> windows_core::Result { unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(self).GetBufferByIndex)(windows_core::Interface::as_raw(self), dwindex, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub unsafe fn ConvertToContiguousBuffer(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).ConvertToContiguousBuffer)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } } + pub unsafe fn AddBuffer(&self, pbuffer: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).AddBuffer)(windows_core::Interface::as_raw(self), pbuffer.param().abi()).ok() } + } + pub unsafe fn RemoveBufferByIndex(&self, dwindex: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveBufferByIndex)(windows_core::Interface::as_raw(self), dwindex).ok() } + } + pub unsafe fn RemoveAllBuffers(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveAllBuffers)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn GetTotalLength(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTotalLength)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn CopyToBuffer(&self, pbuffer: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CopyToBuffer)(windows_core::Interface::as_raw(self), pbuffer.param().abi()).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFSample_Vtbl { @@ -40381,11 +129629,11 @@ pub trait IMFSample_Impl: IMFAttributes_Impl { fn GetBufferCount(&self) -> windows_core::Result; fn GetBufferByIndex(&self, dwindex: u32) -> windows_core::Result; fn ConvertToContiguousBuffer(&self) -> windows_core::Result; - fn AddBuffer(&self, pbuffer: windows_core::Ref) -> windows_core::Result<()>; + fn AddBuffer(&self, pbuffer: windows_core::Ref<'_, IMFMediaBuffer>) -> windows_core::Result<()>; fn RemoveBufferByIndex(&self, dwindex: u32) -> windows_core::Result<()>; fn RemoveAllBuffers(&self) -> windows_core::Result<()>; fn GetTotalLength(&self) -> windows_core::Result; - fn CopyToBuffer(&self, pbuffer: windows_core::Ref) -> windows_core::Result<()>; + fn CopyToBuffer(&self, pbuffer: windows_core::Ref<'_, IMFMediaBuffer>) -> windows_core::Result<()>; } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] impl IMFSample_Vtbl { @@ -40548,6 +129796,20 @@ impl core::ops::Deref for IMFSampleGrabberSinkCallback { } } windows_core::imp::interface_hierarchy!(IMFSampleGrabberSinkCallback, windows_core::IUnknown, IMFClockStateSink); +impl IMFSampleGrabberSinkCallback { + pub unsafe fn OnSetPresentationClock(&self, ppresentationclock: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).OnSetPresentationClock)(windows_core::Interface::as_raw(self), ppresentationclock.param().abi()).ok() } + } + pub unsafe fn OnProcessSample(&self, guidmajormediatype: *const windows_core::GUID, dwsampleflags: u32, llsampletime: i64, llsampleduration: i64, psamplebuffer: &[u8]) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).OnProcessSample)(windows_core::Interface::as_raw(self), guidmajormediatype, dwsampleflags, llsampletime, llsampleduration, core::mem::transmute(psamplebuffer.as_ptr()), psamplebuffer.len().try_into().unwrap()).ok() } + } + pub unsafe fn OnShutdown(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).OnShutdown)(windows_core::Interface::as_raw(self)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFSampleGrabberSinkCallback_Vtbl { @@ -40557,7 +129819,7 @@ pub struct IMFSampleGrabberSinkCallback_Vtbl { pub OnShutdown: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, } pub trait IMFSampleGrabberSinkCallback_Impl: IMFClockStateSink_Impl { - fn OnSetPresentationClock(&self, ppresentationclock: windows_core::Ref) -> windows_core::Result<()>; + fn OnSetPresentationClock(&self, ppresentationclock: windows_core::Ref<'_, IMFPresentationClock>) -> windows_core::Result<()>; fn OnProcessSample(&self, guidmajormediatype: *const windows_core::GUID, dwsampleflags: u32, llsampletime: i64, llsampleduration: i64, psamplebuffer: *const u8, dwsamplesize: u32) -> windows_core::Result<()>; fn OnShutdown(&self) -> windows_core::Result<()>; } @@ -40601,6 +129863,14 @@ impl core::ops::Deref for IMFSampleGrabberSinkCallback2 { } } windows_core::imp::interface_hierarchy!(IMFSampleGrabberSinkCallback2, windows_core::IUnknown, IMFClockStateSink, IMFSampleGrabberSinkCallback); +impl IMFSampleGrabberSinkCallback2 { + pub unsafe fn OnProcessSampleEx(&self, guidmajormediatype: *const windows_core::GUID, dwsampleflags: u32, llsampletime: i64, llsampleduration: i64, psamplebuffer: &[u8], pattributes: P6) -> windows_core::Result<()> + where + P6: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).OnProcessSampleEx)(windows_core::Interface::as_raw(self), guidmajormediatype, dwsampleflags, llsampletime, llsampleduration, core::mem::transmute(psamplebuffer.as_ptr()), psamplebuffer.len().try_into().unwrap(), pattributes.param().abi()).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFSampleGrabberSinkCallback2_Vtbl { @@ -40608,7 +129878,7 @@ pub struct IMFSampleGrabberSinkCallback2_Vtbl { pub OnProcessSampleEx: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, u32, i64, i64, *const u8, u32, *mut core::ffi::c_void) -> windows_core::HRESULT, } pub trait IMFSampleGrabberSinkCallback2_Impl: IMFSampleGrabberSinkCallback_Impl { - fn OnProcessSampleEx(&self, guidmajormediatype: *const windows_core::GUID, dwsampleflags: u32, llsampletime: i64, llsampleduration: i64, psamplebuffer: *const u8, dwsamplesize: u32, pattributes: windows_core::Ref) -> windows_core::Result<()>; + fn OnProcessSampleEx(&self, guidmajormediatype: *const windows_core::GUID, dwsampleflags: u32, llsampletime: i64, llsampleduration: i64, psamplebuffer: *const u8, dwsamplesize: u32, pattributes: windows_core::Ref<'_, IMFAttributes>) -> windows_core::Result<()>; } impl IMFSampleGrabberSinkCallback2_Vtbl { pub const fn new() -> Self { @@ -40633,6 +129903,26 @@ impl core::ops::Deref for IMFSensorStream { } } windows_core::imp::interface_hierarchy!(IMFSensorStream, windows_core::IUnknown, IMFAttributes); +impl IMFSensorStream { + pub unsafe fn GetMediaTypeCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMediaTypeCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetMediaType(&self, dwindex: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMediaType)(windows_core::Interface::as_raw(self), dwindex, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn CloneSensorStream(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CloneSensorStream)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFSensorStream_Vtbl { @@ -40699,13 +129989,262 @@ impl IMFSensorStream_Vtbl { } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] impl windows_core::RuntimeName for IMFSensorStream {} +windows_core::imp::define_interface!(IMFSinkWriter, IMFSinkWriter_Vtbl, 0x3137f1cd_fe5e_4805_a5d8_fb477448cb3d); +windows_core::imp::interface_hierarchy!(IMFSinkWriter, windows_core::IUnknown); +impl IMFSinkWriter { + pub unsafe fn AddStream(&self, ptargetmediatype: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).AddStream)(windows_core::Interface::as_raw(self), ptargetmediatype.param().abi(), &mut result__).map(|| result__) + } + } + pub unsafe fn SetInputMediaType(&self, dwstreamindex: u32, pinputmediatype: P1, pencodingparameters: P2) -> windows_core::Result<()> + where + P1: windows_core::Param, + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetInputMediaType)(windows_core::Interface::as_raw(self), dwstreamindex, pinputmediatype.param().abi(), pencodingparameters.param().abi()).ok() } + } + pub unsafe fn BeginWriting(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).BeginWriting)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn WriteSample(&self, dwstreamindex: u32, psample: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).WriteSample)(windows_core::Interface::as_raw(self), dwstreamindex, psample.param().abi()).ok() } + } + pub unsafe fn SendStreamTick(&self, dwstreamindex: u32, lltimestamp: i64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SendStreamTick)(windows_core::Interface::as_raw(self), dwstreamindex, lltimestamp).ok() } + } + pub unsafe fn PlaceMarker(&self, dwstreamindex: u32, pvcontext: *const core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).PlaceMarker)(windows_core::Interface::as_raw(self), dwstreamindex, pvcontext).ok() } + } + pub unsafe fn NotifyEndOfSegment(&self, dwstreamindex: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).NotifyEndOfSegment)(windows_core::Interface::as_raw(self), dwstreamindex).ok() } + } + pub unsafe fn Flush(&self, dwstreamindex: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Flush)(windows_core::Interface::as_raw(self), dwstreamindex).ok() } + } + pub unsafe fn Finalize(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Finalize)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn GetServiceForStream(&self, dwstreamindex: u32, guidservice: *const windows_core::GUID, riid: *const windows_core::GUID, ppvobject: *mut *mut core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetServiceForStream)(windows_core::Interface::as_raw(self), dwstreamindex, guidservice, riid, ppvobject as _).ok() } + } + pub unsafe fn GetStatistics(&self, dwstreamindex: u32, pstats: *mut MF_SINK_WRITER_STATISTICS) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetStatistics)(windows_core::Interface::as_raw(self), dwstreamindex, pstats as _).ok() } + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMFSinkWriter_Vtbl { + pub base__: windows_core::IUnknown_Vtbl, + pub AddStream: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, + pub SetInputMediaType: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub BeginWriting: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, + pub WriteSample: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *mut core::ffi::c_void) -> windows_core::HRESULT, + pub SendStreamTick: unsafe extern "system" fn(*mut core::ffi::c_void, u32, i64) -> windows_core::HRESULT, + pub PlaceMarker: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const core::ffi::c_void) -> windows_core::HRESULT, + pub NotifyEndOfSegment: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub Flush: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, + pub Finalize: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetServiceForStream: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const windows_core::GUID, *const windows_core::GUID, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, + pub GetStatistics: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *mut MF_SINK_WRITER_STATISTICS) -> windows_core::HRESULT, +} +pub trait IMFSinkWriter_Impl: windows_core::IUnknownImpl { + fn AddStream(&self, ptargetmediatype: windows_core::Ref<'_, IMFMediaType>) -> windows_core::Result; + fn SetInputMediaType(&self, dwstreamindex: u32, pinputmediatype: windows_core::Ref<'_, IMFMediaType>, pencodingparameters: windows_core::Ref<'_, IMFAttributes>) -> windows_core::Result<()>; + fn BeginWriting(&self) -> windows_core::Result<()>; + fn WriteSample(&self, dwstreamindex: u32, psample: windows_core::Ref<'_, IMFSample>) -> windows_core::Result<()>; + fn SendStreamTick(&self, dwstreamindex: u32, lltimestamp: i64) -> windows_core::Result<()>; + fn PlaceMarker(&self, dwstreamindex: u32, pvcontext: *const core::ffi::c_void) -> windows_core::Result<()>; + fn NotifyEndOfSegment(&self, dwstreamindex: u32) -> windows_core::Result<()>; + fn Flush(&self, dwstreamindex: u32) -> windows_core::Result<()>; + fn Finalize(&self) -> windows_core::Result<()>; + fn GetServiceForStream(&self, dwstreamindex: u32, guidservice: *const windows_core::GUID, riid: *const windows_core::GUID, ppvobject: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; + fn GetStatistics(&self, dwstreamindex: u32, pstats: *mut MF_SINK_WRITER_STATISTICS) -> windows_core::Result<()>; +} +impl IMFSinkWriter_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AddStream(this: *mut core::ffi::c_void, ptargetmediatype: *mut core::ffi::c_void, pdwstreamindex: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMFSinkWriter_Impl::AddStream(this, core::mem::transmute_copy(&ptargetmediatype)) { + Ok(ok__) => { + pdwstreamindex.write(core::mem::transmute(ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SetInputMediaType(this: *mut core::ffi::c_void, dwstreamindex: u32, pinputmediatype: *mut core::ffi::c_void, pencodingparameters: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFSinkWriter_Impl::SetInputMediaType(this, core::mem::transmute_copy(&dwstreamindex), core::mem::transmute_copy(&pinputmediatype), core::mem::transmute_copy(&pencodingparameters)).into() + } + } + unsafe extern "system" fn BeginWriting(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFSinkWriter_Impl::BeginWriting(this).into() + } + } + unsafe extern "system" fn WriteSample(this: *mut core::ffi::c_void, dwstreamindex: u32, psample: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFSinkWriter_Impl::WriteSample(this, core::mem::transmute_copy(&dwstreamindex), core::mem::transmute_copy(&psample)).into() + } + } + unsafe extern "system" fn SendStreamTick(this: *mut core::ffi::c_void, dwstreamindex: u32, lltimestamp: i64) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFSinkWriter_Impl::SendStreamTick(this, core::mem::transmute_copy(&dwstreamindex), core::mem::transmute_copy(&lltimestamp)).into() + } + } + unsafe extern "system" fn PlaceMarker(this: *mut core::ffi::c_void, dwstreamindex: u32, pvcontext: *const core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFSinkWriter_Impl::PlaceMarker(this, core::mem::transmute_copy(&dwstreamindex), core::mem::transmute_copy(&pvcontext)).into() + } + } + unsafe extern "system" fn NotifyEndOfSegment(this: *mut core::ffi::c_void, dwstreamindex: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFSinkWriter_Impl::NotifyEndOfSegment(this, core::mem::transmute_copy(&dwstreamindex)).into() + } + } + unsafe extern "system" fn Flush(this: *mut core::ffi::c_void, dwstreamindex: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFSinkWriter_Impl::Flush(this, core::mem::transmute_copy(&dwstreamindex)).into() + } + } + unsafe extern "system" fn Finalize(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFSinkWriter_Impl::Finalize(this).into() + } + } + unsafe extern "system" fn GetServiceForStream(this: *mut core::ffi::c_void, dwstreamindex: u32, guidservice: *const windows_core::GUID, riid: *const windows_core::GUID, ppvobject: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFSinkWriter_Impl::GetServiceForStream(this, core::mem::transmute_copy(&dwstreamindex), core::mem::transmute_copy(&guidservice), core::mem::transmute_copy(&riid), core::mem::transmute_copy(&ppvobject)).into() + } + } + unsafe extern "system" fn GetStatistics(this: *mut core::ffi::c_void, dwstreamindex: u32, pstats: *mut MF_SINK_WRITER_STATISTICS) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFSinkWriter_Impl::GetStatistics(this, core::mem::transmute_copy(&dwstreamindex), core::mem::transmute_copy(&pstats)).into() + } + } + Self { + base__: windows_core::IUnknown_Vtbl::new::(), + AddStream: AddStream::, + SetInputMediaType: SetInputMediaType::, + BeginWriting: BeginWriting::, + WriteSample: WriteSample::, + SendStreamTick: SendStreamTick::, + PlaceMarker: PlaceMarker::, + NotifyEndOfSegment: NotifyEndOfSegment::, + Flush: Flush::, + Finalize: Finalize::, + GetServiceForStream: GetServiceForStream::, + GetStatistics: GetStatistics::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID + } +} +impl windows_core::RuntimeName for IMFSinkWriter {} +windows_core::imp::define_interface!(IMFSinkWriterEx, IMFSinkWriterEx_Vtbl, 0x588d72ab_5bc1_496a_8714_b70617141b25); +impl core::ops::Deref for IMFSinkWriterEx { + type Target = IMFSinkWriter; + fn deref(&self) -> &Self::Target { + unsafe { core::mem::transmute(self) } + } +} +windows_core::imp::interface_hierarchy!(IMFSinkWriterEx, windows_core::IUnknown, IMFSinkWriter); +impl IMFSinkWriterEx { + pub unsafe fn GetTransformForStream(&self, dwstreamindex: u32, dwtransformindex: u32, pguidcategory: Option<*mut windows_core::GUID>, pptransform: *mut Option) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetTransformForStream)(windows_core::Interface::as_raw(self), dwstreamindex, dwtransformindex, pguidcategory.unwrap_or(core::mem::zeroed()) as _, core::mem::transmute(pptransform)).ok() } + } +} +#[repr(C)] +#[doc(hidden)] +pub struct IMFSinkWriterEx_Vtbl { + pub base__: IMFSinkWriter_Vtbl, + pub GetTransformForStream: unsafe extern "system" fn(*mut core::ffi::c_void, u32, u32, *mut windows_core::GUID, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, +} +pub trait IMFSinkWriterEx_Impl: IMFSinkWriter_Impl { + fn GetTransformForStream(&self, dwstreamindex: u32, dwtransformindex: u32, pguidcategory: *mut windows_core::GUID, pptransform: windows_core::OutRef<'_, IMFTransform>) -> windows_core::Result<()>; +} +impl IMFSinkWriterEx_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn GetTransformForStream(this: *mut core::ffi::c_void, dwstreamindex: u32, dwtransformindex: u32, pguidcategory: *mut windows_core::GUID, pptransform: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFSinkWriterEx_Impl::GetTransformForStream(this, core::mem::transmute_copy(&dwstreamindex), core::mem::transmute_copy(&dwtransformindex), core::mem::transmute_copy(&pguidcategory), core::mem::transmute_copy(&pptransform)).into() + } + } + Self { base__: IMFSinkWriter_Vtbl::new::(), GetTransformForStream: GetTransformForStream:: } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID || iid == &::IID + } +} +impl windows_core::RuntimeName for IMFSinkWriterEx {} windows_core::imp::define_interface!(IMFSourceBuffer, IMFSourceBuffer_Vtbl, 0xe2cd3a4b_af25_4d3d_9110_da0e6f8ee877); windows_core::imp::interface_hierarchy!(IMFSourceBuffer, windows_core::IUnknown); impl IMFSourceBuffer { + pub unsafe fn GetUpdating(&self) -> windows_core::BOOL { + unsafe { (windows_core::Interface::vtable(self).GetUpdating)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetBuffered(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetBuffered)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetTimeStampOffset(&self) -> f64 { + unsafe { (windows_core::Interface::vtable(self).GetTimeStampOffset)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn SetTimeStampOffset(&self, offset: f64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetTimeStampOffset)(windows_core::Interface::as_raw(self), offset).ok() } + } + pub unsafe fn GetAppendWindowStart(&self) -> f64 { + unsafe { (windows_core::Interface::vtable(self).GetAppendWindowStart)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn SetAppendWindowStart(&self, time: f64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetAppendWindowStart)(windows_core::Interface::as_raw(self), time).ok() } + } + pub unsafe fn GetAppendWindowEnd(&self) -> f64 { + unsafe { (windows_core::Interface::vtable(self).GetAppendWindowEnd)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn SetAppendWindowEnd(&self, time: f64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetAppendWindowEnd)(windows_core::Interface::as_raw(self), time).ok() } + } pub unsafe fn Append(&self, pdata: &[u8]) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Append)(windows_core::Interface::as_raw(self), core::mem::transmute(pdata.as_ptr()), pdata.len().try_into().unwrap()).ok() } } + pub unsafe fn AppendByteStream(&self, pstream: P0, pmaxlen: Option<*const u64>) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).AppendByteStream)(windows_core::Interface::as_raw(self), pstream.param().abi(), pmaxlen.unwrap_or(core::mem::zeroed()) as _).ok() } } + pub unsafe fn Abort(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Abort)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn Remove(&self, start: f64, end: f64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Remove)(windows_core::Interface::as_raw(self), start, end).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFSourceBuffer_Vtbl { @@ -40733,7 +130272,7 @@ pub trait IMFSourceBuffer_Impl: windows_core::IUnknownImpl { fn GetAppendWindowEnd(&self) -> f64; fn SetAppendWindowEnd(&self, time: f64) -> windows_core::Result<()>; fn Append(&self, pdata: *const u8, len: u32) -> windows_core::Result<()>; - fn AppendByteStream(&self, pstream: windows_core::Ref, pmaxlen: *const u64) -> windows_core::Result<()>; + fn AppendByteStream(&self, pstream: windows_core::Ref<'_, IMFByteStream>, pmaxlen: *const u64) -> windows_core::Result<()>; fn Abort(&self) -> windows_core::Result<()>; fn Remove(&self, start: f64, end: f64) -> windows_core::Result<()>; } @@ -40840,6 +130379,14 @@ impl IMFSourceBuffer_Vtbl { impl windows_core::RuntimeName for IMFSourceBuffer {} windows_core::imp::define_interface!(IMFSourceBufferList, IMFSourceBufferList_Vtbl, 0x249981f8_8325_41f3_b80c_3b9e3aad0cbe); windows_core::imp::interface_hierarchy!(IMFSourceBufferList, windows_core::IUnknown); +impl IMFSourceBufferList { + pub unsafe fn GetLength(&self) -> u32 { + unsafe { (windows_core::Interface::vtable(self).GetLength)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetSourceBuffer(&self, index: u32) -> Option { + unsafe { (windows_core::Interface::vtable(self).GetSourceBuffer)(windows_core::Interface::as_raw(self), index) } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFSourceBufferList_Vtbl { @@ -40878,6 +130425,23 @@ impl IMFSourceBufferList_Vtbl { impl windows_core::RuntimeName for IMFSourceBufferList {} windows_core::imp::define_interface!(IMFSourceBufferNotify, IMFSourceBufferNotify_Vtbl, 0x87e47623_2ceb_45d6_9b88_d8520c4dcbbc); windows_core::imp::interface_hierarchy!(IMFSourceBufferNotify, windows_core::IUnknown); +impl IMFSourceBufferNotify { + pub unsafe fn OnUpdateStart(&self) { + unsafe { (windows_core::Interface::vtable(self).OnUpdateStart)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn OnAbort(&self) { + unsafe { (windows_core::Interface::vtable(self).OnAbort)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn OnError(&self, hr: windows_core::HRESULT) { + unsafe { (windows_core::Interface::vtable(self).OnError)(windows_core::Interface::as_raw(self), hr) } + } + pub unsafe fn OnUpdate(&self) { + unsafe { (windows_core::Interface::vtable(self).OnUpdate)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn OnUpdateEnd(&self) { + unsafe { (windows_core::Interface::vtable(self).OnUpdateEnd)(windows_core::Interface::as_raw(self)) } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFSourceBufferNotify_Vtbl { @@ -40944,6 +130508,12 @@ impl windows_core::RuntimeName for IMFSourceBufferNotify {} windows_core::imp::define_interface!(IMFSourceReader, IMFSourceReader_Vtbl, 0x70ae66f2_c809_4e4f_8915_bdcb406b7993); windows_core::imp::interface_hierarchy!(IMFSourceReader, windows_core::IUnknown); impl IMFSourceReader { + pub unsafe fn GetStreamSelection(&self, dwstreamindex: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamSelection)(windows_core::Interface::as_raw(self), dwstreamindex, &mut result__).map(|| result__) + } + } pub unsafe fn SetStreamSelection(&self, dwstreamindex: u32, fselected: bool) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).SetStreamSelection)(windows_core::Interface::as_raw(self), dwstreamindex, fselected.into()).ok() } } @@ -40975,6 +130545,9 @@ impl IMFSourceReader { pub unsafe fn Flush(&self, dwstreamindex: u32) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Flush)(windows_core::Interface::as_raw(self), dwstreamindex).ok() } } + pub unsafe fn GetServiceForStream(&self, dwstreamindex: u32, guidservice: *const windows_core::GUID, riid: *const windows_core::GUID, ppvobject: *mut *mut core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetServiceForStream)(windows_core::Interface::as_raw(self), dwstreamindex, guidservice, riid, ppvobject as _).ok() } + } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub unsafe fn GetPresentationAttribute(&self, dwstreamindex: u32, guidattribute: *const windows_core::GUID) -> windows_core::Result { unsafe { @@ -41010,9 +130583,9 @@ pub trait IMFSourceReader_Impl: windows_core::IUnknownImpl { fn SetStreamSelection(&self, dwstreamindex: u32, fselected: windows_core::BOOL) -> windows_core::Result<()>; fn GetNativeMediaType(&self, dwstreamindex: u32, dwmediatypeindex: u32) -> windows_core::Result; fn GetCurrentMediaType(&self, dwstreamindex: u32) -> windows_core::Result; - fn SetCurrentMediaType(&self, dwstreamindex: u32, pdwreserved: *const u32, pmediatype: windows_core::Ref) -> windows_core::Result<()>; + fn SetCurrentMediaType(&self, dwstreamindex: u32, pdwreserved: *const u32, pmediatype: windows_core::Ref<'_, IMFMediaType>) -> windows_core::Result<()>; fn SetCurrentPosition(&self, guidtimeformat: *const windows_core::GUID, varposition: *const super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result<()>; - fn ReadSample(&self, dwstreamindex: u32, dwcontrolflags: u32, pdwactualstreamindex: *mut u32, pdwstreamflags: *mut u32, plltimestamp: *mut i64, ppsample: windows_core::OutRef) -> windows_core::Result<()>; + fn ReadSample(&self, dwstreamindex: u32, dwcontrolflags: u32, pdwactualstreamindex: *mut u32, pdwstreamflags: *mut u32, plltimestamp: *mut i64, ppsample: windows_core::OutRef<'_, IMFSample>) -> windows_core::Result<()>; fn Flush(&self, dwstreamindex: u32) -> windows_core::Result<()>; fn GetServiceForStream(&self, dwstreamindex: u32, guidservice: *const windows_core::GUID, riid: *const windows_core::GUID, ppvobject: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; fn GetPresentationAttribute(&self, dwstreamindex: u32, guidattribute: *const windows_core::GUID) -> windows_core::Result; @@ -41126,6 +130699,23 @@ impl IMFSourceReader_Vtbl { impl windows_core::RuntimeName for IMFSourceReader {} windows_core::imp::define_interface!(IMFSourceReaderCallback, IMFSourceReaderCallback_Vtbl, 0xdeec8d99_fa1d_4d82_84c2_2c8969944867); windows_core::imp::interface_hierarchy!(IMFSourceReaderCallback, windows_core::IUnknown); +impl IMFSourceReaderCallback { + pub unsafe fn OnReadSample(&self, hrstatus: windows_core::HRESULT, dwstreamindex: u32, dwstreamflags: u32, lltimestamp: i64, psample: P4) -> windows_core::Result<()> + where + P4: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).OnReadSample)(windows_core::Interface::as_raw(self), hrstatus, dwstreamindex, dwstreamflags, lltimestamp, psample.param().abi()).ok() } + } + pub unsafe fn OnFlush(&self, dwstreamindex: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).OnFlush)(windows_core::Interface::as_raw(self), dwstreamindex).ok() } + } + pub unsafe fn OnEvent(&self, dwstreamindex: u32, pevent: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).OnEvent)(windows_core::Interface::as_raw(self), dwstreamindex, pevent.param().abi()).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFSourceReaderCallback_Vtbl { @@ -41135,9 +130725,9 @@ pub struct IMFSourceReaderCallback_Vtbl { pub OnEvent: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *mut core::ffi::c_void) -> windows_core::HRESULT, } pub trait IMFSourceReaderCallback_Impl: windows_core::IUnknownImpl { - fn OnReadSample(&self, hrstatus: windows_core::HRESULT, dwstreamindex: u32, dwstreamflags: u32, lltimestamp: i64, psample: windows_core::Ref) -> windows_core::Result<()>; + fn OnReadSample(&self, hrstatus: windows_core::HRESULT, dwstreamindex: u32, dwstreamflags: u32, lltimestamp: i64, psample: windows_core::Ref<'_, IMFSample>) -> windows_core::Result<()>; fn OnFlush(&self, dwstreamindex: u32) -> windows_core::Result<()>; - fn OnEvent(&self, dwstreamindex: u32, pevent: windows_core::Ref) -> windows_core::Result<()>; + fn OnEvent(&self, dwstreamindex: u32, pevent: windows_core::Ref<'_, IMFMediaEvent>) -> windows_core::Result<()>; } impl IMFSourceReaderCallback_Vtbl { pub const fn new() -> Self { @@ -41179,6 +130769,14 @@ impl core::ops::Deref for IMFSourceReaderCallback2 { } } windows_core::imp::interface_hierarchy!(IMFSourceReaderCallback2, windows_core::IUnknown, IMFSourceReaderCallback); +impl IMFSourceReaderCallback2 { + pub unsafe fn OnTransformChange(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).OnTransformChange)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn OnStreamError(&self, dwstreamindex: u32, hrstatus: windows_core::HRESULT) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).OnStreamError)(windows_core::Interface::as_raw(self), dwstreamindex, hrstatus).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFSourceReaderCallback2_Vtbl { @@ -41223,6 +130821,29 @@ impl core::ops::Deref for IMFSourceReaderEx { } } windows_core::imp::interface_hierarchy!(IMFSourceReaderEx, windows_core::IUnknown, IMFSourceReader); +impl IMFSourceReaderEx { + pub unsafe fn SetNativeMediaType(&self, dwstreamindex: u32, pmediatype: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).SetNativeMediaType)(windows_core::Interface::as_raw(self), dwstreamindex, pmediatype.param().abi(), &mut result__).map(|| result__) + } + } + pub unsafe fn AddTransformForStream(&self, dwstreamindex: u32, ptransformoractivate: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).AddTransformForStream)(windows_core::Interface::as_raw(self), dwstreamindex, ptransformoractivate.param().abi()).ok() } + } + pub unsafe fn RemoveAllTransformsForStream(&self, dwstreamindex: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RemoveAllTransformsForStream)(windows_core::Interface::as_raw(self), dwstreamindex).ok() } + } + pub unsafe fn GetTransformForStream(&self, dwstreamindex: u32, dwtransformindex: u32, pguidcategory: Option<*mut windows_core::GUID>, pptransform: *mut Option) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetTransformForStream)(windows_core::Interface::as_raw(self), dwstreamindex, dwtransformindex, pguidcategory.unwrap_or(core::mem::zeroed()) as _, core::mem::transmute(pptransform)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFSourceReaderEx_Vtbl { @@ -41234,10 +130855,10 @@ pub struct IMFSourceReaderEx_Vtbl { } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub trait IMFSourceReaderEx_Impl: IMFSourceReader_Impl { - fn SetNativeMediaType(&self, dwstreamindex: u32, pmediatype: windows_core::Ref) -> windows_core::Result; - fn AddTransformForStream(&self, dwstreamindex: u32, ptransformoractivate: windows_core::Ref) -> windows_core::Result<()>; + fn SetNativeMediaType(&self, dwstreamindex: u32, pmediatype: windows_core::Ref<'_, IMFMediaType>) -> windows_core::Result; + fn AddTransformForStream(&self, dwstreamindex: u32, ptransformoractivate: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; fn RemoveAllTransformsForStream(&self, dwstreamindex: u32) -> windows_core::Result<()>; - fn GetTransformForStream(&self, dwstreamindex: u32, dwtransformindex: u32, pguidcategory: *mut windows_core::GUID, pptransform: windows_core::OutRef) -> windows_core::Result<()>; + fn GetTransformForStream(&self, dwstreamindex: u32, dwtransformindex: u32, pguidcategory: *mut windows_core::GUID, pptransform: windows_core::OutRef<'_, IMFTransform>) -> windows_core::Result<()>; } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] impl IMFSourceReaderEx_Vtbl { @@ -41294,6 +130915,35 @@ impl core::ops::Deref for IMFSpatialAudioObjectBuffer { } } windows_core::imp::interface_hierarchy!(IMFSpatialAudioObjectBuffer, windows_core::IUnknown, IMFMediaBuffer); +impl IMFSpatialAudioObjectBuffer { + pub unsafe fn SetID(&self, u32id: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetID)(windows_core::Interface::as_raw(self), u32id).ok() } + } + pub unsafe fn GetID(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetID)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Win32_Media_Audio")] + pub unsafe fn SetType(&self, r#type: super::Audio::AudioObjectType) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetType)(windows_core::Interface::as_raw(self), r#type).ok() } + } + #[cfg(feature = "Win32_Media_Audio")] + pub unsafe fn GetType(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetType)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Win32_Media_Audio")] + pub unsafe fn GetMetadataItems(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMetadataItems)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFSpatialAudioObjectBuffer_Vtbl { @@ -41395,6 +131045,26 @@ impl core::ops::Deref for IMFSpatialAudioSample { } } windows_core::imp::interface_hierarchy!(IMFSpatialAudioSample, windows_core::IUnknown, IMFAttributes, IMFSample); +impl IMFSpatialAudioSample { + pub unsafe fn GetObjectCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetObjectCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn AddSpatialAudioObject(&self, paudioobjbuffer: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).AddSpatialAudioObject)(windows_core::Interface::as_raw(self), paudioobjbuffer.param().abi()).ok() } + } + pub unsafe fn GetSpatialAudioObjectByIndex(&self, dwindex: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetSpatialAudioObjectByIndex)(windows_core::Interface::as_raw(self), dwindex, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFSpatialAudioSample_Vtbl { @@ -41406,7 +131076,7 @@ pub struct IMFSpatialAudioSample_Vtbl { #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub trait IMFSpatialAudioSample_Impl: IMFSample_Impl { fn GetObjectCount(&self) -> windows_core::Result; - fn AddSpatialAudioObject(&self, paudioobjbuffer: windows_core::Ref) -> windows_core::Result<()>; + fn AddSpatialAudioObject(&self, paudioobjbuffer: windows_core::Ref<'_, IMFSpatialAudioObjectBuffer>) -> windows_core::Result<()>; fn GetSpatialAudioObjectByIndex(&self, dwindex: u32) -> windows_core::Result; } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] @@ -41463,6 +131133,20 @@ impl core::ops::Deref for IMFStreamDescriptor { } } windows_core::imp::interface_hierarchy!(IMFStreamDescriptor, windows_core::IUnknown, IMFAttributes); +impl IMFStreamDescriptor { + pub unsafe fn GetStreamIdentifier(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetStreamIdentifier)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetMediaTypeHandler(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMediaTypeHandler)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFStreamDescriptor_Vtbl { @@ -41523,6 +131207,34 @@ impl core::ops::Deref for IMFStreamSink { } windows_core::imp::interface_hierarchy!(IMFStreamSink, windows_core::IUnknown, IMFMediaEventGenerator); impl IMFStreamSink { + pub unsafe fn GetMediaSink(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMediaSink)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetIdentifier(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetIdentifier)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetMediaTypeHandler(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMediaTypeHandler)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn ProcessSample(&self, psample: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).ProcessSample)(windows_core::Interface::as_raw(self), psample.param().abi()).ok() } + } + #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] + pub unsafe fn PlaceMarker(&self, emarkertype: MFSTREAMSINK_MARKER_TYPE, pvarmarkervalue: *const super::super::System::Com::StructuredStorage::PROPVARIANT, pvarcontextvalue: *const super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).PlaceMarker)(windows_core::Interface::as_raw(self), emarkertype, core::mem::transmute(pvarmarkervalue), core::mem::transmute(pvarcontextvalue)).ok() } + } pub unsafe fn Flush(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Flush)(windows_core::Interface::as_raw(self)).ok() } } @@ -41546,7 +131258,7 @@ pub trait IMFStreamSink_Impl: IMFMediaEventGenerator_Impl { fn GetMediaSink(&self) -> windows_core::Result; fn GetIdentifier(&self) -> windows_core::Result; fn GetMediaTypeHandler(&self) -> windows_core::Result; - fn ProcessSample(&self, psample: windows_core::Ref) -> windows_core::Result<()>; + fn ProcessSample(&self, psample: windows_core::Ref<'_, IMFSample>) -> windows_core::Result<()>; fn PlaceMarker(&self, emarkertype: MFSTREAMSINK_MARKER_TYPE, pvarmarkervalue: *const super::super::System::Com::StructuredStorage::PROPVARIANT, pvarcontextvalue: *const super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result<()>; fn Flush(&self) -> windows_core::Result<()>; } @@ -41631,6 +131343,65 @@ impl core::ops::Deref for IMFTopology { } } windows_core::imp::interface_hierarchy!(IMFTopology, windows_core::IUnknown, IMFAttributes); +impl IMFTopology { + pub unsafe fn GetTopologyID(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTopologyID)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn AddNode(&self, pnode: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).AddNode)(windows_core::Interface::as_raw(self), pnode.param().abi()).ok() } + } + pub unsafe fn RemoveNode(&self, pnode: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).RemoveNode)(windows_core::Interface::as_raw(self), pnode.param().abi()).ok() } + } + pub unsafe fn GetNodeCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetNodeCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetNode(&self, windex: u16) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetNode)(windows_core::Interface::as_raw(self), windex, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn Clear(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Clear)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn CloneFrom(&self, ptopology: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CloneFrom)(windows_core::Interface::as_raw(self), ptopology.param().abi()).ok() } + } + pub unsafe fn GetNodeByID(&self, qwtoponodeid: u64) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetNodeByID)(windows_core::Interface::as_raw(self), qwtoponodeid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetSourceNodeCollection(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetSourceNodeCollection)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetOutputNodeCollection(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetOutputNodeCollection)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFTopology_Vtbl { @@ -41649,12 +131420,12 @@ pub struct IMFTopology_Vtbl { #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub trait IMFTopology_Impl: IMFAttributes_Impl { fn GetTopologyID(&self) -> windows_core::Result; - fn AddNode(&self, pnode: windows_core::Ref) -> windows_core::Result<()>; - fn RemoveNode(&self, pnode: windows_core::Ref) -> windows_core::Result<()>; + fn AddNode(&self, pnode: windows_core::Ref<'_, IMFTopologyNode>) -> windows_core::Result<()>; + fn RemoveNode(&self, pnode: windows_core::Ref<'_, IMFTopologyNode>) -> windows_core::Result<()>; fn GetNodeCount(&self) -> windows_core::Result; fn GetNode(&self, windex: u16) -> windows_core::Result; fn Clear(&self) -> windows_core::Result<()>; - fn CloneFrom(&self, ptopology: windows_core::Ref) -> windows_core::Result<()>; + fn CloneFrom(&self, ptopology: windows_core::Ref<'_, IMFTopology>) -> windows_core::Result<()>; fn GetNodeByID(&self, qwtoponodeid: u64) -> windows_core::Result; fn GetSourceNodeCollection(&self) -> windows_core::Result; fn GetOutputNodeCollection(&self) -> windows_core::Result; @@ -41786,6 +131557,92 @@ impl core::ops::Deref for IMFTopologyNode { } } windows_core::imp::interface_hierarchy!(IMFTopologyNode, windows_core::IUnknown, IMFAttributes); +impl IMFTopologyNode { + pub unsafe fn SetObject(&self, pobject: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetObject)(windows_core::Interface::as_raw(self), pobject.param().abi()).ok() } + } + pub unsafe fn GetObject(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetObject)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetNodeType(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetNodeType)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetTopoNodeID(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTopoNodeID)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn SetTopoNodeID(&self, ulltopoid: u64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetTopoNodeID)(windows_core::Interface::as_raw(self), ulltopoid).ok() } + } + pub unsafe fn GetInputCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetInputCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetOutputCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetOutputCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn ConnectOutput(&self, dwoutputindex: u32, pdownstreamnode: P1, dwinputindexondownstreamnode: u32) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).ConnectOutput)(windows_core::Interface::as_raw(self), dwoutputindex, pdownstreamnode.param().abi(), dwinputindexondownstreamnode).ok() } + } + pub unsafe fn DisconnectOutput(&self, dwoutputindex: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).DisconnectOutput)(windows_core::Interface::as_raw(self), dwoutputindex).ok() } + } + pub unsafe fn GetInput(&self, dwinputindex: u32, ppupstreamnode: *mut Option, pdwoutputindexonupstreamnode: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetInput)(windows_core::Interface::as_raw(self), dwinputindex, core::mem::transmute(ppupstreamnode), pdwoutputindexonupstreamnode as _).ok() } + } + pub unsafe fn GetOutput(&self, dwoutputindex: u32, ppdownstreamnode: *mut Option, pdwinputindexondownstreamnode: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetOutput)(windows_core::Interface::as_raw(self), dwoutputindex, core::mem::transmute(ppdownstreamnode), pdwinputindexondownstreamnode as _).ok() } + } + pub unsafe fn SetOutputPrefType(&self, dwoutputindex: u32, ptype: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetOutputPrefType)(windows_core::Interface::as_raw(self), dwoutputindex, ptype.param().abi()).ok() } + } + pub unsafe fn GetOutputPrefType(&self, dwoutputindex: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetOutputPrefType)(windows_core::Interface::as_raw(self), dwoutputindex, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn SetInputPrefType(&self, dwinputindex: u32, ptype: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetInputPrefType)(windows_core::Interface::as_raw(self), dwinputindex, ptype.param().abi()).ok() } + } + pub unsafe fn GetInputPrefType(&self, dwinputindex: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetInputPrefType)(windows_core::Interface::as_raw(self), dwinputindex, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn CloneFrom(&self, pnode: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CloneFrom)(windows_core::Interface::as_raw(self), pnode.param().abi()).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFTopologyNode_Vtbl { @@ -41809,22 +131666,22 @@ pub struct IMFTopologyNode_Vtbl { } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub trait IMFTopologyNode_Impl: IMFAttributes_Impl { - fn SetObject(&self, pobject: windows_core::Ref) -> windows_core::Result<()>; + fn SetObject(&self, pobject: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; fn GetObject(&self) -> windows_core::Result; fn GetNodeType(&self) -> windows_core::Result; fn GetTopoNodeID(&self) -> windows_core::Result; fn SetTopoNodeID(&self, ulltopoid: u64) -> windows_core::Result<()>; fn GetInputCount(&self) -> windows_core::Result; fn GetOutputCount(&self) -> windows_core::Result; - fn ConnectOutput(&self, dwoutputindex: u32, pdownstreamnode: windows_core::Ref, dwinputindexondownstreamnode: u32) -> windows_core::Result<()>; + fn ConnectOutput(&self, dwoutputindex: u32, pdownstreamnode: windows_core::Ref<'_, IMFTopologyNode>, dwinputindexondownstreamnode: u32) -> windows_core::Result<()>; fn DisconnectOutput(&self, dwoutputindex: u32) -> windows_core::Result<()>; - fn GetInput(&self, dwinputindex: u32, ppupstreamnode: windows_core::OutRef, pdwoutputindexonupstreamnode: *mut u32) -> windows_core::Result<()>; - fn GetOutput(&self, dwoutputindex: u32, ppdownstreamnode: windows_core::OutRef, pdwinputindexondownstreamnode: *mut u32) -> windows_core::Result<()>; - fn SetOutputPrefType(&self, dwoutputindex: u32, ptype: windows_core::Ref) -> windows_core::Result<()>; + fn GetInput(&self, dwinputindex: u32, ppupstreamnode: windows_core::OutRef<'_, IMFTopologyNode>, pdwoutputindexonupstreamnode: *mut u32) -> windows_core::Result<()>; + fn GetOutput(&self, dwoutputindex: u32, ppdownstreamnode: windows_core::OutRef<'_, IMFTopologyNode>, pdwinputindexondownstreamnode: *mut u32) -> windows_core::Result<()>; + fn SetOutputPrefType(&self, dwoutputindex: u32, ptype: windows_core::Ref<'_, IMFMediaType>) -> windows_core::Result<()>; fn GetOutputPrefType(&self, dwoutputindex: u32) -> windows_core::Result; - fn SetInputPrefType(&self, dwinputindex: u32, ptype: windows_core::Ref) -> windows_core::Result<()>; + fn SetInputPrefType(&self, dwinputindex: u32, ptype: windows_core::Ref<'_, IMFMediaType>) -> windows_core::Result<()>; fn GetInputPrefType(&self, dwinputindex: u32) -> windows_core::Result; - fn CloneFrom(&self, pnode: windows_core::Ref) -> windows_core::Result<()>; + fn CloneFrom(&self, pnode: windows_core::Ref<'_, IMFTopologyNode>) -> windows_core::Result<()>; } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] impl IMFTopologyNode_Vtbl { @@ -41995,6 +131852,119 @@ impl IMFTopologyNode_Vtbl { impl windows_core::RuntimeName for IMFTopologyNode {} windows_core::imp::define_interface!(IMFTransform, IMFTransform_Vtbl, 0xbf94c121_5b05_4e6f_8000_ba598961414d); windows_core::imp::interface_hierarchy!(IMFTransform, windows_core::IUnknown); +impl IMFTransform { + pub unsafe fn GetStreamLimits(&self, pdwinputminimum: *mut u32, pdwinputmaximum: *mut u32, pdwoutputminimum: *mut u32, pdwoutputmaximum: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetStreamLimits)(windows_core::Interface::as_raw(self), pdwinputminimum as _, pdwinputmaximum as _, pdwoutputminimum as _, pdwoutputmaximum as _).ok() } + } + pub unsafe fn GetStreamCount(&self, pcinputstreams: *mut u32, pcoutputstreams: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetStreamCount)(windows_core::Interface::as_raw(self), pcinputstreams as _, pcoutputstreams as _).ok() } + } + pub unsafe fn GetStreamIDs(&self, pdwinputids: &mut [u32], pdwoutputids: &mut [u32]) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetStreamIDs)(windows_core::Interface::as_raw(self), pdwinputids.len().try_into().unwrap(), core::mem::transmute(pdwinputids.as_ptr()), pdwoutputids.len().try_into().unwrap(), core::mem::transmute(pdwoutputids.as_ptr())).ok() } + } + pub unsafe fn GetInputStreamInfo(&self, dwinputstreamid: u32, pstreaminfo: *mut MFT_INPUT_STREAM_INFO) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetInputStreamInfo)(windows_core::Interface::as_raw(self), dwinputstreamid, pstreaminfo as _).ok() } + } + pub unsafe fn GetOutputStreamInfo(&self, dwoutputstreamid: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetOutputStreamInfo)(windows_core::Interface::as_raw(self), dwoutputstreamid, &mut result__).map(|| result__) + } + } + pub unsafe fn GetAttributes(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetAttributes)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetInputStreamAttributes(&self, dwinputstreamid: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetInputStreamAttributes)(windows_core::Interface::as_raw(self), dwinputstreamid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetOutputStreamAttributes(&self, dwoutputstreamid: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetOutputStreamAttributes)(windows_core::Interface::as_raw(self), dwoutputstreamid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn DeleteInputStream(&self, dwstreamid: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).DeleteInputStream)(windows_core::Interface::as_raw(self), dwstreamid).ok() } + } + pub unsafe fn AddInputStreams(&self, cstreams: u32, adwstreamids: *const u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).AddInputStreams)(windows_core::Interface::as_raw(self), cstreams, adwstreamids).ok() } + } + pub unsafe fn GetInputAvailableType(&self, dwinputstreamid: u32, dwtypeindex: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetInputAvailableType)(windows_core::Interface::as_raw(self), dwinputstreamid, dwtypeindex, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetOutputAvailableType(&self, dwoutputstreamid: u32, dwtypeindex: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetOutputAvailableType)(windows_core::Interface::as_raw(self), dwoutputstreamid, dwtypeindex, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn SetInputType(&self, dwinputstreamid: u32, ptype: P1, dwflags: u32) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetInputType)(windows_core::Interface::as_raw(self), dwinputstreamid, ptype.param().abi(), dwflags).ok() } + } + pub unsafe fn SetOutputType(&self, dwoutputstreamid: u32, ptype: P1, dwflags: u32) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetOutputType)(windows_core::Interface::as_raw(self), dwoutputstreamid, ptype.param().abi(), dwflags).ok() } + } + pub unsafe fn GetInputCurrentType(&self, dwinputstreamid: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetInputCurrentType)(windows_core::Interface::as_raw(self), dwinputstreamid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetOutputCurrentType(&self, dwoutputstreamid: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetOutputCurrentType)(windows_core::Interface::as_raw(self), dwoutputstreamid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetInputStatus(&self, dwinputstreamid: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetInputStatus)(windows_core::Interface::as_raw(self), dwinputstreamid, &mut result__).map(|| result__) + } + } + pub unsafe fn GetOutputStatus(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetOutputStatus)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn SetOutputBounds(&self, hnslowerbound: i64, hnsupperbound: i64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetOutputBounds)(windows_core::Interface::as_raw(self), hnslowerbound, hnsupperbound).ok() } + } + pub unsafe fn ProcessEvent(&self, dwinputstreamid: u32, pevent: P1) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).ProcessEvent)(windows_core::Interface::as_raw(self), dwinputstreamid, pevent.param().abi()).ok() } + } + pub unsafe fn ProcessMessage(&self, emessage: MFT_MESSAGE_TYPE, ulparam: usize) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).ProcessMessage)(windows_core::Interface::as_raw(self), emessage, ulparam).ok() } + } + pub unsafe fn ProcessInput(&self, dwinputstreamid: u32, psample: P1, dwflags: u32) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).ProcessInput)(windows_core::Interface::as_raw(self), dwinputstreamid, psample.param().abi(), dwflags).ok() } + } + pub unsafe fn ProcessOutput(&self, dwflags: u32, poutputsamples: &mut [MFT_OUTPUT_DATA_BUFFER], pdwstatus: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).ProcessOutput)(windows_core::Interface::as_raw(self), dwflags, poutputsamples.len().try_into().unwrap(), core::mem::transmute(poutputsamples.as_ptr()), pdwstatus as _).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFTransform_Vtbl { @@ -42036,16 +132006,16 @@ pub trait IMFTransform_Impl: windows_core::IUnknownImpl { fn AddInputStreams(&self, cstreams: u32, adwstreamids: *const u32) -> windows_core::Result<()>; fn GetInputAvailableType(&self, dwinputstreamid: u32, dwtypeindex: u32) -> windows_core::Result; fn GetOutputAvailableType(&self, dwoutputstreamid: u32, dwtypeindex: u32) -> windows_core::Result; - fn SetInputType(&self, dwinputstreamid: u32, ptype: windows_core::Ref, dwflags: u32) -> windows_core::Result<()>; - fn SetOutputType(&self, dwoutputstreamid: u32, ptype: windows_core::Ref, dwflags: u32) -> windows_core::Result<()>; + fn SetInputType(&self, dwinputstreamid: u32, ptype: windows_core::Ref<'_, IMFMediaType>, dwflags: u32) -> windows_core::Result<()>; + fn SetOutputType(&self, dwoutputstreamid: u32, ptype: windows_core::Ref<'_, IMFMediaType>, dwflags: u32) -> windows_core::Result<()>; fn GetInputCurrentType(&self, dwinputstreamid: u32) -> windows_core::Result; fn GetOutputCurrentType(&self, dwoutputstreamid: u32) -> windows_core::Result; fn GetInputStatus(&self, dwinputstreamid: u32) -> windows_core::Result; fn GetOutputStatus(&self) -> windows_core::Result; fn SetOutputBounds(&self, hnslowerbound: i64, hnsupperbound: i64) -> windows_core::Result<()>; - fn ProcessEvent(&self, dwinputstreamid: u32, pevent: windows_core::Ref) -> windows_core::Result<()>; + fn ProcessEvent(&self, dwinputstreamid: u32, pevent: windows_core::Ref<'_, IMFMediaEvent>) -> windows_core::Result<()>; fn ProcessMessage(&self, emessage: MFT_MESSAGE_TYPE, ulparam: usize) -> windows_core::Result<()>; - fn ProcessInput(&self, dwinputstreamid: u32, psample: windows_core::Ref, dwflags: u32) -> windows_core::Result<()>; + fn ProcessInput(&self, dwinputstreamid: u32, psample: windows_core::Ref<'_, IMFSample>, dwflags: u32) -> windows_core::Result<()>; fn ProcessOutput(&self, dwflags: u32, coutputbuffercount: u32, poutputsamples: *mut MFT_OUTPUT_DATA_BUFFER, pdwstatus: *mut u32) -> windows_core::Result<()>; } impl IMFTransform_Vtbl { @@ -42288,6 +132258,14 @@ impl core::ops::Deref for IMFVideoMediaType { } } windows_core::imp::interface_hierarchy!(IMFVideoMediaType, windows_core::IUnknown, IMFAttributes, IMFMediaType); +impl IMFVideoMediaType { + pub unsafe fn GetVideoFormat(&self) -> *mut MFVIDEOFORMAT { + unsafe { (windows_core::Interface::vtable(self).GetVideoFormat)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetVideoRepresentation(&self, guidrepresentation: windows_core::GUID, ppvrepresentation: *mut *mut core::ffi::c_void, lstride: i32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetVideoRepresentation)(windows_core::Interface::as_raw(self), core::mem::transmute(guidrepresentation), ppvrepresentation as _, lstride).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IMFVideoMediaType_Vtbl { @@ -42336,6 +132314,9 @@ impl core::ops::Deref for IMFVideoPresenter { } windows_core::imp::interface_hierarchy!(IMFVideoPresenter, windows_core::IUnknown, IMFClockStateSink); impl IMFVideoPresenter { + pub unsafe fn ProcessMessage(&self, emessage: MFVP_MESSAGE_TYPE, ulparam: usize) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).ProcessMessage)(windows_core::Interface::as_raw(self), emessage, ulparam).ok() } + } pub unsafe fn GetCurrentMediaType(&self) -> windows_core::Result { unsafe { let mut result__ = core::mem::zeroed(); @@ -42394,6 +132375,23 @@ impl core::ops::Deref for IMFVirtualCamera { } windows_core::imp::interface_hierarchy!(IMFVirtualCamera, windows_core::IUnknown, IMFAttributes); impl IMFVirtualCamera { + pub unsafe fn AddDeviceSourceInfo(&self, devicesourceinfo: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).AddDeviceSourceInfo)(windows_core::Interface::as_raw(self), devicesourceinfo.param().abi()).ok() } + } + #[cfg(feature = "Win32_Devices_Properties")] + pub unsafe fn AddProperty(&self, pkey: *const super::super::Foundation::DEVPROPKEY, r#type: super::super::Devices::Properties::DEVPROPTYPE, pbdata: &[u8]) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).AddProperty)(windows_core::Interface::as_raw(self), pkey, r#type, core::mem::transmute(pbdata.as_ptr()), pbdata.len().try_into().unwrap()).ok() } + } + pub unsafe fn AddRegistryEntry(&self, entryname: P0, subkeypath: P1, dwregtype: u32, pbdata: &[u8]) -> windows_core::Result<()> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).AddRegistryEntry)(windows_core::Interface::as_raw(self), entryname.param().abi(), subkeypath.param().abi(), dwregtype, core::mem::transmute(pbdata.as_ptr()), pbdata.len().try_into().unwrap()).ok() } + } pub unsafe fn Start(&self, pcallback: P0) -> windows_core::Result<()> where P0: windows_core::Param, @@ -42403,6 +132401,30 @@ impl IMFVirtualCamera { pub unsafe fn Stop(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Stop)(windows_core::Interface::as_raw(self)).ok() } } + pub unsafe fn Remove(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Remove)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn GetMediaSource(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMediaSource)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn SendCameraProperty(&self, propertyset: *const windows_core::GUID, propertyid: u32, propertyflags: u32, propertypayload: Option<*mut core::ffi::c_void>, propertypayloadlength: u32, data: Option<*mut core::ffi::c_void>, datalength: u32, datawritten: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SendCameraProperty)(windows_core::Interface::as_raw(self), propertyset, propertyid, propertyflags, propertypayload.unwrap_or(core::mem::zeroed()) as _, propertypayloadlength, data.unwrap_or(core::mem::zeroed()) as _, datalength, datawritten as _).ok() } + } + pub unsafe fn CreateSyncEvent(&self, kseventset: *const windows_core::GUID, kseventid: u32, kseventflags: u32, eventhandle: super::super::Foundation::HANDLE) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateSyncEvent)(windows_core::Interface::as_raw(self), kseventset, kseventid, kseventflags, eventhandle, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn CreateSyncSemaphore(&self, kseventset: *const windows_core::GUID, kseventid: u32, kseventflags: u32, semaphorehandle: super::super::Foundation::HANDLE, semaphoreadjustment: i32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateSyncSemaphore)(windows_core::Interface::as_raw(self), kseventset, kseventid, kseventflags, semaphorehandle, semaphoreadjustment, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } pub unsafe fn Shutdown(&self) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Shutdown)(windows_core::Interface::as_raw(self)).ok() } } @@ -42426,6 +132448,128 @@ pub struct IMFVirtualCamera_Vtbl { pub CreateSyncSemaphore: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, u32, u32, super::super::Foundation::HANDLE, i32, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, pub Shutdown: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, } +#[cfg(all(feature = "Win32_Devices_Properties", feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] +pub trait IMFVirtualCamera_Impl: IMFAttributes_Impl { + fn AddDeviceSourceInfo(&self, devicesourceinfo: &windows_core::PCWSTR) -> windows_core::Result<()>; + fn AddProperty(&self, pkey: *const super::super::Foundation::DEVPROPKEY, r#type: super::super::Devices::Properties::DEVPROPTYPE, pbdata: *const u8, cbdata: u32) -> windows_core::Result<()>; + fn AddRegistryEntry(&self, entryname: &windows_core::PCWSTR, subkeypath: &windows_core::PCWSTR, dwregtype: u32, pbdata: *const u8, cbdata: u32) -> windows_core::Result<()>; + fn Start(&self, pcallback: windows_core::Ref<'_, IMFAsyncCallback>) -> windows_core::Result<()>; + fn Stop(&self) -> windows_core::Result<()>; + fn Remove(&self) -> windows_core::Result<()>; + fn GetMediaSource(&self) -> windows_core::Result; + fn SendCameraProperty(&self, propertyset: *const windows_core::GUID, propertyid: u32, propertyflags: u32, propertypayload: *mut core::ffi::c_void, propertypayloadlength: u32, data: *mut core::ffi::c_void, datalength: u32, datawritten: *mut u32) -> windows_core::Result<()>; + fn CreateSyncEvent(&self, kseventset: *const windows_core::GUID, kseventid: u32, kseventflags: u32, eventhandle: super::super::Foundation::HANDLE) -> windows_core::Result; + fn CreateSyncSemaphore(&self, kseventset: *const windows_core::GUID, kseventid: u32, kseventflags: u32, semaphorehandle: super::super::Foundation::HANDLE, semaphoreadjustment: i32) -> windows_core::Result; + fn Shutdown(&self) -> windows_core::Result<()>; +} +#[cfg(all(feature = "Win32_Devices_Properties", feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] +impl IMFVirtualCamera_Vtbl { + pub const fn new() -> Self { + unsafe extern "system" fn AddDeviceSourceInfo(this: *mut core::ffi::c_void, devicesourceinfo: windows_core::PCWSTR) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFVirtualCamera_Impl::AddDeviceSourceInfo(this, core::mem::transmute(&devicesourceinfo)).into() + } + } + unsafe extern "system" fn AddProperty(this: *mut core::ffi::c_void, pkey: *const super::super::Foundation::DEVPROPKEY, r#type: super::super::Devices::Properties::DEVPROPTYPE, pbdata: *const u8, cbdata: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFVirtualCamera_Impl::AddProperty(this, core::mem::transmute_copy(&pkey), core::mem::transmute_copy(&r#type), core::mem::transmute_copy(&pbdata), core::mem::transmute_copy(&cbdata)).into() + } + } + unsafe extern "system" fn AddRegistryEntry(this: *mut core::ffi::c_void, entryname: windows_core::PCWSTR, subkeypath: windows_core::PCWSTR, dwregtype: u32, pbdata: *const u8, cbdata: u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFVirtualCamera_Impl::AddRegistryEntry(this, core::mem::transmute(&entryname), core::mem::transmute(&subkeypath), core::mem::transmute_copy(&dwregtype), core::mem::transmute_copy(&pbdata), core::mem::transmute_copy(&cbdata)).into() + } + } + unsafe extern "system" fn Start(this: *mut core::ffi::c_void, pcallback: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFVirtualCamera_Impl::Start(this, core::mem::transmute_copy(&pcallback)).into() + } + } + unsafe extern "system" fn Stop(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFVirtualCamera_Impl::Stop(this).into() + } + } + unsafe extern "system" fn Remove(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFVirtualCamera_Impl::Remove(this).into() + } + } + unsafe extern "system" fn GetMediaSource(this: *mut core::ffi::c_void, ppmediasource: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMFVirtualCamera_Impl::GetMediaSource(this) { + Ok(ok__) => { + ppmediasource.write(core::mem::transmute(ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn SendCameraProperty(this: *mut core::ffi::c_void, propertyset: *const windows_core::GUID, propertyid: u32, propertyflags: u32, propertypayload: *mut core::ffi::c_void, propertypayloadlength: u32, data: *mut core::ffi::c_void, datalength: u32, datawritten: *mut u32) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFVirtualCamera_Impl::SendCameraProperty(this, core::mem::transmute_copy(&propertyset), core::mem::transmute_copy(&propertyid), core::mem::transmute_copy(&propertyflags), core::mem::transmute_copy(&propertypayload), core::mem::transmute_copy(&propertypayloadlength), core::mem::transmute_copy(&data), core::mem::transmute_copy(&datalength), core::mem::transmute_copy(&datawritten)).into() + } + } + unsafe extern "system" fn CreateSyncEvent(this: *mut core::ffi::c_void, kseventset: *const windows_core::GUID, kseventid: u32, kseventflags: u32, eventhandle: super::super::Foundation::HANDLE, camerasyncobject: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMFVirtualCamera_Impl::CreateSyncEvent(this, core::mem::transmute_copy(&kseventset), core::mem::transmute_copy(&kseventid), core::mem::transmute_copy(&kseventflags), core::mem::transmute_copy(&eventhandle)) { + Ok(ok__) => { + camerasyncobject.write(core::mem::transmute(ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn CreateSyncSemaphore(this: *mut core::ffi::c_void, kseventset: *const windows_core::GUID, kseventid: u32, kseventflags: u32, semaphorehandle: super::super::Foundation::HANDLE, semaphoreadjustment: i32, camerasyncobject: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + match IMFVirtualCamera_Impl::CreateSyncSemaphore(this, core::mem::transmute_copy(&kseventset), core::mem::transmute_copy(&kseventid), core::mem::transmute_copy(&kseventflags), core::mem::transmute_copy(&semaphorehandle), core::mem::transmute_copy(&semaphoreadjustment)) { + Ok(ok__) => { + camerasyncobject.write(core::mem::transmute(ok__)); + windows_core::HRESULT(0) + } + Err(err) => err.into(), + } + } + } + unsafe extern "system" fn Shutdown(this: *mut core::ffi::c_void) -> windows_core::HRESULT { + unsafe { + let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); + IMFVirtualCamera_Impl::Shutdown(this).into() + } + } + Self { + base__: IMFAttributes_Vtbl::new::(), + AddDeviceSourceInfo: AddDeviceSourceInfo::, + AddProperty: AddProperty::, + AddRegistryEntry: AddRegistryEntry::, + Start: Start::, + Stop: Stop::, + Remove: Remove::, + GetMediaSource: GetMediaSource::, + SendCameraProperty: SendCameraProperty::, + CreateSyncEvent: CreateSyncEvent::, + CreateSyncSemaphore: CreateSyncSemaphore::, + Shutdown: Shutdown::, + } + } + pub fn matches(iid: &windows_core::GUID) -> bool { + iid == &::IID || iid == &::IID + } +} +#[cfg(all(feature = "Win32_Devices_Properties", feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] +impl windows_core::RuntimeName for IMFVirtualCamera {} #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct MEDIA_EVENT_GENERATOR_GET_EVENT_FLAGS(pub u32); @@ -42471,7 +132615,9 @@ pub struct MFAYUVSample { pub bYValue: u8, pub bSampleAlpha8: u8, } +pub const MFAudioFormat_AAC: windows_core::GUID = windows_core::GUID::from_u128(0x00001610_0000_0010_8000_00aa00389b71); pub const MFAudioFormat_Float: windows_core::GUID = windows_core::GUID::from_u128(0x00000003_0000_0010_8000_00aa00389b71); +pub const MFAudioFormat_PCM: windows_core::GUID = windows_core::GUID::from_u128(0x00000001_0000_0010_8000_00aa00389b71); #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct MFBYTESTREAM_SEEK_ORIGIN(pub i32); @@ -42534,6 +132680,9 @@ pub const MFSTARTUP_FULL: u32 = 0u32; #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct MFSTREAMSINK_MARKER_TYPE(pub i32); +pub const MFT_CATEGORY_VIDEO_ENCODER: windows_core::GUID = windows_core::GUID::from_u128(0xf79eac7d_e545_4387_bdee_d647d7bde42a); +pub const MFT_ENUM_HARDWARE_URL_Attribute: windows_core::GUID = windows_core::GUID::from_u128(0x2fb866ac_b078_4942_ab6c_003d05cda674); +pub const MFT_FRIENDLY_NAME_Attribute: windows_core::GUID = windows_core::GUID::from_u128(0x314ffbae_5b41_4c95_9c19_4e7d586face3); #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq)] pub struct MFT_INPUT_STREAM_INFO { @@ -42561,6 +132710,7 @@ pub struct MFT_OUTPUT_STREAM_INFO { pub cbSize: u32, pub cbAlignment: u32, } +pub const MFTranscodeContainerType_MPEG4: windows_core::GUID = windows_core::GUID::from_u128(0xdc6cd05d_b9d0_40ef_bd35_fa622c1ab28a); #[repr(C)] #[derive(Clone, Copy)] pub struct MFVIDEOFORMAT { @@ -42595,6 +132745,8 @@ pub struct MFVideoCompressedInfo { pub AvgBitErrorRate: i64, pub MaxKeyFrameSpacing: u32, } +pub const MFVideoFormat_H264: windows_core::GUID = windows_core::GUID::from_u128(0x34363248_0000_0010_8000_00aa00389b71); +pub const MFVideoFormat_HEVC: windows_core::GUID = windows_core::GUID::from_u128(0x43564548_0000_0010_8000_00aa00389b71); pub const MFVideoFormat_MJPG: windows_core::GUID = windows_core::GUID::from_u128(0x47504a4d_0000_0010_8000_00aa00389b71); pub const MFVideoFormat_NV12: windows_core::GUID = windows_core::GUID::from_u128(0x3231564e_0000_0010_8000_00aa00389b71); pub const MFVideoFormat_RGB24: windows_core::GUID = windows_core::GUID::from_u128(0x00000014_0000_0010_8000_00aa00389b71); @@ -42621,6 +132773,7 @@ pub struct MFVideoInfo { #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct MFVideoInterlaceMode(pub i32); +pub const MFVideoInterlace_Progressive: MFVideoInterlaceMode = MFVideoInterlaceMode(2i32); #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct MFVideoLighting(pub i32); @@ -42663,6 +132816,7 @@ pub struct MF_ATTRIBUTES_MATCH_TYPE(pub i32); #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct MF_ATTRIBUTE_TYPE(pub i32); +pub const MF_BYTESTREAM_CONTENT_TYPE: windows_core::GUID = windows_core::GUID::from_u128(0xfc358289_3cb6_460c_a424_b6681260375a); #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct MF_CAMERA_CONTROL_CONFIGURATION_TYPE(pub i32); @@ -42721,23 +132875,50 @@ pub struct MF_MSE_ERROR(pub i32); #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct MF_MSE_READY(pub i32); +pub const MF_MT_ALL_SAMPLES_INDEPENDENT: windows_core::GUID = windows_core::GUID::from_u128(0xc9173739_5e56_461c_b713_46fb995cb95f); pub const MF_MT_AUDIO_AVG_BYTES_PER_SECOND: windows_core::GUID = windows_core::GUID::from_u128(0x1aab75c8_cfef_451c_ab95_ac034b8e1731); pub const MF_MT_AUDIO_BITS_PER_SAMPLE: windows_core::GUID = windows_core::GUID::from_u128(0xf2deb57f_40fa_4764_aa33_ed4f2d1ff669); pub const MF_MT_AUDIO_BLOCK_ALIGNMENT: windows_core::GUID = windows_core::GUID::from_u128(0x322de230_9eeb_43bd_ab7a_ff412251541d); pub const MF_MT_AUDIO_NUM_CHANNELS: windows_core::GUID = windows_core::GUID::from_u128(0x37e48bf5_645e_4c5b_89de_ada9e29b696a); pub const MF_MT_AUDIO_SAMPLES_PER_SECOND: windows_core::GUID = windows_core::GUID::from_u128(0x5faeeae7_0290_4c31_9e8a_c534f68d9dba); +pub const MF_MT_AVG_BITRATE: windows_core::GUID = windows_core::GUID::from_u128(0x20332624_fb0d_4d9e_bd0d_cbf6786c102e); +pub const MF_MT_DEFAULT_STRIDE: windows_core::GUID = windows_core::GUID::from_u128(0x644b4e48_1e02_4516_b0eb_c01ca9d49ac6); pub const MF_MT_FRAME_RATE: windows_core::GUID = windows_core::GUID::from_u128(0xc459a2e8_3d2c_4e44_b132_fee5156c7bb0); pub const MF_MT_FRAME_SIZE: windows_core::GUID = windows_core::GUID::from_u128(0x1652c33d_d6b2_4012_b834_72030849a37d); pub const MF_MT_INTERLACE_MODE: windows_core::GUID = windows_core::GUID::from_u128(0xe2724bb8_e676_4806_b4b2_a8d6efb44ccd); pub const MF_MT_MAJOR_TYPE: windows_core::GUID = windows_core::GUID::from_u128(0x48eba18e_f8c9_4687_bf11_0a74c9f96a8f); +pub const MF_MT_MINIMUM_DISPLAY_APERTURE: windows_core::GUID = windows_core::GUID::from_u128(0xd7388766_18fe_48c6_a177_ee894867c8c4); pub const MF_MT_PIXEL_ASPECT_RATIO: windows_core::GUID = windows_core::GUID::from_u128(0xc6376a1e_8d0a_4027_be45_6d9a0ad39bb6); pub const MF_MT_SUBTYPE: windows_core::GUID = windows_core::GUID::from_u128(0xf7e34c9a_42e8_4714_b74b_cb29d72c35e5); pub const MF_MT_VIDEO_NOMINAL_RANGE: windows_core::GUID = windows_core::GUID::from_u128(0xc21b8ee5_b956_4071_8daf_325edf5cab11); +pub const MF_MT_VIDEO_PROFILE: windows_core::GUID = windows_core::GUID::from_u128(0xad76a80b_2d5c_4e0b_b375_64e520137036); pub const MF_MT_YUV_MATRIX: windows_core::GUID = windows_core::GUID::from_u128(0x3e23d450_2c75_4d25_a00e_b91670d12327); pub const MF_PD_DURATION: windows_core::GUID = windows_core::GUID::from_u128(0x6c990d33_bb8e_477a_8598_0d5d96fcd88a); pub const MF_READWRITE_DISABLE_CONVERTERS: windows_core::GUID = windows_core::GUID::from_u128(0x98d5b065_1374_4847_8d5d_31520fee7156); pub const MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS: windows_core::GUID = windows_core::GUID::from_u128(0xa634a91c_822b_41b9_a494_4de4643612b0); pub const MF_SA_D3D11_BINDFLAGS: windows_core::GUID = windows_core::GUID::from_u128(0xeacf97ad_065c_4408_bee3_fdcbfd128be2); +pub const MF_SINK_WRITER_DISABLE_THROTTLING: windows_core::GUID = windows_core::GUID::from_u128(0x08b845d8_2b74_4afe_9d53_be16d2d5ae4f); +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct MF_SINK_WRITER_STATISTICS { + pub cb: u32, + pub llLastTimestampReceived: i64, + pub llLastTimestampEncoded: i64, + pub llLastTimestampProcessed: i64, + pub llLastStreamTickReceived: i64, + pub llLastSinkSampleRequest: i64, + pub qwNumSamplesReceived: u64, + pub qwNumSamplesEncoded: u64, + pub qwNumSamplesProcessed: u64, + pub qwNumStreamTicksReceived: u64, + pub dwByteCountQueued: u32, + pub qwByteCountProcessed: u64, + pub dwNumOutstandingSinkSampleRequests: u32, + pub dwAverageSampleRateReceived: u32, + pub dwAverageSampleRateEncoded: u32, + pub dwAverageSampleRateProcessed: u32, +} +pub const MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED: MF_SOURCE_READER_FLAG = MF_SOURCE_READER_FLAG(32i32); pub const MF_SOURCE_READERF_ENDOFSTREAM: MF_SOURCE_READER_FLAG = MF_SOURCE_READER_FLAG(2i32); pub const MF_SOURCE_READERF_STREAMTICK: MF_SOURCE_READER_FLAG = MF_SOURCE_READER_FLAG(256i32); pub const MF_SOURCE_READER_ALL_STREAMS: MF_SOURCE_READER_CONSTANTS = MF_SOURCE_READER_CONSTANTS(-2i32); @@ -42748,6 +132929,7 @@ pub struct MF_SOURCE_READER_CONSTANTS(pub i32); pub const MF_SOURCE_READER_D3D11_BIND_FLAGS: windows_core::GUID = windows_core::GUID::from_u128(0x33f3197b_f73a_4e14_8d85_0e4c4368788d); pub const MF_SOURCE_READER_D3D_MANAGER: windows_core::GUID = windows_core::GUID::from_u128(0xec822da2_e1e9_4b29_a0d8_563c719f5269); pub const MF_SOURCE_READER_DISABLE_DXVA: windows_core::GUID = windows_core::GUID::from_u128(0xaa456cfd_3943_4a1e_a77d_1838c0ea2e35); +pub const MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING: windows_core::GUID = windows_core::GUID::from_u128(0x0f81da2c_b537_4672_a8b2_a681b17307a3); pub const MF_SOURCE_READER_FIRST_AUDIO_STREAM: MF_SOURCE_READER_CONSTANTS = MF_SOURCE_READER_CONSTANTS(-3i32); pub const MF_SOURCE_READER_FIRST_VIDEO_STREAM: MF_SOURCE_READER_CONSTANTS = MF_SOURCE_READER_CONSTANTS(-4i32); #[repr(transparent)] @@ -42793,408 +132975,8 @@ pub struct MF_STREAM_STATE(pub i32); #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct MF_TOPOLOGY_TYPE(pub i32); -pub const MF_VERSION: u32 = 131184u32; -#[inline] -pub unsafe fn MFCreateMemoryBuffer(cbmaxlength: u32) -> windows_core::Result { - windows_core::link!("mfplat.dll" "system" fn MFCreateMemoryBuffer(cbmaxlength : u32, ppbuffer : *mut * mut core::ffi::c_void) -> windows_core::HRESULT); - unsafe { - let mut result__ = core::mem::zeroed(); - MFCreateMemoryBuffer(cbmaxlength, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) - } -} -#[inline] -pub unsafe fn MFCreateSample() -> windows_core::Result { - windows_core::link!("mfplat.dll" "system" fn MFCreateSample(ppimfsample : *mut * mut core::ffi::c_void) -> windows_core::HRESULT); - unsafe { - let mut result__ = core::mem::zeroed(); - MFCreateSample(&mut result__).and_then(|| windows_core::Type::from_abi(result__)) - } -} -#[inline] -pub unsafe fn MFCreateSinkWriterFromURL(pwszoutputurl: P0, pbytestream: P1, pattributes: P2) -> windows_core::Result -where - P0: windows_core::Param, - P1: windows_core::Param, - P2: windows_core::Param, -{ - windows_core::link!("mfreadwrite.dll" "system" fn MFCreateSinkWriterFromURL(pwszoutputurl : windows_core::PCWSTR, pbytestream : * mut core::ffi::c_void, pattributes : * mut core::ffi::c_void, ppsinkwriter : *mut * mut core::ffi::c_void) -> windows_core::HRESULT); - unsafe { - let mut result__ = core::mem::zeroed(); - MFCreateSinkWriterFromURL(pwszoutputurl.param().abi(), pbytestream.param().abi(), pattributes.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) - } -} -impl IMFASFStreamPrioritization { - pub unsafe fn AddStream(&self, wstreamnumber: u16, wstreamflags: u16) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).AddStream)(windows_core::Interface::as_raw(self), wstreamnumber, wstreamflags).ok() } - } - } -pub const CODECAPI_AVEncMPVGOPSize: windows_core::GUID = windows_core::GUID::from_u128(0x95f31b26_95a4_41aa_9303_246a7fc6eef1); -windows_core::imp::define_interface!(ICodecAPI, ICodecAPI_Vtbl, 0x901db4c7_31ce_41a2_85dc_8fa0bf41b8da); -windows_core::imp::interface_hierarchy!(ICodecAPI, windows_core::IUnknown); -impl ICodecAPI { - pub unsafe fn IsSupported(&self, api: *const windows_core::GUID) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).IsSupported)(windows_core::Interface::as_raw(self), api).ok() } - } - pub unsafe fn IsModifiable(&self, api: *const windows_core::GUID) -> windows_core::HRESULT { - unsafe { (windows_core::Interface::vtable(self).IsModifiable)(windows_core::Interface::as_raw(self), api) } - } - #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] - pub unsafe fn GetParameterRange(&self, api: *const windows_core::GUID, valuemin: *mut super::super::System::Variant::VARIANT, valuemax: *mut super::super::System::Variant::VARIANT, steppingdelta: *mut super::super::System::Variant::VARIANT) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).GetParameterRange)(windows_core::Interface::as_raw(self), api, core::mem::transmute(valuemin), core::mem::transmute(valuemax), core::mem::transmute(steppingdelta)).ok() } - } - #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] - pub unsafe fn GetParameterValues(&self, api: *const windows_core::GUID, values: *mut *mut super::super::System::Variant::VARIANT, valuescount: *mut u32) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).GetParameterValues)(windows_core::Interface::as_raw(self), api, values as _, valuescount as _).ok() } - } - #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] - pub unsafe fn GetDefaultValue(&self, api: *const windows_core::GUID) -> windows_core::Result { - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(self).GetDefaultValue)(windows_core::Interface::as_raw(self), api, &mut result__).map(|| core::mem::transmute(result__)) - } - } - #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] - pub unsafe fn GetValue(&self, api: *const windows_core::GUID) -> windows_core::Result { - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(self).GetValue)(windows_core::Interface::as_raw(self), api, &mut result__).map(|| core::mem::transmute(result__)) - } - } - #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] - pub unsafe fn SetValue(&self, api: *const windows_core::GUID, value: *const super::super::System::Variant::VARIANT) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).SetValue)(windows_core::Interface::as_raw(self), api, core::mem::transmute(value)).ok() } - } - pub unsafe fn RegisterForEvent(&self, api: *const windows_core::GUID, userdata: isize) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).RegisterForEvent)(windows_core::Interface::as_raw(self), api, userdata).ok() } - } - pub unsafe fn UnregisterForEvent(&self, api: *const windows_core::GUID) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).UnregisterForEvent)(windows_core::Interface::as_raw(self), api).ok() } - } - pub unsafe fn SetAllDefaults(&self) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).SetAllDefaults)(windows_core::Interface::as_raw(self)).ok() } - } - #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] - pub unsafe fn SetValueWithNotify(&self, api: *const windows_core::GUID, value: *const super::super::System::Variant::VARIANT, changedparam: *mut *mut windows_core::GUID, changedparamcount: *mut u32) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).SetValueWithNotify)(windows_core::Interface::as_raw(self), api, core::mem::transmute(value), changedparam as _, changedparamcount as _).ok() } - } - pub unsafe fn SetAllDefaultsWithNotify(&self, changedparam: *mut *mut windows_core::GUID, changedparamcount: *mut u32) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).SetAllDefaultsWithNotify)(windows_core::Interface::as_raw(self), changedparam as _, changedparamcount as _).ok() } - } - #[cfg(feature = "Win32_System_Com")] - pub unsafe fn GetAllSettings(&self, __midl__icodecapi0000: P0) -> windows_core::Result<()> - where - P0: windows_core::Param, - { - unsafe { (windows_core::Interface::vtable(self).GetAllSettings)(windows_core::Interface::as_raw(self), __midl__icodecapi0000.param().abi()).ok() } - } - #[cfg(feature = "Win32_System_Com")] - pub unsafe fn SetAllSettings(&self, __midl__icodecapi0001: P0) -> windows_core::Result<()> - where - P0: windows_core::Param, - { - unsafe { (windows_core::Interface::vtable(self).SetAllSettings)(windows_core::Interface::as_raw(self), __midl__icodecapi0001.param().abi()).ok() } - } - #[cfg(feature = "Win32_System_Com")] - pub unsafe fn SetAllSettingsWithNotify(&self, __midl__icodecapi0002: P0, changedparam: *mut *mut windows_core::GUID, changedparamcount: *mut u32) -> windows_core::Result<()> - where - P0: windows_core::Param, - { - unsafe { (windows_core::Interface::vtable(self).SetAllSettingsWithNotify)(windows_core::Interface::as_raw(self), __midl__icodecapi0002.param().abi(), changedparam as _, changedparamcount as _).ok() } - } -} -#[repr(C)] -#[doc(hidden)] -pub struct ICodecAPI_Vtbl { - pub base__: windows_core::IUnknown_Vtbl, - pub IsSupported: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID) -> windows_core::HRESULT, - pub IsModifiable: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID) -> windows_core::HRESULT, - #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] - pub GetParameterRange: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, *mut super::super::System::Variant::VARIANT, *mut super::super::System::Variant::VARIANT, *mut super::super::System::Variant::VARIANT) -> windows_core::HRESULT, - #[cfg(not(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant")))] - GetParameterRange: usize, - #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] - pub GetParameterValues: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, *mut *mut super::super::System::Variant::VARIANT, *mut u32) -> windows_core::HRESULT, - #[cfg(not(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant")))] - GetParameterValues: usize, - #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] - pub GetDefaultValue: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, *mut super::super::System::Variant::VARIANT) -> windows_core::HRESULT, - #[cfg(not(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant")))] - GetDefaultValue: usize, - #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] - pub GetValue: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, *mut super::super::System::Variant::VARIANT) -> windows_core::HRESULT, - #[cfg(not(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant")))] - GetValue: usize, - #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] - pub SetValue: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, *const super::super::System::Variant::VARIANT) -> windows_core::HRESULT, - #[cfg(not(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant")))] - SetValue: usize, - pub RegisterForEvent: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, isize) -> windows_core::HRESULT, - pub UnregisterForEvent: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID) -> windows_core::HRESULT, - pub SetAllDefaults: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, - #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] - pub SetValueWithNotify: unsafe extern "system" fn(*mut core::ffi::c_void, *const windows_core::GUID, *const super::super::System::Variant::VARIANT, *mut *mut windows_core::GUID, *mut u32) -> windows_core::HRESULT, - #[cfg(not(all(feature = "Win32_System_Com", feature = "Win32_System_Ole", feature = "Win32_System_Variant")))] - SetValueWithNotify: usize, - pub SetAllDefaultsWithNotify: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut windows_core::GUID, *mut u32) -> windows_core::HRESULT, - #[cfg(feature = "Win32_System_Com")] - pub GetAllSettings: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, - #[cfg(not(feature = "Win32_System_Com"))] - GetAllSettings: usize, - #[cfg(feature = "Win32_System_Com")] - pub SetAllSettings: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, - #[cfg(not(feature = "Win32_System_Com"))] - SetAllSettings: usize, - #[cfg(feature = "Win32_System_Com")] - pub SetAllSettingsWithNotify: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut *mut windows_core::GUID, *mut u32) -> windows_core::HRESULT, - #[cfg(not(feature = "Win32_System_Com"))] - SetAllSettingsWithNotify: usize, -} -windows_core::imp::define_interface!(IMFSinkWriter, IMFSinkWriter_Vtbl, 0x3137f1cd_fe5e_4805_a5d8_fb477448cb3d); -windows_core::imp::interface_hierarchy!(IMFSinkWriter, windows_core::IUnknown); -impl IMFSinkWriter { - pub unsafe fn GetServiceForStream(&self, dwstreamindex: u32, guidservice: *const windows_core::GUID, riid: *const windows_core::GUID, ppvobject: *mut *mut core::ffi::c_void) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).GetServiceForStream)(windows_core::Interface::as_raw(self), dwstreamindex, guidservice, riid, ppvobject as _).ok() } - } - pub unsafe fn AddStream(&self, ptargetmediatype: P0) -> windows_core::Result - where - P0: windows_core::Param, - { - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(self).AddStream)(windows_core::Interface::as_raw(self), ptargetmediatype.param().abi(), &mut result__).map(|| result__) - } - } - pub unsafe fn SetInputMediaType(&self, dwstreamindex: u32, pinputmediatype: P1, pencodingparameters: P2) -> windows_core::Result<()> - where - P1: windows_core::Param, - P2: windows_core::Param, - { - unsafe { (windows_core::Interface::vtable(self).SetInputMediaType)(windows_core::Interface::as_raw(self), dwstreamindex, pinputmediatype.param().abi(), pencodingparameters.param().abi()).ok() } - } - pub unsafe fn BeginWriting(&self) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).BeginWriting)(windows_core::Interface::as_raw(self)).ok() } - } - pub unsafe fn WriteSample(&self, dwstreamindex: u32, psample: P1) -> windows_core::Result<()> - where - P1: windows_core::Param, - { - unsafe { (windows_core::Interface::vtable(self).WriteSample)(windows_core::Interface::as_raw(self), dwstreamindex, psample.param().abi()).ok() } - } - pub unsafe fn Finalize(&self) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).Finalize)(windows_core::Interface::as_raw(self)).ok() } - } - } -#[repr(C)] -#[doc(hidden)] -pub struct IMFSinkWriter_Vtbl { - pub base__: windows_core::IUnknown_Vtbl, - pub AddStream: unsafe extern "system" fn(*mut core::ffi::c_void, *mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, - pub SetInputMediaType: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *mut core::ffi::c_void, *mut core::ffi::c_void) -> windows_core::HRESULT, - pub BeginWriting: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, - pub WriteSample: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *mut core::ffi::c_void) -> windows_core::HRESULT, - pub SendStreamTick: unsafe extern "system" fn(*mut core::ffi::c_void, u32, i64) -> windows_core::HRESULT, - pub PlaceMarker: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const core::ffi::c_void) -> windows_core::HRESULT, - pub NotifyEndOfSegment: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, - pub Flush: unsafe extern "system" fn(*mut core::ffi::c_void, u32) -> windows_core::HRESULT, - pub Finalize: unsafe extern "system" fn(*mut core::ffi::c_void) -> windows_core::HRESULT, - pub GetServiceForStream: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *const windows_core::GUID, *const windows_core::GUID, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, - pub GetStatistics: unsafe extern "system" fn(*mut core::ffi::c_void, u32, *mut MF_SINK_WRITER_STATISTICS) -> windows_core::HRESULT, -} -pub trait IMFSinkWriter_Impl: windows_core::IUnknownImpl { - fn AddStream(&self, ptargetmediatype: windows_core::Ref) -> windows_core::Result; - fn SetInputMediaType(&self, dwstreamindex: u32, pinputmediatype: windows_core::Ref, pencodingparameters: windows_core::Ref) -> windows_core::Result<()>; - fn BeginWriting(&self) -> windows_core::Result<()>; - fn WriteSample(&self, dwstreamindex: u32, psample: windows_core::Ref) -> windows_core::Result<()>; - fn SendStreamTick(&self, dwstreamindex: u32, lltimestamp: i64) -> windows_core::Result<()>; - fn PlaceMarker(&self, dwstreamindex: u32, pvcontext: *const core::ffi::c_void) -> windows_core::Result<()>; - fn NotifyEndOfSegment(&self, dwstreamindex: u32) -> windows_core::Result<()>; - fn Flush(&self, dwstreamindex: u32) -> windows_core::Result<()>; - fn Finalize(&self) -> windows_core::Result<()>; - fn GetServiceForStream(&self, dwstreamindex: u32, guidservice: *const windows_core::GUID, riid: *const windows_core::GUID, ppvobject: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; - fn GetStatistics(&self, dwstreamindex: u32, pstats: *mut MF_SINK_WRITER_STATISTICS) -> windows_core::Result<()>; -} -impl IMFSinkWriter_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn AddStream(this: *mut core::ffi::c_void, ptargetmediatype: *mut core::ffi::c_void, pdwstreamindex: *mut u32) -> windows_core::HRESULT { - unsafe { - let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); - match IMFSinkWriter_Impl::AddStream(this, core::mem::transmute_copy(&ptargetmediatype)) { - Ok(ok__) => { - pdwstreamindex.write(core::mem::transmute(ok__)); - windows_core::HRESULT(0) - } - Err(err) => err.into(), - } - } - } - unsafe extern "system" fn SetInputMediaType(this: *mut core::ffi::c_void, dwstreamindex: u32, pinputmediatype: *mut core::ffi::c_void, pencodingparameters: *mut core::ffi::c_void) -> windows_core::HRESULT { - unsafe { - let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IMFSinkWriter_Impl::SetInputMediaType(this, core::mem::transmute_copy(&dwstreamindex), core::mem::transmute_copy(&pinputmediatype), core::mem::transmute_copy(&pencodingparameters)).into() - } - } - unsafe extern "system" fn BeginWriting(this: *mut core::ffi::c_void) -> windows_core::HRESULT { - unsafe { - let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IMFSinkWriter_Impl::BeginWriting(this).into() - } - } - unsafe extern "system" fn WriteSample(this: *mut core::ffi::c_void, dwstreamindex: u32, psample: *mut core::ffi::c_void) -> windows_core::HRESULT { - unsafe { - let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IMFSinkWriter_Impl::WriteSample(this, core::mem::transmute_copy(&dwstreamindex), core::mem::transmute_copy(&psample)).into() - } - } - unsafe extern "system" fn SendStreamTick(this: *mut core::ffi::c_void, dwstreamindex: u32, lltimestamp: i64) -> windows_core::HRESULT { - unsafe { - let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IMFSinkWriter_Impl::SendStreamTick(this, core::mem::transmute_copy(&dwstreamindex), core::mem::transmute_copy(&lltimestamp)).into() - } - } - unsafe extern "system" fn PlaceMarker(this: *mut core::ffi::c_void, dwstreamindex: u32, pvcontext: *const core::ffi::c_void) -> windows_core::HRESULT { - unsafe { - let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IMFSinkWriter_Impl::PlaceMarker(this, core::mem::transmute_copy(&dwstreamindex), core::mem::transmute_copy(&pvcontext)).into() - } - } - unsafe extern "system" fn NotifyEndOfSegment(this: *mut core::ffi::c_void, dwstreamindex: u32) -> windows_core::HRESULT { - unsafe { - let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IMFSinkWriter_Impl::NotifyEndOfSegment(this, core::mem::transmute_copy(&dwstreamindex)).into() - } - } - unsafe extern "system" fn Flush(this: *mut core::ffi::c_void, dwstreamindex: u32) -> windows_core::HRESULT { - unsafe { - let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IMFSinkWriter_Impl::Flush(this, core::mem::transmute_copy(&dwstreamindex)).into() - } - } - unsafe extern "system" fn Finalize(this: *mut core::ffi::c_void) -> windows_core::HRESULT { - unsafe { - let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IMFSinkWriter_Impl::Finalize(this).into() - } - } - unsafe extern "system" fn GetServiceForStream(this: *mut core::ffi::c_void, dwstreamindex: u32, guidservice: *const windows_core::GUID, riid: *const windows_core::GUID, ppvobject: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { - unsafe { - let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IMFSinkWriter_Impl::GetServiceForStream(this, core::mem::transmute_copy(&dwstreamindex), core::mem::transmute_copy(&guidservice), core::mem::transmute_copy(&riid), core::mem::transmute_copy(&ppvobject)).into() - } - } - unsafe extern "system" fn GetStatistics(this: *mut core::ffi::c_void, dwstreamindex: u32, pstats: *mut MF_SINK_WRITER_STATISTICS) -> windows_core::HRESULT { - unsafe { - let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IMFSinkWriter_Impl::GetStatistics(this, core::mem::transmute_copy(&dwstreamindex), core::mem::transmute_copy(&pstats)).into() - } - } - Self { - base__: windows_core::IUnknown_Vtbl::new::(), - AddStream: AddStream::, - SetInputMediaType: SetInputMediaType::, - BeginWriting: BeginWriting::, - WriteSample: WriteSample::, - SendStreamTick: SendStreamTick::, - PlaceMarker: PlaceMarker::, - NotifyEndOfSegment: NotifyEndOfSegment::, - Flush: Flush::, - Finalize: Finalize::, - GetServiceForStream: GetServiceForStream::, - GetStatistics: GetStatistics::, - } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID - } -} -impl windows_core::RuntimeName for IMFSinkWriter {} -windows_core::imp::define_interface!(IMFSinkWriterEx, IMFSinkWriterEx_Vtbl, 0x588d72ab_5bc1_496a_8714_b70617141b25); -impl core::ops::Deref for IMFSinkWriterEx { - type Target = IMFSinkWriter; - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute(self) } - } -} -windows_core::imp::interface_hierarchy!(IMFSinkWriterEx, windows_core::IUnknown, IMFSinkWriter); -impl IMFSinkWriterEx { - pub unsafe fn GetTransformForStream(&self, dwstreamindex: u32, dwtransformindex: u32, pguidcategory: Option<*mut windows_core::GUID>, pptransform: *mut Option) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).GetTransformForStream)(windows_core::Interface::as_raw(self), dwstreamindex, dwtransformindex, pguidcategory.unwrap_or(core::mem::zeroed()) as _, core::mem::transmute(pptransform)).ok() } - } -} -#[repr(C)] -#[doc(hidden)] -pub struct IMFSinkWriterEx_Vtbl { - pub base__: IMFSinkWriter_Vtbl, - pub GetTransformForStream: unsafe extern "system" fn(*mut core::ffi::c_void, u32, u32, *mut windows_core::GUID, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, -} -pub trait IMFSinkWriterEx_Impl: IMFSinkWriter_Impl { - fn GetTransformForStream(&self, dwstreamindex: u32, dwtransformindex: u32, pguidcategory: *mut windows_core::GUID, pptransform: windows_core::OutRef) -> windows_core::Result<()>; -} -impl IMFSinkWriterEx_Vtbl { - pub const fn new() -> Self { - unsafe extern "system" fn GetTransformForStream(this: *mut core::ffi::c_void, dwstreamindex: u32, dwtransformindex: u32, pguidcategory: *mut windows_core::GUID, pptransform: *mut *mut core::ffi::c_void) -> windows_core::HRESULT { - unsafe { - let this: &Identity = &*((this as *const *const ()).offset(OFFSET) as *const Identity); - IMFSinkWriterEx_Impl::GetTransformForStream(this, core::mem::transmute_copy(&dwstreamindex), core::mem::transmute_copy(&dwtransformindex), core::mem::transmute_copy(&pguidcategory), core::mem::transmute_copy(&pptransform)).into() - } - } - Self { base__: IMFSinkWriter_Vtbl::new::(), GetTransformForStream: GetTransformForStream:: } - } - pub fn matches(iid: &windows_core::GUID) -> bool { - iid == &::IID || iid == &::IID - } -} -impl windows_core::RuntimeName for IMFSinkWriterEx {} -impl IMFSourceReaderEx { - pub unsafe fn GetTransformForStream(&self, dwstreamindex: u32, dwtransformindex: u32, pguidcategory: Option<*mut windows_core::GUID>, pptransform: *mut Option) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).GetTransformForStream)(windows_core::Interface::as_raw(self), dwstreamindex, dwtransformindex, pguidcategory.unwrap_or(core::mem::zeroed()) as _, core::mem::transmute(pptransform)).ok() } - } -} -impl IMFTransform { - pub unsafe fn GetAttributes(&self) -> windows_core::Result { - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(self).GetAttributes)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) - } - } - } -pub const MFAudioFormat_AAC: windows_core::GUID = windows_core::GUID::from_u128(0x00001610_0000_0010_8000_00aa00389b71); -pub const MFAudioFormat_PCM: windows_core::GUID = windows_core::GUID::from_u128(0x00000001_0000_0010_8000_00aa00389b71); -pub const MFT_CATEGORY_VIDEO_ENCODER: windows_core::GUID = windows_core::GUID::from_u128(0xf79eac7d_e545_4387_bdee_d647d7bde42a); -pub const MFT_ENUM_HARDWARE_URL_Attribute: windows_core::GUID = windows_core::GUID::from_u128(0x2fb866ac_b078_4942_ab6c_003d05cda674); -pub const MFT_FRIENDLY_NAME_Attribute: windows_core::GUID = windows_core::GUID::from_u128(0x314ffbae_5b41_4c95_9c19_4e7d586face3); -pub const MFTranscodeContainerType_MPEG4: windows_core::GUID = windows_core::GUID::from_u128(0xdc6cd05d_b9d0_40ef_bd35_fa622c1ab28a); -pub const MFVideoFormat_H264: windows_core::GUID = windows_core::GUID::from_u128(0x34363248_0000_0010_8000_00aa00389b71); -pub const MFVideoFormat_HEVC: windows_core::GUID = windows_core::GUID::from_u128(0x43564548_0000_0010_8000_00aa00389b71); -pub const MFVideoInterlace_Progressive: MFVideoInterlaceMode = MFVideoInterlaceMode(2i32); -pub const MF_MT_ALL_SAMPLES_INDEPENDENT: windows_core::GUID = windows_core::GUID::from_u128(0xc9173739_5e56_461c_b713_46fb995cb95f); -pub const MF_MT_AVG_BITRATE: windows_core::GUID = windows_core::GUID::from_u128(0x20332624_fb0d_4d9e_bd0d_cbf6786c102e); -pub const MF_MT_DEFAULT_STRIDE: windows_core::GUID = windows_core::GUID::from_u128(0x644b4e48_1e02_4516_b0eb_c01ca9d49ac6); -pub const MF_MT_MINIMUM_DISPLAY_APERTURE: windows_core::GUID = windows_core::GUID::from_u128(0xd7388766_18fe_48c6_a177_ee894867c8c4); -pub const MF_MT_VIDEO_PROFILE: windows_core::GUID = windows_core::GUID::from_u128(0xad76a80b_2d5c_4e0b_b375_64e520137036); -pub const MF_SINK_WRITER_DISABLE_THROTTLING: windows_core::GUID = windows_core::GUID::from_u128(0x08b845d8_2b74_4afe_9d53_be16d2d5ae4f); -#[repr(C)] -#[derive(Clone, Copy, Debug, Default, PartialEq)] -pub struct MF_SINK_WRITER_STATISTICS { - pub cb: u32, - pub llLastTimestampReceived: i64, - pub llLastTimestampEncoded: i64, - pub llLastTimestampProcessed: i64, - pub llLastStreamTickReceived: i64, - pub llLastSinkSampleRequest: i64, - pub qwNumSamplesReceived: u64, - pub qwNumSamplesEncoded: u64, - pub qwNumSamplesProcessed: u64, - pub qwNumStreamTicksReceived: u64, - pub dwByteCountQueued: u32, - pub qwByteCountProcessed: u64, - pub dwNumOutstandingSinkSampleRequests: u32, - pub dwAverageSampleRateReceived: u32, - pub dwAverageSampleRateEncoded: u32, - pub dwAverageSampleRateProcessed: u32, -} -pub const MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED: MF_SOURCE_READER_FLAG = MF_SOURCE_READER_FLAG(32i32); -pub const MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING: windows_core::GUID = windows_core::GUID::from_u128(0x0f81da2c_b537_4672_a8b2_a681b17307a3); pub const MF_TRANSCODE_CONTAINERTYPE: windows_core::GUID = windows_core::GUID::from_u128(0x150ff23f_4abc_478b_ac4f_e1916fba1cca); +pub const MF_VERSION: u32 = 131184u32; #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct eAVEncH264VProfile(pub i32); @@ -43203,41 +132985,13 @@ pub const eAVEncH264VProfile_Main: eAVEncH264VProfile = eAVEncH264VProfile(77i32 #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct eAVEncH265VProfile(pub i32); pub const eAVEncH265VProfile_Main_420_8: eAVEncH265VProfile = eAVEncH265VProfile(1i32); -impl IMFAttributes { - pub unsafe fn GetBlob(&self, guidkey: *const windows_core::GUID, pbuf: &mut [u8], pcbblobsize: Option<*mut u32>) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).GetBlob)(windows_core::Interface::as_raw(self), guidkey, core::mem::transmute(pbuf.as_ptr()), pbuf.len().try_into().unwrap(), pcbblobsize.unwrap_or(core::mem::zeroed()) as _).ok() } - } -} -impl IMFMediaBuffer { - pub unsafe fn SetCurrentLength(&self, cbcurrentlength: u32) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).SetCurrentLength)(windows_core::Interface::as_raw(self), cbcurrentlength).ok() } - } -} -impl IMFSample { - pub unsafe fn SetSampleTime(&self, hnssampletime: i64) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).SetSampleTime)(windows_core::Interface::as_raw(self), hnssampletime).ok() } - } - pub unsafe fn SetSampleDuration(&self, hnssampleduration: i64) -> windows_core::Result<()> { - unsafe { (windows_core::Interface::vtable(self).SetSampleDuration)(windows_core::Interface::as_raw(self), hnssampleduration).ok() } - } - pub unsafe fn ConvertToContiguousBuffer(&self) -> windows_core::Result { - unsafe { - let mut result__ = core::mem::zeroed(); - (windows_core::Interface::vtable(self).ConvertToContiguousBuffer)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) - } - } - pub unsafe fn AddBuffer(&self, pbuffer: P0) -> windows_core::Result<()> - where - P0: windows_core::Param, - { - unsafe { (windows_core::Interface::vtable(self).AddBuffer)(windows_core::Interface::as_raw(self), pbuffer.param().abi()).ok() } - } -} } +#[cfg(feature = "Win32_Media_Multimedia")] pub mod Multimedia{ pub const KSDATAFORMAT_SUBTYPE_IEEE_FLOAT: windows_core::GUID = windows_core::GUID::from_u128(0x00000003_0000_0010_8000_00aa00389b71); } } +#[cfg(feature = "Win32_Security")] pub mod Security{ #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq)] @@ -43252,7 +133006,9 @@ impl Default for SECURITY_ATTRIBUTES { } } } +#[cfg(feature = "Win32_System")] pub mod System{ +#[cfg(feature = "Win32_System_Com")] pub mod Com{ #[inline] pub unsafe fn CoCreateInstance(rclsid: *const windows_core::GUID, punkouter: P1, dwclscontext: CLSCTX) -> windows_core::Result @@ -43271,7 +133027,7 @@ pub unsafe fn CoInitializeEx(pvreserved: Option<*const core::ffi::c_void>, dwcoi } #[inline] pub unsafe fn CoTaskMemFree(pv: Option<*const core::ffi::c_void>) { - windows_core::link!("combase.dll" "system" fn CoTaskMemFree(pv : *const core::ffi::c_void)); + windows_core::link!("ole32.dll" "system" fn CoTaskMemFree(pv : *const core::ffi::c_void)); unsafe { CoTaskMemFree(pv.unwrap_or(core::mem::zeroed()) as _) } } #[inline] @@ -43587,7 +133343,7 @@ impl Default for ELEMDESC_0 { } } #[repr(C)] -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] pub struct EXCEPINFO { pub wCode: u16, pub wReserved: u16, @@ -43649,6 +133405,27 @@ pub struct FUNCFLAGS(pub u16); pub struct FUNCKIND(pub i32); windows_core::imp::define_interface!(IAdviseSink, IAdviseSink_Vtbl, 0x0000010f_0000_0000_c000_000000000046); windows_core::imp::interface_hierarchy!(IAdviseSink, windows_core::IUnknown); +impl IAdviseSink { + #[cfg(all(feature = "Win32_Graphics_Gdi", feature = "Win32_System_Com_StructuredStorage"))] + pub unsafe fn OnDataChange(&self, pformatetc: *const FORMATETC, pstgmed: *const STGMEDIUM) { + unsafe { (windows_core::Interface::vtable(self).OnDataChange)(windows_core::Interface::as_raw(self), pformatetc, core::mem::transmute(pstgmed)) } + } + pub unsafe fn OnViewChange(&self, dwaspect: u32, lindex: i32) { + unsafe { (windows_core::Interface::vtable(self).OnViewChange)(windows_core::Interface::as_raw(self), dwaspect, lindex) } + } + pub unsafe fn OnRename(&self, pmk: P0) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).OnRename)(windows_core::Interface::as_raw(self), pmk.param().abi()) } + } + pub unsafe fn OnSave(&self) { + unsafe { (windows_core::Interface::vtable(self).OnSave)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn OnClose(&self) { + unsafe { (windows_core::Interface::vtable(self).OnClose)(windows_core::Interface::as_raw(self)) } + } +} #[repr(C)] #[doc(hidden)] pub struct IAdviseSink_Vtbl { @@ -43666,7 +133443,7 @@ pub struct IAdviseSink_Vtbl { pub trait IAdviseSink_Impl: windows_core::IUnknownImpl { fn OnDataChange(&self, pformatetc: *const FORMATETC, pstgmed: *const STGMEDIUM); fn OnViewChange(&self, dwaspect: u32, lindex: i32); - fn OnRename(&self, pmk: windows_core::Ref); + fn OnRename(&self, pmk: windows_core::Ref<'_, IMoniker>); fn OnSave(&self); fn OnClose(&self); } @@ -43726,6 +133503,14 @@ impl core::ops::Deref for IAdviseSink2 { } } windows_core::imp::interface_hierarchy!(IAdviseSink2, windows_core::IUnknown, IAdviseSink); +impl IAdviseSink2 { + pub unsafe fn OnLinkSrcChange(&self, pmk: P0) + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).OnLinkSrcChange)(windows_core::Interface::as_raw(self), pmk.param().abi()) } + } +} #[repr(C)] #[doc(hidden)] pub struct IAdviseSink2_Vtbl { @@ -43734,7 +133519,7 @@ pub struct IAdviseSink2_Vtbl { } #[cfg(all(feature = "Win32_Graphics_Gdi", feature = "Win32_System_Com_StructuredStorage"))] pub trait IAdviseSink2_Impl: IAdviseSink_Impl { - fn OnLinkSrcChange(&self, pmk: windows_core::Ref); + fn OnLinkSrcChange(&self, pmk: windows_core::Ref<'_, IMoniker>); } #[cfg(all(feature = "Win32_Graphics_Gdi", feature = "Win32_System_Com_StructuredStorage"))] impl IAdviseSink2_Vtbl { @@ -43755,6 +133540,63 @@ impl IAdviseSink2_Vtbl { impl windows_core::RuntimeName for IAdviseSink2 {} windows_core::imp::define_interface!(IBindCtx, IBindCtx_Vtbl, 0x0000000e_0000_0000_c000_000000000046); windows_core::imp::interface_hierarchy!(IBindCtx, windows_core::IUnknown); +impl IBindCtx { + pub unsafe fn RegisterObjectBound(&self, punk: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).RegisterObjectBound)(windows_core::Interface::as_raw(self), punk.param().abi()).ok() } + } + pub unsafe fn RevokeObjectBound(&self, punk: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).RevokeObjectBound)(windows_core::Interface::as_raw(self), punk.param().abi()).ok() } + } + pub unsafe fn ReleaseBoundObjects(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).ReleaseBoundObjects)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn SetBindOptions(&self, pbindopts: *const BIND_OPTS) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetBindOptions)(windows_core::Interface::as_raw(self), pbindopts).ok() } + } + pub unsafe fn GetBindOptions(&self, pbindopts: *mut BIND_OPTS) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetBindOptions)(windows_core::Interface::as_raw(self), pbindopts as _).ok() } + } + pub unsafe fn GetRunningObjectTable(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetRunningObjectTable)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn RegisterObjectParam(&self, pszkey: P0, punk: P1) -> windows_core::Result<()> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).RegisterObjectParam)(windows_core::Interface::as_raw(self), pszkey.param().abi(), punk.param().abi()).ok() } + } + pub unsafe fn GetObjectParam(&self, pszkey: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetObjectParam)(windows_core::Interface::as_raw(self), pszkey.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn EnumObjectParam(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).EnumObjectParam)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn RevokeObjectParam(&self, pszkey: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).RevokeObjectParam)(windows_core::Interface::as_raw(self), pszkey.param().abi()).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IBindCtx_Vtbl { @@ -43771,13 +133613,13 @@ pub struct IBindCtx_Vtbl { pub RevokeObjectParam: unsafe extern "system" fn(*mut core::ffi::c_void, windows_core::PCWSTR) -> windows_core::HRESULT, } pub trait IBindCtx_Impl: windows_core::IUnknownImpl { - fn RegisterObjectBound(&self, punk: windows_core::Ref) -> windows_core::Result<()>; - fn RevokeObjectBound(&self, punk: windows_core::Ref) -> windows_core::Result<()>; + fn RegisterObjectBound(&self, punk: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; + fn RevokeObjectBound(&self, punk: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; fn ReleaseBoundObjects(&self) -> windows_core::Result<()>; fn SetBindOptions(&self, pbindopts: *const BIND_OPTS) -> windows_core::Result<()>; fn GetBindOptions(&self, pbindopts: *mut BIND_OPTS) -> windows_core::Result<()>; fn GetRunningObjectTable(&self) -> windows_core::Result; - fn RegisterObjectParam(&self, pszkey: &windows_core::PCWSTR, punk: windows_core::Ref) -> windows_core::Result<()>; + fn RegisterObjectParam(&self, pszkey: &windows_core::PCWSTR, punk: windows_core::Ref<'_, windows_core::IUnknown>) -> windows_core::Result<()>; fn GetObjectParam(&self, pszkey: &windows_core::PCWSTR) -> windows_core::Result; fn EnumObjectParam(&self) -> windows_core::Result; fn RevokeObjectParam(&self, pszkey: &windows_core::PCWSTR) -> windows_core::Result<()>; @@ -43933,13 +133775,45 @@ impl IDataObject { (windows_core::Interface::vtable(self).GetData)(windows_core::Interface::as_raw(self), pformatetcin, &mut result__).map(|| core::mem::transmute(result__)) } } + #[cfg(all(feature = "Win32_Graphics_Gdi", feature = "Win32_System_Com_StructuredStorage"))] + pub unsafe fn GetDataHere(&self, pformatetc: *const FORMATETC, pmedium: *mut STGMEDIUM) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetDataHere)(windows_core::Interface::as_raw(self), pformatetc, core::mem::transmute(pmedium)).ok() } + } + pub unsafe fn QueryGetData(&self, pformatetc: *const FORMATETC) -> windows_core::HRESULT { + unsafe { (windows_core::Interface::vtable(self).QueryGetData)(windows_core::Interface::as_raw(self), pformatetc) } + } + pub unsafe fn GetCanonicalFormatEtc(&self, pformatectin: *const FORMATETC, pformatetcout: *mut FORMATETC) -> windows_core::HRESULT { + unsafe { (windows_core::Interface::vtable(self).GetCanonicalFormatEtc)(windows_core::Interface::as_raw(self), pformatectin, pformatetcout as _) } + } + #[cfg(all(feature = "Win32_Graphics_Gdi", feature = "Win32_System_Com_StructuredStorage"))] + pub unsafe fn SetData(&self, pformatetc: *const FORMATETC, pmedium: *const STGMEDIUM, frelease: bool) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetData)(windows_core::Interface::as_raw(self), pformatetc, core::mem::transmute(pmedium), frelease.into()).ok() } + } pub unsafe fn EnumFormatEtc(&self, dwdirection: u32) -> windows_core::Result { unsafe { let mut result__ = core::mem::zeroed(); (windows_core::Interface::vtable(self).EnumFormatEtc)(windows_core::Interface::as_raw(self), dwdirection, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub unsafe fn DAdvise(&self, pformatetc: *const FORMATETC, advf: u32, padvsink: P2) -> windows_core::Result + where + P2: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).DAdvise)(windows_core::Interface::as_raw(self), pformatetc, advf, padvsink.param().abi(), &mut result__).map(|| result__) + } } + pub unsafe fn DUnadvise(&self, dwconnection: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).DUnadvise)(windows_core::Interface::as_raw(self), dwconnection).ok() } + } + pub unsafe fn EnumDAdvise(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).EnumDAdvise)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IDataObject_Vtbl { @@ -43971,7 +133845,7 @@ pub trait IDataObject_Impl: windows_core::IUnknownImpl { fn GetCanonicalFormatEtc(&self, pformatectin: *const FORMATETC, pformatetcout: *mut FORMATETC) -> windows_core::HRESULT; fn SetData(&self, pformatetc: *const FORMATETC, pmedium: *const STGMEDIUM, frelease: windows_core::BOOL) -> windows_core::Result<()>; fn EnumFormatEtc(&self, dwdirection: u32) -> windows_core::Result; - fn DAdvise(&self, pformatetc: *const FORMATETC, advf: u32, padvsink: windows_core::Ref) -> windows_core::Result; + fn DAdvise(&self, pformatetc: *const FORMATETC, advf: u32, padvsink: windows_core::Ref<'_, IAdviseSink>) -> windows_core::Result; fn DUnadvise(&self, dwconnection: u32) -> windows_core::Result<()>; fn EnumDAdvise(&self) -> windows_core::Result; } @@ -44077,6 +133951,27 @@ impl IDataObject_Vtbl { impl windows_core::RuntimeName for IDataObject {} windows_core::imp::define_interface!(IDispatch, IDispatch_Vtbl, 0x00020400_0000_0000_c000_000000000046); windows_core::imp::interface_hierarchy!(IDispatch, windows_core::IUnknown); +impl IDispatch { + pub unsafe fn GetTypeInfoCount(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTypeInfoCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetTypeInfo(&self, itinfo: u32, lcid: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTypeInfo)(windows_core::Interface::as_raw(self), itinfo, lcid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetIDsOfNames(&self, riid: *const windows_core::GUID, rgsznames: *const windows_core::PCWSTR, cnames: u32, lcid: u32, rgdispid: *mut i32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetIDsOfNames)(windows_core::Interface::as_raw(self), riid, rgsznames, cnames, lcid, rgdispid as _).ok() } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn Invoke(&self, dispidmember: i32, riid: *const windows_core::GUID, lcid: u32, wflags: DISPATCH_FLAGS, pdispparams: *const DISPPARAMS, pvarresult: Option<*mut super::Variant::VARIANT>, pexcepinfo: Option<*mut EXCEPINFO>, puargerr: Option<*mut u32>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Invoke)(windows_core::Interface::as_raw(self), dispidmember, riid, lcid, wflags, pdispparams, pvarresult.unwrap_or(core::mem::zeroed()) as _, pexcepinfo.unwrap_or(core::mem::zeroed()) as _, puargerr.unwrap_or(core::mem::zeroed()) as _).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IDispatch_Vtbl { @@ -44155,7 +134050,19 @@ impl IEnumFORMATETC { pub unsafe fn Next(&self, rgelt: &mut [FORMATETC], pceltfetched: Option<*mut u32>) -> windows_core::HRESULT { unsafe { (windows_core::Interface::vtable(self).Next)(windows_core::Interface::as_raw(self), rgelt.len().try_into().unwrap(), core::mem::transmute(rgelt.as_ptr()), pceltfetched.unwrap_or(core::mem::zeroed()) as _) } } + pub unsafe fn Skip(&self, celt: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Skip)(windows_core::Interface::as_raw(self), celt).ok() } } + pub unsafe fn Reset(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Reset)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn Clone(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Clone)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IEnumFORMATETC_Vtbl { @@ -44222,7 +134129,19 @@ impl IEnumMoniker { pub unsafe fn Next(&self, rgelt: &mut [Option], pceltfetched: Option<*mut u32>) -> windows_core::HRESULT { unsafe { (windows_core::Interface::vtable(self).Next)(windows_core::Interface::as_raw(self), rgelt.len().try_into().unwrap(), core::mem::transmute(rgelt.as_ptr()), pceltfetched.unwrap_or(core::mem::zeroed()) as _) } } + pub unsafe fn Skip(&self, celt: u32) -> windows_core::HRESULT { + unsafe { (windows_core::Interface::vtable(self).Skip)(windows_core::Interface::as_raw(self), celt) } } + pub unsafe fn Reset(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Reset)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn Clone(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Clone)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IEnumMoniker_Vtbl { @@ -44289,7 +134208,19 @@ impl IEnumSTATDATA { pub unsafe fn Next(&self, rgelt: &mut [STATDATA], pceltfetched: Option<*mut u32>) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Next)(windows_core::Interface::as_raw(self), rgelt.len().try_into().unwrap(), core::mem::transmute(rgelt.as_ptr()), pceltfetched.unwrap_or(core::mem::zeroed()) as _).ok() } } + pub unsafe fn Skip(&self, celt: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Skip)(windows_core::Interface::as_raw(self), celt).ok() } } + pub unsafe fn Reset(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Reset)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn Clone(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Clone)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IEnumSTATDATA_Vtbl { @@ -44356,7 +134287,19 @@ impl IEnumString { pub unsafe fn Next(&self, rgelt: &mut [windows_core::PWSTR], pceltfetched: Option<*mut u32>) -> windows_core::HRESULT { unsafe { (windows_core::Interface::vtable(self).Next)(windows_core::Interface::as_raw(self), rgelt.len().try_into().unwrap(), core::mem::transmute(rgelt.as_ptr()), pceltfetched.unwrap_or(core::mem::zeroed()) as _) } } + pub unsafe fn Skip(&self, celt: u32) -> windows_core::HRESULT { + unsafe { (windows_core::Interface::vtable(self).Skip)(windows_core::Interface::as_raw(self), celt) } } + pub unsafe fn Reset(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Reset)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn Clone(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Clone)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IEnumString_Vtbl { @@ -44461,6 +134404,125 @@ impl core::ops::Deref for IMoniker { } } windows_core::imp::interface_hierarchy!(IMoniker, windows_core::IUnknown, IPersist, IPersistStream); +impl IMoniker { + pub unsafe fn BindToObject(&self, pbc: P0, pmktoleft: P1) -> windows_core::Result + where + P0: windows_core::Param, + P1: windows_core::Param, + T: windows_core::Interface, + { + let mut result__ = core::ptr::null_mut(); + unsafe { (windows_core::Interface::vtable(self).BindToObject)(windows_core::Interface::as_raw(self), pbc.param().abi(), pmktoleft.param().abi(), &T::IID, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } + } + pub unsafe fn BindToStorage(&self, pbc: P0, pmktoleft: P1) -> windows_core::Result + where + P0: windows_core::Param, + P1: windows_core::Param, + T: windows_core::Interface, + { + let mut result__ = core::ptr::null_mut(); + unsafe { (windows_core::Interface::vtable(self).BindToStorage)(windows_core::Interface::as_raw(self), pbc.param().abi(), pmktoleft.param().abi(), &T::IID, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } + } + pub unsafe fn Reduce(&self, pbc: P0, dwreducehowfar: u32, ppmktoleft: *mut Option, ppmkreduced: *mut Option) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).Reduce)(windows_core::Interface::as_raw(self), pbc.param().abi(), dwreducehowfar, core::mem::transmute(ppmktoleft), core::mem::transmute(ppmkreduced)).ok() } + } + pub unsafe fn ComposeWith(&self, pmkright: P0, fonlyifnotgeneric: bool) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).ComposeWith)(windows_core::Interface::as_raw(self), pmkright.param().abi(), fonlyifnotgeneric.into(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn Enum(&self, fforward: bool) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Enum)(windows_core::Interface::as_raw(self), fforward.into(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn IsEqual(&self, pmkothermoniker: P0) -> windows_core::HRESULT + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).IsEqual)(windows_core::Interface::as_raw(self), pmkothermoniker.param().abi()) } + } + pub unsafe fn Hash(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Hash)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn IsRunning(&self, pbc: P0, pmktoleft: P1, pmknewlyrunning: P2) -> windows_core::Result<()> + where + P0: windows_core::Param, + P1: windows_core::Param, + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).IsRunning)(windows_core::Interface::as_raw(self), pbc.param().abi(), pmktoleft.param().abi(), pmknewlyrunning.param().abi()).ok() } + } + pub unsafe fn GetTimeOfLastChange(&self, pbc: P0, pmktoleft: P1) -> windows_core::Result + where + P0: windows_core::Param, + P1: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTimeOfLastChange)(windows_core::Interface::as_raw(self), pbc.param().abi(), pmktoleft.param().abi(), &mut result__).map(|| result__) + } + } + pub unsafe fn Inverse(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Inverse)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn CommonPrefixWith(&self, pmkother: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CommonPrefixWith)(windows_core::Interface::as_raw(self), pmkother.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn RelativePathTo(&self, pmkother: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).RelativePathTo)(windows_core::Interface::as_raw(self), pmkother.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetDisplayName(&self, pbc: P0, pmktoleft: P1) -> windows_core::Result + where + P0: windows_core::Param, + P1: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetDisplayName)(windows_core::Interface::as_raw(self), pbc.param().abi(), pmktoleft.param().abi(), &mut result__).map(|| result__) + } + } + pub unsafe fn ParseDisplayName(&self, pbc: P0, pmktoleft: P1, pszdisplayname: P2, pcheaten: *mut u32, ppmkout: *mut Option) -> windows_core::Result<()> + where + P0: windows_core::Param, + P1: windows_core::Param, + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).ParseDisplayName)(windows_core::Interface::as_raw(self), pbc.param().abi(), pmktoleft.param().abi(), pszdisplayname.param().abi(), pcheaten as _, core::mem::transmute(ppmkout)).ok() } + } + pub unsafe fn IsSystemMoniker(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).IsSystemMoniker)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IMoniker_Vtbl { @@ -44482,20 +134544,20 @@ pub struct IMoniker_Vtbl { pub IsSystemMoniker: unsafe extern "system" fn(*mut core::ffi::c_void, *mut u32) -> windows_core::HRESULT, } pub trait IMoniker_Impl: IPersistStream_Impl { - fn BindToObject(&self, pbc: windows_core::Ref, pmktoleft: windows_core::Ref, riidresult: *const windows_core::GUID, ppvresult: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; - fn BindToStorage(&self, pbc: windows_core::Ref, pmktoleft: windows_core::Ref, riid: *const windows_core::GUID, ppvobj: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; - fn Reduce(&self, pbc: windows_core::Ref, dwreducehowfar: u32, ppmktoleft: windows_core::OutRef, ppmkreduced: windows_core::OutRef) -> windows_core::Result<()>; - fn ComposeWith(&self, pmkright: windows_core::Ref, fonlyifnotgeneric: windows_core::BOOL) -> windows_core::Result; + fn BindToObject(&self, pbc: windows_core::Ref<'_, IBindCtx>, pmktoleft: windows_core::Ref<'_, IMoniker>, riidresult: *const windows_core::GUID, ppvresult: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; + fn BindToStorage(&self, pbc: windows_core::Ref<'_, IBindCtx>, pmktoleft: windows_core::Ref<'_, IMoniker>, riid: *const windows_core::GUID, ppvobj: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; + fn Reduce(&self, pbc: windows_core::Ref<'_, IBindCtx>, dwreducehowfar: u32, ppmktoleft: windows_core::OutRef<'_, IMoniker>, ppmkreduced: windows_core::OutRef<'_, IMoniker>) -> windows_core::Result<()>; + fn ComposeWith(&self, pmkright: windows_core::Ref<'_, IMoniker>, fonlyifnotgeneric: windows_core::BOOL) -> windows_core::Result; fn Enum(&self, fforward: windows_core::BOOL) -> windows_core::Result; - fn IsEqual(&self, pmkothermoniker: windows_core::Ref) -> windows_core::HRESULT; + fn IsEqual(&self, pmkothermoniker: windows_core::Ref<'_, IMoniker>) -> windows_core::HRESULT; fn Hash(&self) -> windows_core::Result; - fn IsRunning(&self, pbc: windows_core::Ref, pmktoleft: windows_core::Ref, pmknewlyrunning: windows_core::Ref) -> windows_core::Result<()>; - fn GetTimeOfLastChange(&self, pbc: windows_core::Ref, pmktoleft: windows_core::Ref) -> windows_core::Result; + fn IsRunning(&self, pbc: windows_core::Ref<'_, IBindCtx>, pmktoleft: windows_core::Ref<'_, IMoniker>, pmknewlyrunning: windows_core::Ref<'_, IMoniker>) -> windows_core::Result<()>; + fn GetTimeOfLastChange(&self, pbc: windows_core::Ref<'_, IBindCtx>, pmktoleft: windows_core::Ref<'_, IMoniker>) -> windows_core::Result; fn Inverse(&self) -> windows_core::Result; - fn CommonPrefixWith(&self, pmkother: windows_core::Ref) -> windows_core::Result; - fn RelativePathTo(&self, pmkother: windows_core::Ref) -> windows_core::Result; - fn GetDisplayName(&self, pbc: windows_core::Ref, pmktoleft: windows_core::Ref) -> windows_core::Result; - fn ParseDisplayName(&self, pbc: windows_core::Ref, pmktoleft: windows_core::Ref, pszdisplayname: &windows_core::PCWSTR, pcheaten: *mut u32, ppmkout: windows_core::OutRef) -> windows_core::Result<()>; + fn CommonPrefixWith(&self, pmkother: windows_core::Ref<'_, IMoniker>) -> windows_core::Result; + fn RelativePathTo(&self, pmkother: windows_core::Ref<'_, IMoniker>) -> windows_core::Result; + fn GetDisplayName(&self, pbc: windows_core::Ref<'_, IBindCtx>, pmktoleft: windows_core::Ref<'_, IMoniker>) -> windows_core::Result; + fn ParseDisplayName(&self, pbc: windows_core::Ref<'_, IBindCtx>, pmktoleft: windows_core::Ref<'_, IMoniker>, pszdisplayname: &windows_core::PCWSTR, pcheaten: *mut u32, ppmkout: windows_core::OutRef<'_, IMoniker>) -> windows_core::Result<()>; fn IsSystemMoniker(&self) -> windows_core::Result; } impl IMoniker_Vtbl { @@ -44673,6 +134735,14 @@ impl windows_core::RuntimeName for IMoniker {} pub struct INVOKEKIND(pub i32); windows_core::imp::define_interface!(IPersist, IPersist_Vtbl, 0x0000010c_0000_0000_c000_000000000046); windows_core::imp::interface_hierarchy!(IPersist, windows_core::IUnknown); +impl IPersist { + pub unsafe fn GetClassID(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetClassID)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IPersist_Vtbl { @@ -44711,6 +134781,35 @@ impl core::ops::Deref for IPersistFile { } } windows_core::imp::interface_hierarchy!(IPersistFile, windows_core::IUnknown, IPersist); +impl IPersistFile { + pub unsafe fn IsDirty(&self) -> windows_core::HRESULT { + unsafe { (windows_core::Interface::vtable(self).IsDirty)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn Load(&self, pszfilename: P0, dwmode: STGM) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).Load)(windows_core::Interface::as_raw(self), pszfilename.param().abi(), dwmode).ok() } + } + pub unsafe fn Save(&self, pszfilename: P0, fremember: bool) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).Save)(windows_core::Interface::as_raw(self), pszfilename.param().abi(), fremember.into()).ok() } + } + pub unsafe fn SaveCompleted(&self, pszfilename: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SaveCompleted)(windows_core::Interface::as_raw(self), pszfilename.param().abi()).ok() } + } + pub unsafe fn GetCurFile(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetCurFile)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IPersistFile_Vtbl { @@ -44788,6 +134887,26 @@ impl core::ops::Deref for IPersistMemory { } } windows_core::imp::interface_hierarchy!(IPersistMemory, windows_core::IUnknown, IPersist); +impl IPersistMemory { + pub unsafe fn IsDirty(&self) -> windows_core::HRESULT { + unsafe { (windows_core::Interface::vtable(self).IsDirty)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn Load(&self, pmem: &[u8]) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Load)(windows_core::Interface::as_raw(self), core::mem::transmute(pmem.as_ptr()), pmem.len().try_into().unwrap()).ok() } + } + pub unsafe fn Save(&self, pmem: &mut [u8], fcleardirty: bool) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Save)(windows_core::Interface::as_raw(self), core::mem::transmute(pmem.as_ptr()), fcleardirty.into(), pmem.len().try_into().unwrap()).ok() } + } + pub unsafe fn GetSizeMax(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetSizeMax)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn InitNew(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).InitNew)(windows_core::Interface::as_raw(self)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IPersistMemory_Vtbl { @@ -44865,6 +134984,29 @@ impl core::ops::Deref for IPersistStream { } } windows_core::imp::interface_hierarchy!(IPersistStream, windows_core::IUnknown, IPersist); +impl IPersistStream { + pub unsafe fn IsDirty(&self) -> windows_core::HRESULT { + unsafe { (windows_core::Interface::vtable(self).IsDirty)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn Load(&self, pstm: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).Load)(windows_core::Interface::as_raw(self), pstm.param().abi()).ok() } + } + pub unsafe fn Save(&self, pstm: P0, fcleardirty: bool) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).Save)(windows_core::Interface::as_raw(self), pstm.param().abi(), fcleardirty.into()).ok() } + } + pub unsafe fn GetSizeMax(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetSizeMax)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IPersistStream_Vtbl { @@ -44876,8 +135018,8 @@ pub struct IPersistStream_Vtbl { } pub trait IPersistStream_Impl: IPersist_Impl { fn IsDirty(&self) -> windows_core::HRESULT; - fn Load(&self, pstm: windows_core::Ref) -> windows_core::Result<()>; - fn Save(&self, pstm: windows_core::Ref, fcleardirty: windows_core::BOOL) -> windows_core::Result<()>; + fn Load(&self, pstm: windows_core::Ref<'_, IStream>) -> windows_core::Result<()>; + fn Save(&self, pstm: windows_core::Ref<'_, IStream>, fcleardirty: windows_core::BOOL) -> windows_core::Result<()>; fn GetSizeMax(&self) -> windows_core::Result; } impl IPersistStream_Vtbl { @@ -44933,6 +135075,32 @@ impl core::ops::Deref for IPersistStreamInit { } } windows_core::imp::interface_hierarchy!(IPersistStreamInit, windows_core::IUnknown, IPersist); +impl IPersistStreamInit { + pub unsafe fn IsDirty(&self) -> windows_core::HRESULT { + unsafe { (windows_core::Interface::vtable(self).IsDirty)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn Load(&self, pstm: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).Load)(windows_core::Interface::as_raw(self), pstm.param().abi()).ok() } + } + pub unsafe fn Save(&self, pstm: P0, fcleardirty: bool) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).Save)(windows_core::Interface::as_raw(self), pstm.param().abi(), fcleardirty.into()).ok() } + } + pub unsafe fn GetSizeMax(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetSizeMax)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn InitNew(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).InitNew)(windows_core::Interface::as_raw(self)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IPersistStreamInit_Vtbl { @@ -44945,8 +135113,8 @@ pub struct IPersistStreamInit_Vtbl { } pub trait IPersistStreamInit_Impl: IPersist_Impl { fn IsDirty(&self) -> windows_core::HRESULT; - fn Load(&self, pstm: windows_core::Ref) -> windows_core::Result<()>; - fn Save(&self, pstm: windows_core::Ref, fcleardirty: windows_core::BOOL) -> windows_core::Result<()>; + fn Load(&self, pstm: windows_core::Ref<'_, IStream>) -> windows_core::Result<()>; + fn Save(&self, pstm: windows_core::Ref<'_, IStream>, fcleardirty: windows_core::BOOL) -> windows_core::Result<()>; fn GetSizeMax(&self) -> windows_core::Result; fn InitNew(&self) -> windows_core::Result<()>; } @@ -45004,6 +135172,54 @@ impl IPersistStreamInit_Vtbl { impl windows_core::RuntimeName for IPersistStreamInit {} windows_core::imp::define_interface!(IRunningObjectTable, IRunningObjectTable_Vtbl, 0x00000010_0000_0000_c000_000000000046); windows_core::imp::interface_hierarchy!(IRunningObjectTable, windows_core::IUnknown); +impl IRunningObjectTable { + pub unsafe fn Register(&self, grfflags: ROT_FLAGS, punkobject: P1, pmkobjectname: P2) -> windows_core::Result + where + P1: windows_core::Param, + P2: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Register)(windows_core::Interface::as_raw(self), grfflags, punkobject.param().abi(), pmkobjectname.param().abi(), &mut result__).map(|| result__) + } + } + pub unsafe fn Revoke(&self, dwregister: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Revoke)(windows_core::Interface::as_raw(self), dwregister).ok() } + } + pub unsafe fn IsRunning(&self, pmkobjectname: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).IsRunning)(windows_core::Interface::as_raw(self), pmkobjectname.param().abi()).ok() } + } + pub unsafe fn GetObject(&self, pmkobjectname: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetObject)(windows_core::Interface::as_raw(self), pmkobjectname.param().abi(), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn NoteChangeTime(&self, dwregister: u32, pfiletime: *const super::super::Foundation::FILETIME) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).NoteChangeTime)(windows_core::Interface::as_raw(self), dwregister, pfiletime).ok() } + } + pub unsafe fn GetTimeOfLastChange(&self, pmkobjectname: P0) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTimeOfLastChange)(windows_core::Interface::as_raw(self), pmkobjectname.param().abi(), &mut result__).map(|| result__) + } + } + pub unsafe fn EnumRunning(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).EnumRunning)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IRunningObjectTable_Vtbl { @@ -45017,12 +135233,12 @@ pub struct IRunningObjectTable_Vtbl { pub EnumRunning: unsafe extern "system" fn(*mut core::ffi::c_void, *mut *mut core::ffi::c_void) -> windows_core::HRESULT, } pub trait IRunningObjectTable_Impl: windows_core::IUnknownImpl { - fn Register(&self, grfflags: ROT_FLAGS, punkobject: windows_core::Ref, pmkobjectname: windows_core::Ref) -> windows_core::Result; + fn Register(&self, grfflags: ROT_FLAGS, punkobject: windows_core::Ref<'_, windows_core::IUnknown>, pmkobjectname: windows_core::Ref<'_, IMoniker>) -> windows_core::Result; fn Revoke(&self, dwregister: u32) -> windows_core::Result<()>; - fn IsRunning(&self, pmkobjectname: windows_core::Ref) -> windows_core::Result<()>; - fn GetObject(&self, pmkobjectname: windows_core::Ref) -> windows_core::Result; + fn IsRunning(&self, pmkobjectname: windows_core::Ref<'_, IMoniker>) -> windows_core::Result<()>; + fn GetObject(&self, pmkobjectname: windows_core::Ref<'_, IMoniker>) -> windows_core::Result; fn NoteChangeTime(&self, dwregister: u32, pfiletime: *const super::super::Foundation::FILETIME) -> windows_core::Result<()>; - fn GetTimeOfLastChange(&self, pmkobjectname: windows_core::Ref) -> windows_core::Result; + fn GetTimeOfLastChange(&self, pmkobjectname: windows_core::Ref<'_, IMoniker>) -> windows_core::Result; fn EnumRunning(&self) -> windows_core::Result; } impl IRunningObjectTable_Vtbl { @@ -45111,6 +135327,14 @@ impl IRunningObjectTable_Vtbl { impl windows_core::RuntimeName for IRunningObjectTable {} windows_core::imp::define_interface!(ISequentialStream, ISequentialStream_Vtbl, 0x0c733a30_2a1c_11ce_ade5_00aa0044773d); windows_core::imp::interface_hierarchy!(ISequentialStream, windows_core::IUnknown); +impl ISequentialStream { + pub unsafe fn Read(&self, pv: *mut core::ffi::c_void, cb: u32, pcbread: Option<*mut u32>) -> windows_core::HRESULT { + unsafe { (windows_core::Interface::vtable(self).Read)(windows_core::Interface::as_raw(self), pv as _, cb, pcbread.unwrap_or(core::mem::zeroed()) as _) } + } + pub unsafe fn Write(&self, pv: *const core::ffi::c_void, cb: u32, pcbwritten: Option<*mut u32>) -> windows_core::HRESULT { + unsafe { (windows_core::Interface::vtable(self).Write)(windows_core::Interface::as_raw(self), pv, cb, pcbwritten.unwrap_or(core::mem::zeroed()) as _) } + } +} #[repr(C)] #[doc(hidden)] pub struct ISequentialStream_Vtbl { @@ -45155,7 +135379,37 @@ impl IStream { pub unsafe fn Seek(&self, dlibmove: i64, dworigin: STREAM_SEEK, plibnewposition: Option<*mut u64>) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Seek)(windows_core::Interface::as_raw(self), dlibmove, dworigin, plibnewposition.unwrap_or(core::mem::zeroed()) as _).ok() } } + pub unsafe fn SetSize(&self, libnewsize: u64) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetSize)(windows_core::Interface::as_raw(self), libnewsize).ok() } } + pub unsafe fn CopyTo(&self, pstm: P0, cb: u64, pcbread: Option<*mut u64>, pcbwritten: Option<*mut u64>) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CopyTo)(windows_core::Interface::as_raw(self), pstm.param().abi(), cb, pcbread.unwrap_or(core::mem::zeroed()) as _, pcbwritten.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn Commit(&self, grfcommitflags: STGC) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Commit)(windows_core::Interface::as_raw(self), grfcommitflags.0 as _).ok() } + } + pub unsafe fn Revert(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Revert)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn LockRegion(&self, liboffset: u64, cb: u64, dwlocktype: LOCKTYPE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).LockRegion)(windows_core::Interface::as_raw(self), liboffset, cb, dwlocktype.0 as _).ok() } + } + pub unsafe fn UnlockRegion(&self, liboffset: u64, cb: u64, dwlocktype: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).UnlockRegion)(windows_core::Interface::as_raw(self), liboffset, cb, dwlocktype).ok() } + } + pub unsafe fn Stat(&self, pstatstg: *mut STATSTG, grfstatflag: STATFLAG) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Stat)(windows_core::Interface::as_raw(self), pstatstg as _, grfstatflag.0 as _).ok() } + } + pub unsafe fn Clone(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Clone)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IStream_Vtbl { @@ -45173,7 +135427,7 @@ pub struct IStream_Vtbl { pub trait IStream_Impl: ISequentialStream_Impl { fn Seek(&self, dlibmove: i64, dworigin: STREAM_SEEK, plibnewposition: *mut u64) -> windows_core::Result<()>; fn SetSize(&self, libnewsize: u64) -> windows_core::Result<()>; - fn CopyTo(&self, pstm: windows_core::Ref, cb: u64, pcbread: *mut u64, pcbwritten: *mut u64) -> windows_core::Result<()>; + fn CopyTo(&self, pstm: windows_core::Ref<'_, IStream>, cb: u64, pcbread: *mut u64, pcbwritten: *mut u64) -> windows_core::Result<()>; fn Commit(&self, grfcommitflags: &STGC) -> windows_core::Result<()>; fn Revert(&self) -> windows_core::Result<()>; fn LockRegion(&self, liboffset: u64, cb: u64, dwlocktype: &LOCKTYPE) -> windows_core::Result<()>; @@ -45263,6 +135517,21 @@ impl IStream_Vtbl { impl windows_core::RuntimeName for IStream {} windows_core::imp::define_interface!(ITypeComp, ITypeComp_Vtbl, 0x00020403_0000_0000_c000_000000000046); windows_core::imp::interface_hierarchy!(ITypeComp, windows_core::IUnknown); +impl ITypeComp { + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn Bind(&self, szname: P0, lhashval: u32, wflags: u16, pptinfo: *mut Option, pdesckind: *mut DESCKIND, pbindptr: *mut BINDPTR) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).Bind)(windows_core::Interface::as_raw(self), szname.param().abi(), lhashval, wflags, core::mem::transmute(pptinfo), pdesckind as _, core::mem::transmute(pbindptr)).ok() } + } + pub unsafe fn BindType(&self, szname: P0, lhashval: u32, pptinfo: *mut Option, pptcomp: *mut Option) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).BindType)(windows_core::Interface::as_raw(self), szname.param().abi(), lhashval, core::mem::transmute(pptinfo), core::mem::transmute(pptcomp)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct ITypeComp_Vtbl { @@ -45275,8 +135544,8 @@ pub struct ITypeComp_Vtbl { } #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] pub trait ITypeComp_Impl: windows_core::IUnknownImpl { - fn Bind(&self, szname: &windows_core::PCWSTR, lhashval: u32, wflags: u16, pptinfo: windows_core::OutRef, pdesckind: *mut DESCKIND, pbindptr: *mut BINDPTR) -> windows_core::Result<()>; - fn BindType(&self, szname: &windows_core::PCWSTR, lhashval: u32, pptinfo: windows_core::OutRef, pptcomp: windows_core::OutRef) -> windows_core::Result<()>; + fn Bind(&self, szname: &windows_core::PCWSTR, lhashval: u32, wflags: u16, pptinfo: windows_core::OutRef<'_, ITypeInfo>, pdesckind: *mut DESCKIND, pbindptr: *mut BINDPTR) -> windows_core::Result<()>; + fn BindType(&self, szname: &windows_core::PCWSTR, lhashval: u32, pptinfo: windows_core::OutRef<'_, ITypeInfo>, pptcomp: windows_core::OutRef<'_, ITypeComp>) -> windows_core::Result<()>; } #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] impl ITypeComp_Vtbl { @@ -45304,6 +135573,70 @@ impl windows_core::RuntimeName for ITypeComp {} windows_core::imp::define_interface!(ITypeInfo, ITypeInfo_Vtbl, 0x00020401_0000_0000_c000_000000000046); windows_core::imp::interface_hierarchy!(ITypeInfo, windows_core::IUnknown); impl ITypeInfo { + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetTypeAttr(&self) -> windows_core::Result<*mut TYPEATTR> { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTypeAttr)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetTypeComp(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTypeComp)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetFuncDesc(&self, index: u32) -> windows_core::Result<*mut FUNCDESC> { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetFuncDesc)(windows_core::Interface::as_raw(self), index, &mut result__).map(|| result__) + } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetVarDesc(&self, index: u32) -> windows_core::Result<*mut VARDESC> { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetVarDesc)(windows_core::Interface::as_raw(self), index, &mut result__).map(|| result__) + } + } + pub unsafe fn GetNames(&self, memid: i32, rgbstrnames: &mut [windows_core::BSTR], pcnames: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetNames)(windows_core::Interface::as_raw(self), memid, core::mem::transmute(rgbstrnames.as_ptr()), rgbstrnames.len().try_into().unwrap(), pcnames as _).ok() } + } + pub unsafe fn GetRefTypeOfImplType(&self, index: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetRefTypeOfImplType)(windows_core::Interface::as_raw(self), index, &mut result__).map(|| result__) + } + } + pub unsafe fn GetImplTypeFlags(&self, index: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetImplTypeFlags)(windows_core::Interface::as_raw(self), index, &mut result__).map(|| result__) + } + } + pub unsafe fn GetIDsOfNames(&self, rgsznames: *const windows_core::PCWSTR, cnames: u32, pmemid: *mut i32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetIDsOfNames)(windows_core::Interface::as_raw(self), rgsznames, cnames, pmemid as _).ok() } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn Invoke(&self, pvinstance: *const core::ffi::c_void, memid: i32, wflags: DISPATCH_FLAGS, pdispparams: *mut DISPPARAMS, pvarresult: *mut super::Variant::VARIANT, pexcepinfo: *mut EXCEPINFO, puargerr: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Invoke)(windows_core::Interface::as_raw(self), pvinstance, memid, wflags, pdispparams as _, core::mem::transmute(pvarresult), core::mem::transmute(pexcepinfo), puargerr as _).ok() } + } + pub unsafe fn GetDocumentation(&self, memid: i32, pbstrname: Option<*mut windows_core::BSTR>, pbstrdocstring: Option<*mut windows_core::BSTR>, pdwhelpcontext: *mut u32, pbstrhelpfile: Option<*mut windows_core::BSTR>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetDocumentation)(windows_core::Interface::as_raw(self), memid, pbstrname.unwrap_or(core::mem::zeroed()) as _, pbstrdocstring.unwrap_or(core::mem::zeroed()) as _, pdwhelpcontext as _, pbstrhelpfile.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn GetDllEntry(&self, memid: i32, invkind: INVOKEKIND, pbstrdllname: Option<*mut windows_core::BSTR>, pbstrname: Option<*mut windows_core::BSTR>, pwordinal: *mut u16) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetDllEntry)(windows_core::Interface::as_raw(self), memid, invkind, pbstrdllname.unwrap_or(core::mem::zeroed()) as _, pbstrname.unwrap_or(core::mem::zeroed()) as _, pwordinal as _).ok() } + } + pub unsafe fn GetRefTypeInfo(&self, hreftype: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetRefTypeInfo)(windows_core::Interface::as_raw(self), hreftype, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn AddressOfMember(&self, memid: i32, invkind: INVOKEKIND, ppv: *mut *mut core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).AddressOfMember)(windows_core::Interface::as_raw(self), memid, invkind, ppv as _).ok() } + } pub unsafe fn CreateInstance(&self, punkouter: P0) -> windows_core::Result where P0: windows_core::Param, @@ -45312,7 +135645,28 @@ impl ITypeInfo { let mut result__ = core::ptr::null_mut(); unsafe { (windows_core::Interface::vtable(self).CreateInstance)(windows_core::Interface::as_raw(self), punkouter.param().abi(), &T::IID, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) } } + pub unsafe fn GetMops(&self, memid: i32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetMops)(windows_core::Interface::as_raw(self), memid, &mut result__).map(|| core::mem::transmute(result__)) + } } + pub unsafe fn GetContainingTypeLib(&self, pptlib: *mut Option, pindex: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetContainingTypeLib)(windows_core::Interface::as_raw(self), core::mem::transmute(pptlib), pindex as _).ok() } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn ReleaseTypeAttr(&self, ptypeattr: *const TYPEATTR) { + unsafe { (windows_core::Interface::vtable(self).ReleaseTypeAttr)(windows_core::Interface::as_raw(self), ptypeattr) } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn ReleaseFuncDesc(&self, pfuncdesc: *const FUNCDESC) { + unsafe { (windows_core::Interface::vtable(self).ReleaseFuncDesc)(windows_core::Interface::as_raw(self), pfuncdesc) } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn ReleaseVarDesc(&self, pvardesc: *const VARDESC) { + unsafe { (windows_core::Interface::vtable(self).ReleaseVarDesc)(windows_core::Interface::as_raw(self), pvardesc) } + } +} #[repr(C)] #[doc(hidden)] pub struct ITypeInfo_Vtbl { @@ -45373,9 +135727,9 @@ pub trait ITypeInfo_Impl: windows_core::IUnknownImpl { fn GetDllEntry(&self, memid: i32, invkind: INVOKEKIND, pbstrdllname: *mut windows_core::BSTR, pbstrname: *mut windows_core::BSTR, pwordinal: *mut u16) -> windows_core::Result<()>; fn GetRefTypeInfo(&self, hreftype: u32) -> windows_core::Result; fn AddressOfMember(&self, memid: i32, invkind: INVOKEKIND, ppv: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; - fn CreateInstance(&self, punkouter: windows_core::Ref, riid: *const windows_core::GUID, ppvobj: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; + fn CreateInstance(&self, punkouter: windows_core::Ref<'_, windows_core::IUnknown>, riid: *const windows_core::GUID, ppvobj: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; fn GetMops(&self, memid: i32) -> windows_core::Result; - fn GetContainingTypeLib(&self, pptlib: windows_core::OutRef, pindex: *mut u32) -> windows_core::Result<()>; + fn GetContainingTypeLib(&self, pptlib: windows_core::OutRef<'_, ITypeLib>, pindex: *mut u32) -> windows_core::Result<()>; fn ReleaseTypeAttr(&self, ptypeattr: *const TYPEATTR); fn ReleaseFuncDesc(&self, pfuncdesc: *const FUNCDESC); fn ReleaseVarDesc(&self, pvardesc: *const VARDESC); @@ -45582,6 +135936,105 @@ impl core::ops::Deref for ITypeInfo2 { } } windows_core::imp::interface_hierarchy!(ITypeInfo2, windows_core::IUnknown, ITypeInfo); +impl ITypeInfo2 { + pub unsafe fn GetTypeKind(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTypeKind)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetTypeFlags(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTypeFlags)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetFuncIndexOfMemId(&self, memid: i32, invkind: INVOKEKIND) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetFuncIndexOfMemId)(windows_core::Interface::as_raw(self), memid, invkind, &mut result__).map(|| result__) + } + } + pub unsafe fn GetVarIndexOfMemId(&self, memid: i32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetVarIndexOfMemId)(windows_core::Interface::as_raw(self), memid, &mut result__).map(|| result__) + } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetCustData(&self, guid: *const windows_core::GUID) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetCustData)(windows_core::Interface::as_raw(self), guid, &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetFuncCustData(&self, index: u32, guid: *const windows_core::GUID) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetFuncCustData)(windows_core::Interface::as_raw(self), index, guid, &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetParamCustData(&self, indexfunc: u32, indexparam: u32, guid: *const windows_core::GUID) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetParamCustData)(windows_core::Interface::as_raw(self), indexfunc, indexparam, guid, &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetVarCustData(&self, index: u32, guid: *const windows_core::GUID) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetVarCustData)(windows_core::Interface::as_raw(self), index, guid, &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetImplTypeCustData(&self, index: u32, guid: *const windows_core::GUID) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetImplTypeCustData)(windows_core::Interface::as_raw(self), index, guid, &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub unsafe fn GetDocumentation2(&self, memid: i32, lcid: u32, pbstrhelpstring: Option<*mut windows_core::BSTR>, pdwhelpstringcontext: *mut u32, pbstrhelpstringdll: Option<*mut windows_core::BSTR>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetDocumentation2)(windows_core::Interface::as_raw(self), memid, lcid, pbstrhelpstring.unwrap_or(core::mem::zeroed()) as _, pdwhelpstringcontext as _, pbstrhelpstringdll.unwrap_or(core::mem::zeroed()) as _).ok() } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetAllCustData(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetAllCustData)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetAllFuncCustData(&self, index: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetAllFuncCustData)(windows_core::Interface::as_raw(self), index, &mut result__).map(|| result__) + } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetAllParamCustData(&self, indexfunc: u32, indexparam: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetAllParamCustData)(windows_core::Interface::as_raw(self), indexfunc, indexparam, &mut result__).map(|| result__) + } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetAllVarCustData(&self, index: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetAllVarCustData)(windows_core::Interface::as_raw(self), index, &mut result__).map(|| result__) + } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetAllImplTypeCustData(&self, index: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetAllImplTypeCustData)(windows_core::Interface::as_raw(self), index, &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct ITypeInfo2_Vtbl { @@ -45854,6 +136307,53 @@ impl ITypeInfo2_Vtbl { impl windows_core::RuntimeName for ITypeInfo2 {} windows_core::imp::define_interface!(ITypeLib, ITypeLib_Vtbl, 0x00020402_0000_0000_c000_000000000046); windows_core::imp::interface_hierarchy!(ITypeLib, windows_core::IUnknown); +impl ITypeLib { + pub unsafe fn GetTypeInfoCount(&self) -> u32 { + unsafe { (windows_core::Interface::vtable(self).GetTypeInfoCount)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn GetTypeInfo(&self, index: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTypeInfo)(windows_core::Interface::as_raw(self), index, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetTypeInfoType(&self, index: u32) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTypeInfoType)(windows_core::Interface::as_raw(self), index, &mut result__).map(|| result__) + } + } + pub unsafe fn GetTypeInfoOfGuid(&self, guid: *const windows_core::GUID) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTypeInfoOfGuid)(windows_core::Interface::as_raw(self), guid, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetLibAttr(&self) -> windows_core::Result<*mut TLIBATTR> { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetLibAttr)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetTypeComp(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTypeComp)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn GetDocumentation(&self, index: i32, pbstrname: Option<*mut windows_core::BSTR>, pbstrdocstring: Option<*mut windows_core::BSTR>, pdwhelpcontext: *mut u32, pbstrhelpfile: Option<*mut windows_core::BSTR>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetDocumentation)(windows_core::Interface::as_raw(self), index, pbstrname.unwrap_or(core::mem::zeroed()) as _, pbstrdocstring.unwrap_or(core::mem::zeroed()) as _, pdwhelpcontext as _, pbstrhelpfile.unwrap_or(core::mem::zeroed()) as _).ok() } + } + pub unsafe fn IsName(&self, sznamebuf: windows_core::PWSTR, lhashval: u32, pfname: *mut windows_core::BOOL) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).IsName)(windows_core::Interface::as_raw(self), core::mem::transmute(sznamebuf), lhashval, pfname as _).ok() } + } + pub unsafe fn FindName(&self, sznamebuf: windows_core::PWSTR, lhashval: u32, pptinfo: *mut Option, rgmemid: *mut i32, pcfound: *mut u16) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).FindName)(windows_core::Interface::as_raw(self), core::mem::transmute(sznamebuf), lhashval, core::mem::transmute(pptinfo), rgmemid as _, pcfound as _).ok() } + } + pub unsafe fn ReleaseTLibAttr(&self, ptlibattr: *const TLIBATTR) { + unsafe { (windows_core::Interface::vtable(self).ReleaseTLibAttr)(windows_core::Interface::as_raw(self), ptlibattr) } + } +} #[repr(C)] #[doc(hidden)] pub struct ITypeLib_Vtbl { @@ -45878,7 +136378,7 @@ pub trait ITypeLib_Impl: windows_core::IUnknownImpl { fn GetTypeComp(&self) -> windows_core::Result; fn GetDocumentation(&self, index: i32, pbstrname: *mut windows_core::BSTR, pbstrdocstring: *mut windows_core::BSTR, pdwhelpcontext: *mut u32, pbstrhelpfile: *mut windows_core::BSTR) -> windows_core::Result<()>; fn IsName(&self, sznamebuf: windows_core::PWSTR, lhashval: u32, pfname: *mut windows_core::BOOL) -> windows_core::Result<()>; - fn FindName(&self, sznamebuf: windows_core::PWSTR, lhashval: u32, pptinfo: windows_core::OutRef, rgmemid: *mut i32, pcfound: *mut u16) -> windows_core::Result<()>; + fn FindName(&self, sznamebuf: windows_core::PWSTR, lhashval: u32, pptinfo: windows_core::OutRef<'_, ITypeInfo>, rgmemid: *mut i32, pcfound: *mut u16) -> windows_core::Result<()>; fn ReleaseTLibAttr(&self, ptlibattr: *const TLIBATTR); } impl ITypeLib_Vtbl { @@ -46000,6 +136500,28 @@ impl core::ops::Deref for ITypeLib2 { } } windows_core::imp::interface_hierarchy!(ITypeLib2, windows_core::IUnknown, ITypeLib); +impl ITypeLib2 { + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetCustData(&self, guid: *const windows_core::GUID) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetCustData)(windows_core::Interface::as_raw(self), guid, &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub unsafe fn GetLibStatistics(&self, pcuniquenames: *mut u32, pcchuniquenames: *mut u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetLibStatistics)(windows_core::Interface::as_raw(self), pcuniquenames as _, pcchuniquenames as _).ok() } + } + pub unsafe fn GetDocumentation2(&self, index: i32, lcid: u32, pbstrhelpstring: Option<*mut windows_core::BSTR>, pdwhelpstringcontext: *mut u32, pbstrhelpstringdll: Option<*mut windows_core::BSTR>) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetDocumentation2)(windows_core::Interface::as_raw(self), index, lcid, pbstrhelpstring.unwrap_or(core::mem::zeroed()) as _, pdwhelpstringcontext as _, pbstrhelpstringdll.unwrap_or(core::mem::zeroed()) as _).ok() } + } + #[cfg(all(feature = "Win32_System_Ole", feature = "Win32_System_Variant"))] + pub unsafe fn GetAllCustData(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetAllCustData)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } +} #[repr(C)] #[doc(hidden)] pub struct ITypeLib2_Vtbl { @@ -46392,6 +136914,7 @@ pub struct VARFLAGS(pub u16); #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct VARKIND(pub i32); +#[cfg(feature = "Win32_System_Com_StructuredStorage")] pub mod StructuredStorage{ #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq)] @@ -46661,7 +137184,19 @@ impl IEnumSTATSTG { pub unsafe fn Next(&self, rgelt: &mut [super::STATSTG], pceltfetched: Option<*mut u32>) -> windows_core::Result<()> { unsafe { (windows_core::Interface::vtable(self).Next)(windows_core::Interface::as_raw(self), rgelt.len().try_into().unwrap(), core::mem::transmute(rgelt.as_ptr()), pceltfetched.unwrap_or(core::mem::zeroed()) as _).ok() } } + pub unsafe fn Skip(&self, celt: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Skip)(windows_core::Interface::as_raw(self), celt).ok() } } + pub unsafe fn Reset(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Reset)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn Clone(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).Clone)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } +} #[repr(C)] #[doc(hidden)] pub struct IEnumSTATSTG_Vtbl { @@ -46724,6 +137259,99 @@ impl IEnumSTATSTG_Vtbl { impl windows_core::RuntimeName for IEnumSTATSTG {} windows_core::imp::define_interface!(IStorage, IStorage_Vtbl, 0x0000000b_0000_0000_c000_000000000046); windows_core::imp::interface_hierarchy!(IStorage, windows_core::IUnknown); +impl IStorage { + pub unsafe fn CreateStream(&self, pwcsname: P0, grfmode: super::STGM, reserved1: u32, reserved2: u32) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateStream)(windows_core::Interface::as_raw(self), pwcsname.param().abi(), grfmode, reserved1, reserved2, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn OpenStream(&self, pwcsname: P0, reserved1: Option<*const core::ffi::c_void>, grfmode: super::STGM, reserved2: u32) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).OpenStream)(windows_core::Interface::as_raw(self), pwcsname.param().abi(), reserved1.unwrap_or(core::mem::zeroed()) as _, grfmode, reserved2, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn CreateStorage(&self, pwcsname: P0, grfmode: super::STGM, reserved1: u32, reserved2: u32) -> windows_core::Result + where + P0: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).CreateStorage)(windows_core::Interface::as_raw(self), pwcsname.param().abi(), grfmode, reserved1, reserved2, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn OpenStorage(&self, pwcsname: P0, pstgpriority: P1, grfmode: super::STGM, snbexclude: *const *const u16, reserved: u32) -> windows_core::Result + where + P0: windows_core::Param, + P1: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).OpenStorage)(windows_core::Interface::as_raw(self), pwcsname.param().abi(), pstgpriority.param().abi(), grfmode, snbexclude, reserved, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn CopyTo(&self, rgiidexclude: Option<&[windows_core::GUID]>, snbexclude: Option<*const *const u16>, pstgdest: P3) -> windows_core::Result<()> + where + P3: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).CopyTo)(windows_core::Interface::as_raw(self), rgiidexclude.as_deref().map_or(0, |slice| slice.len().try_into().unwrap()), core::mem::transmute(rgiidexclude.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), snbexclude.unwrap_or(core::mem::zeroed()) as _, pstgdest.param().abi()).ok() } + } + pub unsafe fn MoveElementTo(&self, pwcsname: P0, pstgdest: P1, pwcsnewname: P2, grfflags: STGMOVE) -> windows_core::Result<()> + where + P0: windows_core::Param, + P1: windows_core::Param, + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).MoveElementTo)(windows_core::Interface::as_raw(self), pwcsname.param().abi(), pstgdest.param().abi(), pwcsnewname.param().abi(), grfflags.0 as _).ok() } + } + pub unsafe fn Commit(&self, grfcommitflags: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Commit)(windows_core::Interface::as_raw(self), grfcommitflags).ok() } + } + pub unsafe fn Revert(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Revert)(windows_core::Interface::as_raw(self)).ok() } + } + pub unsafe fn EnumElements(&self, reserved1: Option, reserved2: Option<*const core::ffi::c_void>, reserved3: Option) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).EnumElements)(windows_core::Interface::as_raw(self), reserved1.unwrap_or(core::mem::zeroed()) as _, reserved2.unwrap_or(core::mem::zeroed()) as _, reserved3.unwrap_or(core::mem::zeroed()) as _, &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + pub unsafe fn DestroyElement(&self, pwcsname: P0) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DestroyElement)(windows_core::Interface::as_raw(self), pwcsname.param().abi()).ok() } + } + pub unsafe fn RenameElement(&self, pwcsoldname: P0, pwcsnewname: P1) -> windows_core::Result<()> + where + P0: windows_core::Param, + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).RenameElement)(windows_core::Interface::as_raw(self), pwcsoldname.param().abi(), pwcsnewname.param().abi()).ok() } + } + pub unsafe fn SetElementTimes(&self, pwcsname: P0, pctime: *const super::super::super::Foundation::FILETIME, patime: *const super::super::super::Foundation::FILETIME, pmtime: *const super::super::super::Foundation::FILETIME) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).SetElementTimes)(windows_core::Interface::as_raw(self), pwcsname.param().abi(), pctime, patime, pmtime).ok() } + } + pub unsafe fn SetClass(&self, clsid: *const windows_core::GUID) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetClass)(windows_core::Interface::as_raw(self), clsid).ok() } + } + pub unsafe fn SetStateBits(&self, grfstatebits: u32, grfmask: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetStateBits)(windows_core::Interface::as_raw(self), grfstatebits, grfmask).ok() } + } + pub unsafe fn Stat(&self, pstatstg: *mut super::STATSTG, grfstatflag: u32) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Stat)(windows_core::Interface::as_raw(self), pstatstg as _, grfstatflag).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IStorage_Vtbl { @@ -46748,9 +137376,9 @@ pub trait IStorage_Impl: windows_core::IUnknownImpl { fn CreateStream(&self, pwcsname: &windows_core::PCWSTR, grfmode: super::STGM, reserved1: u32, reserved2: u32) -> windows_core::Result; fn OpenStream(&self, pwcsname: &windows_core::PCWSTR, reserved1: *const core::ffi::c_void, grfmode: super::STGM, reserved2: u32) -> windows_core::Result; fn CreateStorage(&self, pwcsname: &windows_core::PCWSTR, grfmode: super::STGM, reserved1: u32, reserved2: u32) -> windows_core::Result; - fn OpenStorage(&self, pwcsname: &windows_core::PCWSTR, pstgpriority: windows_core::Ref, grfmode: super::STGM, snbexclude: *const *const u16, reserved: u32) -> windows_core::Result; - fn CopyTo(&self, ciidexclude: u32, rgiidexclude: *const windows_core::GUID, snbexclude: *const *const u16, pstgdest: windows_core::Ref) -> windows_core::Result<()>; - fn MoveElementTo(&self, pwcsname: &windows_core::PCWSTR, pstgdest: windows_core::Ref, pwcsnewname: &windows_core::PCWSTR, grfflags: &STGMOVE) -> windows_core::Result<()>; + fn OpenStorage(&self, pwcsname: &windows_core::PCWSTR, pstgpriority: windows_core::Ref<'_, IStorage>, grfmode: super::STGM, snbexclude: *const *const u16, reserved: u32) -> windows_core::Result; + fn CopyTo(&self, ciidexclude: u32, rgiidexclude: *const windows_core::GUID, snbexclude: *const *const u16, pstgdest: windows_core::Ref<'_, IStorage>) -> windows_core::Result<()>; + fn MoveElementTo(&self, pwcsname: &windows_core::PCWSTR, pstgdest: windows_core::Ref<'_, IStorage>, pwcsnewname: &windows_core::PCWSTR, grfflags: &STGMOVE) -> windows_core::Result<()>; fn Commit(&self, grfcommitflags: u32) -> windows_core::Result<()>; fn Revert(&self) -> windows_core::Result<()>; fn EnumElements(&self, reserved1: u32, reserved2: *const core::ffi::c_void, reserved3: u32) -> windows_core::Result; @@ -47057,6 +137685,7 @@ pub struct VERSIONEDSTREAM { } } } +#[cfg(feature = "Win32_System_Console")] pub mod Console{ #[inline] pub unsafe fn ClosePseudoConsole(hpc: HPCON) { @@ -47102,6 +137731,7 @@ impl windows_core::Free for HPCON { } } } +#[cfg(feature = "Win32_System_DataExchange")] pub mod DataExchange{ #[inline] pub unsafe fn CloseClipboard() -> windows_core::Result<()> { @@ -47131,6 +137761,7 @@ pub unsafe fn SetClipboardData(uformat: u32, hmem: Option(lpmodulename: P0) -> windows_core::Result @@ -47159,6 +137790,7 @@ where (!result__.is_invalid()).then_some(result__).ok_or_else(windows_core::Error::from_thread) } } +#[cfg(feature = "Win32_System_Memory")] pub mod Memory{ #[inline] pub unsafe fn GlobalAlloc(uflags: GLOBAL_ALLOC_FLAGS, dwbytes: usize) -> windows_core::Result { @@ -47220,6 +137852,7 @@ impl core::ops::Not for GLOBAL_ALLOC_FLAGS { pub const GMEM_FIXED: GLOBAL_ALLOC_FLAGS = GLOBAL_ALLOC_FLAGS(0u32); pub const GMEM_ZEROINIT: GLOBAL_ALLOC_FLAGS = GLOBAL_ALLOC_FLAGS(64u32); } +#[cfg(feature = "Win32_System_Ole")] pub mod Ole{ #[cfg(feature = "Win32_System_Com")] #[inline] @@ -47310,6 +137943,15 @@ pub const DROPEFFECT_LINK: DROPEFFECT = DROPEFFECT(4u32); pub const DROPEFFECT_MOVE: DROPEFFECT = DROPEFFECT(2u32); windows_core::imp::define_interface!(IDropSource, IDropSource_Vtbl, 0x00000121_0000_0000_c000_000000000046); windows_core::imp::interface_hierarchy!(IDropSource, windows_core::IUnknown); +impl IDropSource { + #[cfg(feature = "Win32_System_SystemServices")] + pub unsafe fn QueryContinueDrag(&self, fescapepressed: bool, grfkeystate: super::SystemServices::MODIFIERKEYS_FLAGS) -> windows_core::HRESULT { + unsafe { (windows_core::Interface::vtable(self).QueryContinueDrag)(windows_core::Interface::as_raw(self), fescapepressed.into(), grfkeystate) } + } + pub unsafe fn GiveFeedback(&self, dweffect: DROPEFFECT) -> windows_core::HRESULT { + unsafe { (windows_core::Interface::vtable(self).GiveFeedback)(windows_core::Interface::as_raw(self), dweffect) } + } +} #[repr(C)] #[doc(hidden)] pub struct IDropSource_Vtbl { @@ -47355,6 +137997,20 @@ impl windows_core::RuntimeName for IDropSource {} windows_core::imp::define_interface!(IDropTarget, IDropTarget_Vtbl, 0x00000122_0000_0000_c000_000000000046); windows_core::imp::interface_hierarchy!(IDropTarget, windows_core::IUnknown); impl IDropTarget { + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_SystemServices"))] + pub unsafe fn DragEnter(&self, pdataobj: P0, grfkeystate: super::SystemServices::MODIFIERKEYS_FLAGS, pt: super::super::Foundation::POINTL, pdweffect: *mut DROPEFFECT) -> windows_core::Result<()> + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).DragEnter)(windows_core::Interface::as_raw(self), pdataobj.param().abi(), grfkeystate, core::mem::transmute(pt), pdweffect as _).ok() } + } + #[cfg(feature = "Win32_System_SystemServices")] + pub unsafe fn DragOver(&self, grfkeystate: super::SystemServices::MODIFIERKEYS_FLAGS, pt: super::super::Foundation::POINTL, pdweffect: *mut DROPEFFECT) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).DragOver)(windows_core::Interface::as_raw(self), grfkeystate, core::mem::transmute(pt), pdweffect as _).ok() } + } + pub unsafe fn DragLeave(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).DragLeave)(windows_core::Interface::as_raw(self)).ok() } + } #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_SystemServices"))] pub unsafe fn Drop(&self, pdataobj: P0, grfkeystate: super::SystemServices::MODIFIERKEYS_FLAGS, pt: super::super::Foundation::POINTL, pdweffect: *mut DROPEFFECT) -> windows_core::Result<()> where @@ -47383,10 +138039,10 @@ pub struct IDropTarget_Vtbl { } #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_SystemServices"))] pub trait IDropTarget_Impl: windows_core::IUnknownImpl { - fn DragEnter(&self, pdataobj: windows_core::Ref, grfkeystate: super::SystemServices::MODIFIERKEYS_FLAGS, pt: &super::super::Foundation::POINTL, pdweffect: *mut DROPEFFECT) -> windows_core::Result<()>; + fn DragEnter(&self, pdataobj: windows_core::Ref<'_, super::Com::IDataObject>, grfkeystate: super::SystemServices::MODIFIERKEYS_FLAGS, pt: &super::super::Foundation::POINTL, pdweffect: *mut DROPEFFECT) -> windows_core::Result<()>; fn DragOver(&self, grfkeystate: super::SystemServices::MODIFIERKEYS_FLAGS, pt: &super::super::Foundation::POINTL, pdweffect: *mut DROPEFFECT) -> windows_core::Result<()>; fn DragLeave(&self) -> windows_core::Result<()>; - fn Drop(&self, pdataobj: windows_core::Ref, grfkeystate: super::SystemServices::MODIFIERKEYS_FLAGS, pt: &super::super::Foundation::POINTL, pdweffect: *mut DROPEFFECT) -> windows_core::Result<()>; + fn Drop(&self, pdataobj: windows_core::Ref<'_, super::Com::IDataObject>, grfkeystate: super::SystemServices::MODIFIERKEYS_FLAGS, pt: &super::super::Foundation::POINTL, pdweffect: *mut DROPEFFECT) -> windows_core::Result<()>; } #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_SystemServices"))] impl IDropTarget_Vtbl { @@ -47431,6 +138087,91 @@ impl IDropTarget_Vtbl { impl windows_core::RuntimeName for IDropTarget {} windows_core::imp::define_interface!(IRecordInfo, IRecordInfo_Vtbl, 0x0000002f_0000_0000_c000_000000000046); windows_core::imp::interface_hierarchy!(IRecordInfo, windows_core::IUnknown); +impl IRecordInfo { + pub unsafe fn RecordInit(&self, pvnew: *mut core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RecordInit)(windows_core::Interface::as_raw(self), pvnew as _).ok() } + } + pub unsafe fn RecordClear(&self, pvexisting: *const core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RecordClear)(windows_core::Interface::as_raw(self), pvexisting).ok() } + } + pub unsafe fn RecordCopy(&self, pvexisting: *const core::ffi::c_void, pvnew: *mut core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RecordCopy)(windows_core::Interface::as_raw(self), pvexisting, pvnew as _).ok() } + } + pub unsafe fn GetGuid(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetGuid)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + pub unsafe fn GetName(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetName)(windows_core::Interface::as_raw(self), &mut result__).map(|| core::mem::transmute(result__)) + } + } + pub unsafe fn GetSize(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetSize)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) + } + } + #[cfg(feature = "Win32_System_Com")] + pub unsafe fn GetTypeInfo(&self) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetTypeInfo)(windows_core::Interface::as_raw(self), &mut result__).and_then(|| windows_core::Type::from_abi(result__)) + } + } + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Variant"))] + pub unsafe fn GetField(&self, pvdata: *const core::ffi::c_void, szfieldname: P1) -> windows_core::Result + where + P1: windows_core::Param, + { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetField)(windows_core::Interface::as_raw(self), pvdata, szfieldname.param().abi(), &mut result__).map(|| core::mem::transmute(result__)) + } + } + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Variant"))] + pub unsafe fn GetFieldNoCopy(&self, pvdata: *const core::ffi::c_void, szfieldname: P1, pvarfield: *mut super::Variant::VARIANT, ppvdatacarray: *mut *mut core::ffi::c_void) -> windows_core::Result<()> + where + P1: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).GetFieldNoCopy)(windows_core::Interface::as_raw(self), pvdata, szfieldname.param().abi(), core::mem::transmute(pvarfield), ppvdatacarray as _).ok() } + } + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Variant"))] + pub unsafe fn PutField(&self, wflags: u32, pvdata: *mut core::ffi::c_void, szfieldname: P2, pvarfield: *const super::Variant::VARIANT) -> windows_core::Result<()> + where + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).PutField)(windows_core::Interface::as_raw(self), wflags, pvdata as _, szfieldname.param().abi(), core::mem::transmute(pvarfield)).ok() } + } + #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Variant"))] + pub unsafe fn PutFieldNoCopy(&self, wflags: u32, pvdata: *mut core::ffi::c_void, szfieldname: P2, pvarfield: *const super::Variant::VARIANT) -> windows_core::Result<()> + where + P2: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).PutFieldNoCopy)(windows_core::Interface::as_raw(self), wflags, pvdata as _, szfieldname.param().abi(), core::mem::transmute(pvarfield)).ok() } + } + pub unsafe fn GetFieldNames(&self, pcnames: *mut u32, rgbstrnames: *mut windows_core::BSTR) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetFieldNames)(windows_core::Interface::as_raw(self), pcnames as _, core::mem::transmute(rgbstrnames)).ok() } + } + pub unsafe fn IsMatchingType(&self, precordinfo: P0) -> windows_core::BOOL + where + P0: windows_core::Param, + { + unsafe { (windows_core::Interface::vtable(self).IsMatchingType)(windows_core::Interface::as_raw(self), precordinfo.param().abi()) } + } + pub unsafe fn RecordCreate(&self) -> *mut core::ffi::c_void { + unsafe { (windows_core::Interface::vtable(self).RecordCreate)(windows_core::Interface::as_raw(self)) } + } + pub unsafe fn RecordCreateCopy(&self, pvsource: *const core::ffi::c_void, ppvdest: *mut *mut core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RecordCreateCopy)(windows_core::Interface::as_raw(self), pvsource, ppvdest as _).ok() } + } + pub unsafe fn RecordDestroy(&self, pvrecord: *const core::ffi::c_void) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).RecordDestroy)(windows_core::Interface::as_raw(self), pvrecord).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IRecordInfo_Vtbl { @@ -47481,7 +138222,7 @@ pub trait IRecordInfo_Impl: windows_core::IUnknownImpl { fn PutField(&self, wflags: u32, pvdata: *mut core::ffi::c_void, szfieldname: &windows_core::PCWSTR, pvarfield: *const super::Variant::VARIANT) -> windows_core::Result<()>; fn PutFieldNoCopy(&self, wflags: u32, pvdata: *mut core::ffi::c_void, szfieldname: &windows_core::PCWSTR, pvarfield: *const super::Variant::VARIANT) -> windows_core::Result<()>; fn GetFieldNames(&self, pcnames: *mut u32, rgbstrnames: *mut windows_core::BSTR) -> windows_core::Result<()>; - fn IsMatchingType(&self, precordinfo: windows_core::Ref) -> windows_core::BOOL; + fn IsMatchingType(&self, precordinfo: windows_core::Ref<'_, IRecordInfo>) -> windows_core::BOOL; fn RecordCreate(&self) -> *mut core::ffi::c_void; fn RecordCreateCopy(&self, pvsource: *const core::ffi::c_void, ppvdest: *mut *mut core::ffi::c_void) -> windows_core::Result<()>; fn RecordDestroy(&self, pvrecord: *const core::ffi::c_void) -> windows_core::Result<()>; @@ -47641,9 +138382,6 @@ impl IRecordInfo_Vtbl { } #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Variant"))] impl windows_core::RuntimeName for IRecordInfo {} -#[repr(transparent)] -#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] -pub struct PARAMFLAGS(pub u16); #[repr(C)] #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Variant"))] #[derive(Clone, Copy, Debug, PartialEq)] @@ -47651,41 +138389,44 @@ pub struct PARAMDESC { pub pparamdescex: *mut PARAMDESCEX, pub wParamFlags: PARAMFLAGS, } -#[repr(C)] -#[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Variant"))] -pub struct PARAMDESCEX { - pub cBytes: u32, - pub varDefaultValue: super::Variant::VARIANT, -} -impl PARAMFLAGS { - pub const fn contains(&self, other: Self) -> bool { - self.0 & other.0 == other.0 - } -} #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Variant"))] impl Default for PARAMDESC { fn default() -> Self { unsafe { core::mem::zeroed() } } } +#[repr(C)] +#[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Variant"))] +pub struct PARAMDESCEX { + pub cBytes: u32, + pub varDefaultValue: super::Variant::VARIANT, +} #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Variant"))] impl Clone for PARAMDESCEX { fn clone(&self) -> Self { unsafe { core::mem::transmute_copy(self) } } } -impl core::ops::BitOr for PARAMFLAGS { - type Output = Self; - fn bitor(self, other: Self) -> Self { - Self(self.0 | other.0) - } -} #[cfg(all(feature = "Win32_System_Com", feature = "Win32_System_Variant"))] impl Default for PARAMDESCEX { fn default() -> Self { unsafe { core::mem::zeroed() } } } +#[repr(transparent)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct PARAMFLAGS(pub u16); +impl PARAMFLAGS { + pub const fn contains(&self, other: Self) -> bool { + self.0 & other.0 == other.0 + } +} +impl core::ops::BitOr for PARAMFLAGS { + type Output = Self; + fn bitor(self, other: Self) -> Self { + Self(self.0 | other.0) + } +} impl core::ops::BitAnd for PARAMFLAGS { type Output = Self; fn bitand(self, other: Self) -> Self { @@ -47709,6 +138450,7 @@ impl core::ops::Not for PARAMFLAGS { } } } +#[cfg(feature = "Win32_System_Performance")] pub mod Performance{ #[inline] pub unsafe fn QueryPerformanceCounter(lpperformancecount: *mut i64) -> windows_core::Result<()> { @@ -47721,6 +138463,7 @@ pub unsafe fn QueryPerformanceFrequency(lpfrequency: *mut i64) -> windows_core:: unsafe { QueryPerformanceFrequency(lpfrequency as _).ok() } } } +#[cfg(feature = "Win32_System_Pipes")] pub mod Pipes{ #[cfg(feature = "Win32_Security")] #[inline] @@ -47729,6 +138472,7 @@ pub unsafe fn CreatePipe(hreadpipe: *mut super::super::Foundation::HANDLE, hwrit unsafe { CreatePipe(hreadpipe as _, hwritepipe as _, lppipeattributes.unwrap_or(core::mem::zeroed()) as _, nsize).ok() } } } +#[cfg(feature = "Win32_System_SystemServices")] pub mod SystemServices{ pub const MK_CONTROL: MODIFIERKEYS_FLAGS = MODIFIERKEYS_FLAGS(8u32); pub const MK_LBUTTON: MODIFIERKEYS_FLAGS = MODIFIERKEYS_FLAGS(1u32); @@ -47770,6 +138514,7 @@ impl core::ops::Not for MODIFIERKEYS_FLAGS { } } } +#[cfg(feature = "Win32_System_Threading")] pub mod Threading{ #[inline] pub unsafe fn AvSetMmThreadCharacteristicsW(taskname: P0, taskindex: *mut u32) -> windows_core::Result @@ -47975,6 +138720,7 @@ impl core::ops::Not for STARTUPINFOW_FLAGS { } } } +#[cfg(feature = "Win32_System_Variant")] pub mod Variant{ #[repr(transparent)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] @@ -48139,6 +138885,7 @@ impl Default for VARIANT_0_0_0_0 { } pub const VT_UI8: VARENUM = VARENUM(21u16); } +#[cfg(feature = "Win32_System_WinRT")] pub mod WinRT{ windows_core::imp::define_interface!(IBufferByteAccess, IBufferByteAccess_Vtbl, 0x905a0fef_bc53_11df_8c49_001e4fc686da); windows_core::imp::interface_hierarchy!(IBufferByteAccess, windows_core::IUnknown); @@ -48181,11 +138928,14 @@ impl IBufferByteAccess_Vtbl { } impl windows_core::RuntimeName for IBufferByteAccess {} } +#[cfg(feature = "Win32_System_WindowsProgramming")] pub mod WindowsProgramming{ pub const GMEM_DDESHARE: u32 = 8192u32; } } +#[cfg(feature = "Win32_UI")] pub mod UI{ +#[cfg(feature = "Win32_UI_Controls")] pub mod Controls{ #[repr(C)] #[derive(Clone, Copy, Debug, Default, PartialEq)] @@ -48197,6 +138947,7 @@ pub struct MARGINS { } pub const WM_MOUSELEAVE: u32 = 675u32; } +#[cfg(feature = "Win32_UI_HiDpi")] pub mod HiDpi{ #[repr(transparent)] #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -48222,7 +138973,9 @@ pub struct MONITOR_DPI_TYPE(pub i32); pub struct PROCESS_DPI_AWARENESS(pub i32); pub const PROCESS_PER_MONITOR_DPI_AWARE: PROCESS_DPI_AWARENESS = PROCESS_DPI_AWARENESS(2i32); } +#[cfg(feature = "Win32_UI_Input")] pub mod Input{ +#[cfg(feature = "Win32_UI_Input_Ime")] pub mod Ime{ #[inline] pub unsafe fn ImmAssociateContext(param0: super::super::super::Foundation::HWND, param1: HIMC) -> HIMC { @@ -48325,6 +139078,7 @@ impl core::ops::Not for IME_COMPOSITION_STRING { } } } +#[cfg(feature = "Win32_UI_Input_KeyboardAndMouse")] pub mod KeyboardAndMouse{ #[inline] pub unsafe fn GetKeyState(nvirtkey: i32) -> i16 { @@ -48526,6 +139280,7 @@ pub const VK_X: VIRTUAL_KEY = VIRTUAL_KEY(88u16); pub const VK_Y: VIRTUAL_KEY = VIRTUAL_KEY(89u16); pub const VK_Z: VIRTUAL_KEY = VIRTUAL_KEY(90u16); } +#[cfg(feature = "Win32_UI_Input_XboxController")] pub mod XboxController{ #[inline] pub unsafe fn XInputGetState(dwuserindex: u32, pstate: *mut XINPUT_STATE) -> u32 { @@ -48601,14 +139356,13 @@ pub struct XINPUT_STATE { } } } +#[cfg(feature = "Win32_UI_Shell")] pub mod Shell{ +#[cfg(feature = "Win32_System_Com")] #[inline] pub unsafe fn SHCreateMemStream(pinit: Option<&[u8]>) -> Option { - windows_core::link!("shlwapi.dll" "system" fn SHCreateMemStream(pinit : *const u8, cbinit : u32) -> * mut core::ffi::c_void); - unsafe { - let result__ = SHCreateMemStream(pinit.map_or(core::ptr::null(), |slice| slice.as_ptr()), pinit.map_or(0u32, |slice| slice.len() as u32)); - windows_core::Type::from_abi(result__).ok() - } + windows_core::link!("shlwapi.dll" "system" fn SHCreateMemStream(pinit : *const u8, cbinit : u32) -> Option < super::super::System::Com:: IStream >); + unsafe { SHCreateMemStream(core::mem::transmute(pinit.as_deref().map_or(core::ptr::null(), |slice| slice.as_ptr())), pinit.as_deref().map_or(0, |slice| slice.len().try_into().unwrap())) } } #[inline] pub unsafe fn SHGetKnownFolderPath(rfid: *const windows_core::GUID, dwflags: KNOWN_FOLDER_FLAG, htoken: Option) -> windows_core::Result { @@ -48656,6 +139410,7 @@ impl core::ops::Not for KNOWN_FOLDER_FLAG { Self(self.0.not()) } } +#[cfg(feature = "Win32_UI_Shell_PropertiesSystem")] pub mod PropertiesSystem{ windows_core::imp::define_interface!(IPropertyStore, IPropertyStore_Vtbl, 0x886d8eeb_8cf2_4446_8d02_cdba1dbdcf99); windows_core::imp::interface_hierarchy!(IPropertyStore, windows_core::IUnknown); @@ -48666,6 +139421,9 @@ impl IPropertyStore { (windows_core::Interface::vtable(self).GetCount)(windows_core::Interface::as_raw(self), &mut result__).map(|| result__) } } + pub unsafe fn GetAt(&self, iprop: u32, pkey: *mut super::super::super::Foundation::PROPERTYKEY) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetAt)(windows_core::Interface::as_raw(self), iprop, pkey as _).ok() } + } #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] pub unsafe fn GetValue(&self, key: *const super::super::super::Foundation::PROPERTYKEY) -> windows_core::Result { unsafe { @@ -48673,7 +139431,14 @@ impl IPropertyStore { (windows_core::Interface::vtable(self).GetValue)(windows_core::Interface::as_raw(self), key, &mut result__).map(|| core::mem::transmute(result__)) } } + #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] + pub unsafe fn SetValue(&self, key: *const super::super::super::Foundation::PROPERTYKEY, propvar: *const super::super::super::System::Com::StructuredStorage::PROPVARIANT) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetValue)(windows_core::Interface::as_raw(self), key, core::mem::transmute(propvar)).ok() } } + pub unsafe fn Commit(&self) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).Commit)(windows_core::Interface::as_raw(self)).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IPropertyStore_Vtbl { @@ -48766,6 +139531,25 @@ impl core::ops::Deref for IPropertyStoreCache { } } windows_core::imp::interface_hierarchy!(IPropertyStoreCache, windows_core::IUnknown, IPropertyStore); +impl IPropertyStoreCache { + pub unsafe fn GetState(&self, key: *const super::super::super::Foundation::PROPERTYKEY) -> windows_core::Result { + unsafe { + let mut result__ = core::mem::zeroed(); + (windows_core::Interface::vtable(self).GetState)(windows_core::Interface::as_raw(self), key, &mut result__).map(|| result__) + } + } + #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] + pub unsafe fn GetValueAndState(&self, key: *const super::super::super::Foundation::PROPERTYKEY, ppropvar: *mut super::super::super::System::Com::StructuredStorage::PROPVARIANT, pstate: *mut PSC_STATE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).GetValueAndState)(windows_core::Interface::as_raw(self), key, core::mem::transmute(ppropvar), pstate as _).ok() } + } + pub unsafe fn SetState(&self, key: *const super::super::super::Foundation::PROPERTYKEY, state: PSC_STATE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetState)(windows_core::Interface::as_raw(self), key, state).ok() } + } + #[cfg(all(feature = "Win32_System_Com_StructuredStorage", feature = "Win32_System_Variant"))] + pub unsafe fn SetValueAndState(&self, key: *const super::super::super::Foundation::PROPERTYKEY, ppropvar: *const super::super::super::System::Com::StructuredStorage::PROPVARIANT, state: PSC_STATE) -> windows_core::Result<()> { + unsafe { (windows_core::Interface::vtable(self).SetValueAndState)(windows_core::Interface::as_raw(self), key, core::mem::transmute(ppropvar), state).ok() } + } +} #[repr(C)] #[doc(hidden)] pub struct IPropertyStoreCache_Vtbl { @@ -48840,6 +139624,7 @@ impl windows_core::RuntimeName for IPropertyStoreCache {} pub struct PSC_STATE(pub i32); } } +#[cfg(feature = "Win32_UI_WindowsAndMessaging")] pub mod WindowsAndMessaging{ #[inline] pub unsafe fn AdjustWindowRectEx(lprect: *mut super::super::Foundation::RECT, dwstyle: WINDOW_STYLE, bmenu: bool, dwexstyle: WINDOW_EX_STYLE) -> windows_core::Result<()> { @@ -49511,7 +140296,7 @@ pub const WM_XBUTTONDOWN: u32 = 523u32; pub const WM_XBUTTONUP: u32 = 524u32; #[repr(C)] #[cfg(feature = "Win32_Graphics_Gdi")] -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] pub struct WNDCLASSEXW { pub cbSize: u32, pub style: WNDCLASS_STYLES, diff --git a/tools/windows_bindgen/Cargo.toml b/tools/windows_bindgen/Cargo.toml new file mode 100644 index 000000000..c86c7219f --- /dev/null +++ b/tools/windows_bindgen/Cargo.toml @@ -0,0 +1,13 @@ +# Regenerates libs/windows/windows-rs/src/Windows/mod.rs from filter.txt. +# Standalone on purpose: windows-bindgen and its metadata are build tooling, +# not something any app should link. +[package] +name = "makepad-windows-bindgen" +version = "0.1.0" +edition = "2021" +publish = false + +[workspace] + +[dependencies] +windows-bindgen = "=0.62.1" diff --git a/tools/windows_bindgen/filter.txt b/tools/windows_bindgen/filter.txt new file mode 100644 index 000000000..80fe31d18 --- /dev/null +++ b/tools/windows_bindgen/filter.txt @@ -0,0 +1,2213 @@ +# The Windows APIs this repo uses, one fully-qualified item or namespace per +# line. tools/windows_bindgen turns this into libs/windows/windows-rs/src/Windows/mod.rs +# (windows-bindgen 0.62.1, --package --implement, upstream rustfmt width). +# Metadata dependencies of listed items come along automatically; a member +# whose type is not reachable is skipped by the generator, which is fine. +# +# Add what you need, rerun the tool, and cross-check the consumers with +# `cargo check --target x86_64-pc-windows-msvc` (platform, platform/video, +# platform/network, libs/system_speech, libs/terminal_core, apps/mpterm). + +# ---- the OS speech engines (makepad-system-speech) ---- +Windows.Globalization.Language +Windows.Media.SpeechRecognition +Windows.Media.SpeechSynthesis + +# ---- everything the platform, video, network and terminal crates use ---- +Windows.ApplicationModel.Background.ActivitySensorTrigger +Windows.ApplicationModel.Background.AppBroadcastTrigger +Windows.ApplicationModel.Background.AppBroadcastTriggerProviderInfo +Windows.ApplicationModel.Background.ApplicationTrigger +Windows.ApplicationModel.Background.ApplicationTriggerResult +Windows.ApplicationModel.Background.AppointmentStoreNotificationTrigger +Windows.ApplicationModel.Background.BluetoothLEAdvertisementPublisherTrigger +Windows.ApplicationModel.Background.BluetoothLEAdvertisementWatcherTrigger +Windows.ApplicationModel.Background.CachedFileUpdaterTrigger +Windows.ApplicationModel.Background.ChatMessageNotificationTrigger +Windows.ApplicationModel.Background.ChatMessageReceivedNotificationTrigger +Windows.ApplicationModel.Background.CommunicationBlockingAppSetAsActiveTrigger +Windows.ApplicationModel.Background.ContactStoreNotificationTrigger +Windows.ApplicationModel.Background.ContentPrefetchTrigger +Windows.ApplicationModel.Background.ConversationalAgentTrigger +Windows.ApplicationModel.Background.CustomSystemEventTrigger +Windows.ApplicationModel.Background.CustomSystemEventTriggerRecurrence +Windows.ApplicationModel.Background.DeviceConnectionChangeTrigger +Windows.ApplicationModel.Background.DeviceManufacturerNotificationTrigger +Windows.ApplicationModel.Background.DeviceServicingTrigger +Windows.ApplicationModel.Background.DeviceTriggerResult +Windows.ApplicationModel.Background.DeviceUseTrigger +Windows.ApplicationModel.Background.DeviceWatcherTrigger +Windows.ApplicationModel.Background.EmailStoreNotificationTrigger +Windows.ApplicationModel.Background.GattCharacteristicNotificationTrigger +Windows.ApplicationModel.Background.GattServiceProviderTrigger +Windows.ApplicationModel.Background.GattServiceProviderTriggerResult +Windows.ApplicationModel.Background.GeovisitTrigger +Windows.ApplicationModel.Background.IActivitySensorTrigger +Windows.ApplicationModel.Background.IActivitySensorTriggerFactory +Windows.ApplicationModel.Background.IAppBroadcastTrigger +Windows.ApplicationModel.Background.IAppBroadcastTriggerFactory +Windows.ApplicationModel.Background.IAppBroadcastTriggerProviderInfo +Windows.ApplicationModel.Background.IApplicationTrigger +Windows.ApplicationModel.Background.IAppointmentStoreNotificationTrigger +Windows.ApplicationModel.Background.IBackgroundTrigger +Windows.ApplicationModel.Background.IBluetoothLEAdvertisementPublisherTrigger +Windows.ApplicationModel.Background.IBluetoothLEAdvertisementPublisherTrigger2 +Windows.ApplicationModel.Background.IBluetoothLEAdvertisementWatcherTrigger +Windows.ApplicationModel.Background.IBluetoothLEAdvertisementWatcherTrigger2 +Windows.ApplicationModel.Background.ICachedFileUpdaterTrigger +Windows.ApplicationModel.Background.IChatMessageNotificationTrigger +Windows.ApplicationModel.Background.IChatMessageReceivedNotificationTrigger +Windows.ApplicationModel.Background.ICommunicationBlockingAppSetAsActiveTrigger +Windows.ApplicationModel.Background.IContactStoreNotificationTrigger +Windows.ApplicationModel.Background.IContentPrefetchTrigger +Windows.ApplicationModel.Background.IContentPrefetchTriggerFactory +Windows.ApplicationModel.Background.ICustomSystemEventTrigger +Windows.ApplicationModel.Background.ICustomSystemEventTriggerFactory +Windows.ApplicationModel.Background.IDeviceConnectionChangeTrigger +Windows.ApplicationModel.Background.IDeviceConnectionChangeTriggerStatics +Windows.ApplicationModel.Background.IDeviceManufacturerNotificationTrigger +Windows.ApplicationModel.Background.IDeviceManufacturerNotificationTriggerFactory +Windows.ApplicationModel.Background.IDeviceServicingTrigger +Windows.ApplicationModel.Background.IDeviceUseTrigger +Windows.ApplicationModel.Background.IDeviceWatcherTrigger +Windows.ApplicationModel.Background.IEmailStoreNotificationTrigger +Windows.ApplicationModel.Background.IGattCharacteristicNotificationTrigger +Windows.ApplicationModel.Background.IGattCharacteristicNotificationTrigger2 +Windows.ApplicationModel.Background.IGattCharacteristicNotificationTriggerFactory +Windows.ApplicationModel.Background.IGattCharacteristicNotificationTriggerFactory2 +Windows.ApplicationModel.Background.IGattServiceProviderTrigger +Windows.ApplicationModel.Background.IGattServiceProviderTriggerResult +Windows.ApplicationModel.Background.IGattServiceProviderTriggerStatics +Windows.ApplicationModel.Background.IGeovisitTrigger +Windows.ApplicationModel.Background.ILocationTrigger +Windows.ApplicationModel.Background.ILocationTriggerFactory +Windows.ApplicationModel.Background.IMaintenanceTrigger +Windows.ApplicationModel.Background.IMaintenanceTriggerFactory +Windows.ApplicationModel.Background.IMediaProcessingTrigger +Windows.ApplicationModel.Background.INetworkOperatorHotspotAuthenticationTrigger +Windows.ApplicationModel.Background.INetworkOperatorNotificationTrigger +Windows.ApplicationModel.Background.INetworkOperatorNotificationTriggerFactory +Windows.ApplicationModel.Background.IPhoneTrigger +Windows.ApplicationModel.Background.IPhoneTriggerFactory +Windows.ApplicationModel.Background.IPushNotificationTriggerFactory +Windows.ApplicationModel.Background.IRcsEndUserMessageAvailableTrigger +Windows.ApplicationModel.Background.IRfcommConnectionTrigger +Windows.ApplicationModel.Background.ISecondaryAuthenticationFactorAuthenticationTrigger +Windows.ApplicationModel.Background.ISensorDataThresholdTrigger +Windows.ApplicationModel.Background.ISensorDataThresholdTriggerFactory +Windows.ApplicationModel.Background.ISmartCardTrigger +Windows.ApplicationModel.Background.ISmartCardTriggerFactory +Windows.ApplicationModel.Background.ISmsMessageReceivedTriggerFactory +Windows.ApplicationModel.Background.ISocketActivityTrigger +Windows.ApplicationModel.Background.IStorageLibraryChangeTrackerTriggerFactory +Windows.ApplicationModel.Background.IStorageLibraryContentChangedTrigger +Windows.ApplicationModel.Background.IStorageLibraryContentChangedTriggerStatics +Windows.ApplicationModel.Background.ISystemTrigger +Windows.ApplicationModel.Background.ISystemTriggerFactory +Windows.ApplicationModel.Background.ITimeTrigger +Windows.ApplicationModel.Background.ITimeTriggerFactory +Windows.ApplicationModel.Background.IToastNotificationActionTriggerFactory +Windows.ApplicationModel.Background.IToastNotificationHistoryChangedTriggerFactory +Windows.ApplicationModel.Background.IUserNotificationChangedTriggerFactory +Windows.ApplicationModel.Background.LocationTrigger +Windows.ApplicationModel.Background.LocationTriggerType +Windows.ApplicationModel.Background.MaintenanceTrigger +Windows.ApplicationModel.Background.MediaProcessingTrigger +Windows.ApplicationModel.Background.MediaProcessingTriggerResult +Windows.ApplicationModel.Background.MobileBroadbandDeviceServiceNotificationTrigger +Windows.ApplicationModel.Background.MobileBroadbandPcoDataChangeTrigger +Windows.ApplicationModel.Background.MobileBroadbandPinLockStateChangeTrigger +Windows.ApplicationModel.Background.MobileBroadbandRadioStateChangeTrigger +Windows.ApplicationModel.Background.MobileBroadbandRegistrationStateChangeTrigger +Windows.ApplicationModel.Background.NetworkOperatorDataUsageTrigger +Windows.ApplicationModel.Background.NetworkOperatorHotspotAuthenticationTrigger +Windows.ApplicationModel.Background.NetworkOperatorNotificationTrigger +Windows.ApplicationModel.Background.PaymentAppCanMakePaymentTrigger +Windows.ApplicationModel.Background.PhoneTrigger +Windows.ApplicationModel.Background.PushNotificationTrigger +Windows.ApplicationModel.Background.RcsEndUserMessageAvailableTrigger +Windows.ApplicationModel.Background.RfcommConnectionTrigger +Windows.ApplicationModel.Background.SecondaryAuthenticationFactorAuthenticationTrigger +Windows.ApplicationModel.Background.SensorDataThresholdTrigger +Windows.ApplicationModel.Background.SmartCardTrigger +Windows.ApplicationModel.Background.SmsMessageReceivedTrigger +Windows.ApplicationModel.Background.SocketActivityTrigger +Windows.ApplicationModel.Background.StorageLibraryChangeTrackerTrigger +Windows.ApplicationModel.Background.StorageLibraryContentChangedTrigger +Windows.ApplicationModel.Background.SystemTrigger +Windows.ApplicationModel.Background.SystemTriggerType +Windows.ApplicationModel.Background.TetheringEntitlementCheckTrigger +Windows.ApplicationModel.Background.TimeTrigger +Windows.ApplicationModel.Background.ToastNotificationActionTrigger +Windows.ApplicationModel.Background.ToastNotificationHistoryChangedTrigger +Windows.ApplicationModel.Background.UserNotificationChangedTrigger +Windows.ApplicationModel.Background.WiFiOnDemandHotspotConnectTrigger +Windows.ApplicationModel.Background.WiFiOnDemandHotspotUpdateMetadataTrigger +Windows.ApplicationModel.Calls.Background.PhoneTriggerType +Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisement +Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementBytePattern +Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementDataSection +Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementFilter +Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementFlags +Windows.Devices.Bluetooth.Advertisement.BluetoothLEManufacturerData +Windows.Devices.Bluetooth.Advertisement.IBluetoothLEAdvertisement +Windows.Devices.Bluetooth.Advertisement.IBluetoothLEAdvertisementBytePattern +Windows.Devices.Bluetooth.Advertisement.IBluetoothLEAdvertisementBytePatternFactory +Windows.Devices.Bluetooth.Advertisement.IBluetoothLEAdvertisementDataSection +Windows.Devices.Bluetooth.Advertisement.IBluetoothLEAdvertisementDataSectionFactory +Windows.Devices.Bluetooth.Advertisement.IBluetoothLEAdvertisementFilter +Windows.Devices.Bluetooth.Advertisement.IBluetoothLEManufacturerData +Windows.Devices.Bluetooth.Advertisement.IBluetoothLEManufacturerDataFactory +Windows.Devices.Bluetooth.Background.BluetoothEventTriggeringMode +Windows.Devices.Bluetooth.Background.IRfcommInboundConnectionInformation +Windows.Devices.Bluetooth.Background.IRfcommOutboundConnectionInformation +Windows.Devices.Bluetooth.Background.RfcommInboundConnectionInformation +Windows.Devices.Bluetooth.Background.RfcommOutboundConnectionInformation +Windows.Devices.Bluetooth.BluetoothAddressType +Windows.Devices.Bluetooth.BluetoothCacheMode +Windows.Devices.Bluetooth.BluetoothConnectionStatus +Windows.Devices.Bluetooth.BluetoothDeviceId +Windows.Devices.Bluetooth.BluetoothError +Windows.Devices.Bluetooth.BluetoothLEAppearance +Windows.Devices.Bluetooth.BluetoothLEConnectionParameters +Windows.Devices.Bluetooth.BluetoothLEConnectionPhy +Windows.Devices.Bluetooth.BluetoothLEConnectionPhyInfo +Windows.Devices.Bluetooth.BluetoothLEDevice +Windows.Devices.Bluetooth.BluetoothLEPreferredConnectionParameters +Windows.Devices.Bluetooth.BluetoothLEPreferredConnectionParametersRequest +Windows.Devices.Bluetooth.BluetoothLEPreferredConnectionParametersRequestStatus +Windows.Devices.Bluetooth.BluetoothServiceCapabilities +Windows.Devices.Bluetooth.BluetoothSignalStrengthFilter +Windows.Devices.Bluetooth.GenericAttributeProfile.GattCharacteristic +Windows.Devices.Bluetooth.GenericAttributeProfile.GattCharacteristicProperties +Windows.Devices.Bluetooth.GenericAttributeProfile.GattCharacteristicsResult +Windows.Devices.Bluetooth.GenericAttributeProfile.GattClientCharacteristicConfigurationDescriptorValue +Windows.Devices.Bluetooth.GenericAttributeProfile.GattClientNotificationResult +Windows.Devices.Bluetooth.GenericAttributeProfile.GattCommunicationStatus +Windows.Devices.Bluetooth.GenericAttributeProfile.GattDescriptor +Windows.Devices.Bluetooth.GenericAttributeProfile.GattDescriptorsResult +Windows.Devices.Bluetooth.GenericAttributeProfile.GattDeviceService +Windows.Devices.Bluetooth.GenericAttributeProfile.GattDeviceServicesResult +Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalCharacteristic +Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalCharacteristicParameters +Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalCharacteristicResult +Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalDescriptor +Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalDescriptorParameters +Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalDescriptorResult +Windows.Devices.Bluetooth.GenericAttributeProfile.GattLocalService +Windows.Devices.Bluetooth.GenericAttributeProfile.GattOpenStatus +Windows.Devices.Bluetooth.GenericAttributeProfile.GattPresentationFormat +Windows.Devices.Bluetooth.GenericAttributeProfile.GattProtectionLevel +Windows.Devices.Bluetooth.GenericAttributeProfile.GattReadClientCharacteristicConfigurationDescriptorResult +Windows.Devices.Bluetooth.GenericAttributeProfile.GattReadRequest +Windows.Devices.Bluetooth.GenericAttributeProfile.GattReadRequestedEventArgs +Windows.Devices.Bluetooth.GenericAttributeProfile.GattReadResult +Windows.Devices.Bluetooth.GenericAttributeProfile.GattRequestState +Windows.Devices.Bluetooth.GenericAttributeProfile.GattRequestStateChangedEventArgs +Windows.Devices.Bluetooth.GenericAttributeProfile.GattServiceProviderAdvertisingParameters +Windows.Devices.Bluetooth.GenericAttributeProfile.GattSession +Windows.Devices.Bluetooth.GenericAttributeProfile.GattSessionStatus +Windows.Devices.Bluetooth.GenericAttributeProfile.GattSessionStatusChangedEventArgs +Windows.Devices.Bluetooth.GenericAttributeProfile.GattSharingMode +Windows.Devices.Bluetooth.GenericAttributeProfile.GattSubscribedClient +Windows.Devices.Bluetooth.GenericAttributeProfile.GattValueChangedEventArgs +Windows.Devices.Bluetooth.GenericAttributeProfile.GattWriteOption +Windows.Devices.Bluetooth.GenericAttributeProfile.GattWriteRequest +Windows.Devices.Bluetooth.GenericAttributeProfile.GattWriteRequestedEventArgs +Windows.Devices.Bluetooth.GenericAttributeProfile.GattWriteResult +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattCharacteristic +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattCharacteristic2 +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattCharacteristic3 +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattCharacteristicStatics +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattCharacteristicsResult +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattClientNotificationResult +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattClientNotificationResult2 +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDescriptor +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDescriptor2 +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDescriptorStatics +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDescriptorsResult +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDeviceService +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDeviceService2 +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDeviceService3 +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDeviceServiceStatics +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDeviceServiceStatics2 +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattDeviceServicesResult +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattLocalCharacteristic +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattLocalCharacteristicParameters +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattLocalCharacteristicResult +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattLocalDescriptor +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattLocalDescriptorParameters +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattLocalDescriptorResult +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattLocalService +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattPresentationFormat +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattPresentationFormatStatics +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattPresentationFormatStatics2 +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattReadClientCharacteristicConfigurationDescriptorResult +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattReadClientCharacteristicConfigurationDescriptorResult2 +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattReadRequest +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattReadRequestedEventArgs +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattReadResult +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattReadResult2 +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattRequestStateChangedEventArgs +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattServiceProviderAdvertisingParameters +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattServiceProviderAdvertisingParameters2 +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattSession +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattSessionStatics +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattSessionStatusChangedEventArgs +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattSubscribedClient +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattValueChangedEventArgs +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattWriteRequest +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattWriteRequestedEventArgs +Windows.Devices.Bluetooth.GenericAttributeProfile.IGattWriteResult +Windows.Devices.Bluetooth.IBluetoothDeviceId +Windows.Devices.Bluetooth.IBluetoothDeviceIdStatics +Windows.Devices.Bluetooth.IBluetoothLEAppearance +Windows.Devices.Bluetooth.IBluetoothLEAppearanceStatics +Windows.Devices.Bluetooth.IBluetoothLEConnectionParameters +Windows.Devices.Bluetooth.IBluetoothLEConnectionPhy +Windows.Devices.Bluetooth.IBluetoothLEConnectionPhyInfo +Windows.Devices.Bluetooth.IBluetoothLEDevice +Windows.Devices.Bluetooth.IBluetoothLEDevice2 +Windows.Devices.Bluetooth.IBluetoothLEDevice3 +Windows.Devices.Bluetooth.IBluetoothLEDevice4 +Windows.Devices.Bluetooth.IBluetoothLEDevice5 +Windows.Devices.Bluetooth.IBluetoothLEDevice6 +Windows.Devices.Bluetooth.IBluetoothLEDeviceStatics +Windows.Devices.Bluetooth.IBluetoothLEDeviceStatics2 +Windows.Devices.Bluetooth.IBluetoothLEPreferredConnectionParameters +Windows.Devices.Bluetooth.IBluetoothLEPreferredConnectionParametersRequest +Windows.Devices.Bluetooth.IBluetoothLEPreferredConnectionParametersStatics +Windows.Devices.Bluetooth.IBluetoothSignalStrengthFilter +Windows.Devices.Bluetooth.Rfcomm.IRfcommServiceId +Windows.Devices.Bluetooth.Rfcomm.IRfcommServiceIdStatics +Windows.Devices.Bluetooth.Rfcomm.RfcommServiceId +Windows.Devices.Enumeration.DeviceAccessChangedEventArgs +Windows.Devices.Enumeration.DeviceAccessInformation +Windows.Devices.Enumeration.DeviceAccessStatus +Windows.Devices.Enumeration.DeviceClass +Windows.Devices.Enumeration.DeviceInformation +Windows.Devices.Enumeration.DeviceInformationCollection +Windows.Devices.Enumeration.DeviceInformationCustomPairing +Windows.Devices.Enumeration.DeviceInformationKind +Windows.Devices.Enumeration.DeviceInformationPairing +Windows.Devices.Enumeration.DeviceInformationUpdate +Windows.Devices.Enumeration.DevicePairingAddPairingSetMemberStatus +Windows.Devices.Enumeration.DevicePairingKinds +Windows.Devices.Enumeration.DevicePairingProtectionLevel +Windows.Devices.Enumeration.DevicePairingRequestedEventArgs +Windows.Devices.Enumeration.DevicePairingResult +Windows.Devices.Enumeration.DevicePairingResultStatus +Windows.Devices.Enumeration.DevicePairingSetMembersRequestedEventArgs +Windows.Devices.Enumeration.DeviceThumbnail +Windows.Devices.Enumeration.DeviceUnpairingResult +Windows.Devices.Enumeration.DeviceUnpairingResultStatus +Windows.Devices.Enumeration.DeviceWatcher +Windows.Devices.Enumeration.DeviceWatcherEventKind +Windows.Devices.Enumeration.DeviceWatcherStatus +Windows.Devices.Enumeration.EnclosureLocation +Windows.Devices.Enumeration.IDeviceAccessChangedEventArgs +Windows.Devices.Enumeration.IDeviceAccessChangedEventArgs2 +Windows.Devices.Enumeration.IDeviceAccessChangedEventArgs3 +Windows.Devices.Enumeration.IDeviceAccessInformation +Windows.Devices.Enumeration.IDeviceAccessInformation2 +Windows.Devices.Enumeration.IDeviceAccessInformationStatics +Windows.Devices.Enumeration.IDeviceEnumerationSettings +Windows.Devices.Enumeration.IDeviceInformation +Windows.Devices.Enumeration.IDeviceInformation2 +Windows.Devices.Enumeration.IDeviceInformationCustomPairing +Windows.Devices.Enumeration.IDeviceInformationCustomPairing2 +Windows.Devices.Enumeration.IDeviceInformationPairing +Windows.Devices.Enumeration.IDeviceInformationPairing2 +Windows.Devices.Enumeration.IDeviceInformationPairingStatics +Windows.Devices.Enumeration.IDeviceInformationPairingStatics2 +Windows.Devices.Enumeration.IDeviceInformationStatics +Windows.Devices.Enumeration.IDeviceInformationStatics2 +Windows.Devices.Enumeration.IDeviceInformationStatics3 +Windows.Devices.Enumeration.IDeviceInformationUpdate +Windows.Devices.Enumeration.IDeviceInformationUpdate2 +Windows.Devices.Enumeration.IDevicePairingRequestedEventArgs +Windows.Devices.Enumeration.IDevicePairingRequestedEventArgs2 +Windows.Devices.Enumeration.IDevicePairingRequestedEventArgs3 +Windows.Devices.Enumeration.IDevicePairingResult +Windows.Devices.Enumeration.IDevicePairingSetMembersRequestedEventArgs +Windows.Devices.Enumeration.IDevicePairingSettings +Windows.Devices.Enumeration.IDeviceUnpairingResult +Windows.Devices.Enumeration.IDeviceWatcher +Windows.Devices.Enumeration.IDeviceWatcher2 +Windows.Devices.Enumeration.IEnclosureLocation +Windows.Devices.Enumeration.IEnclosureLocation2 +Windows.Devices.Enumeration.Panel +Windows.Devices.Geolocation.VisitMonitoringScope +Windows.Devices.Midi.IMidiChannelPressureMessage +Windows.Devices.Midi.IMidiChannelPressureMessageFactory +Windows.Devices.Midi.IMidiControlChangeMessage +Windows.Devices.Midi.IMidiControlChangeMessageFactory +Windows.Devices.Midi.IMidiInPort +Windows.Devices.Midi.IMidiInPortStatics +Windows.Devices.Midi.IMidiMessage +Windows.Devices.Midi.IMidiMessageReceivedEventArgs +Windows.Devices.Midi.IMidiNoteOffMessage +Windows.Devices.Midi.IMidiNoteOffMessageFactory +Windows.Devices.Midi.IMidiNoteOnMessage +Windows.Devices.Midi.IMidiNoteOnMessageFactory +Windows.Devices.Midi.IMidiOutPort +Windows.Devices.Midi.IMidiOutPortStatics +Windows.Devices.Midi.IMidiPitchBendChangeMessage +Windows.Devices.Midi.IMidiPitchBendChangeMessageFactory +Windows.Devices.Midi.IMidiPolyphonicKeyPressureMessage +Windows.Devices.Midi.IMidiPolyphonicKeyPressureMessageFactory +Windows.Devices.Midi.IMidiProgramChangeMessage +Windows.Devices.Midi.IMidiProgramChangeMessageFactory +Windows.Devices.Midi.IMidiSongPositionPointerMessage +Windows.Devices.Midi.IMidiSongPositionPointerMessageFactory +Windows.Devices.Midi.IMidiSongSelectMessage +Windows.Devices.Midi.IMidiSongSelectMessageFactory +Windows.Devices.Midi.IMidiSynthesizer +Windows.Devices.Midi.IMidiSynthesizerStatics +Windows.Devices.Midi.IMidiSystemExclusiveMessageFactory +Windows.Devices.Midi.IMidiTimeCodeMessage +Windows.Devices.Midi.IMidiTimeCodeMessageFactory +Windows.Devices.Midi.MidiActiveSensingMessage +Windows.Devices.Midi.MidiChannelPressureMessage +Windows.Devices.Midi.MidiContinueMessage +Windows.Devices.Midi.MidiControlChangeMessage +Windows.Devices.Midi.MidiInPort +Windows.Devices.Midi.MidiMessageReceivedEventArgs +Windows.Devices.Midi.MidiMessageType +Windows.Devices.Midi.MidiNoteOffMessage +Windows.Devices.Midi.MidiNoteOnMessage +Windows.Devices.Midi.MidiOutPort +Windows.Devices.Midi.MidiPitchBendChangeMessage +Windows.Devices.Midi.MidiPolyphonicKeyPressureMessage +Windows.Devices.Midi.MidiProgramChangeMessage +Windows.Devices.Midi.MidiSongPositionPointerMessage +Windows.Devices.Midi.MidiSongSelectMessage +Windows.Devices.Midi.MidiStartMessage +Windows.Devices.Midi.MidiStopMessage +Windows.Devices.Midi.MidiSynthesizer +Windows.Devices.Midi.MidiSystemExclusiveMessage +Windows.Devices.Midi.MidiSystemResetMessage +Windows.Devices.Midi.MidiTimeCodeMessage +Windows.Devices.Midi.MidiTimingClockMessage +Windows.Devices.Midi.MidiTuneRequestMessage +Windows.Devices.Sensors.Accelerometer +Windows.Devices.Sensors.AccelerometerDataThreshold +Windows.Devices.Sensors.AccelerometerReading +Windows.Devices.Sensors.AccelerometerReadingChangedEventArgs +Windows.Devices.Sensors.AccelerometerReadingType +Windows.Devices.Sensors.AccelerometerShakenEventArgs +Windows.Devices.Sensors.ActivitySensor +Windows.Devices.Sensors.ActivitySensorReading +Windows.Devices.Sensors.ActivitySensorReadingChangedEventArgs +Windows.Devices.Sensors.ActivitySensorReadingConfidence +Windows.Devices.Sensors.ActivityType +Windows.Devices.Sensors.Barometer +Windows.Devices.Sensors.BarometerDataThreshold +Windows.Devices.Sensors.BarometerReading +Windows.Devices.Sensors.BarometerReadingChangedEventArgs +Windows.Devices.Sensors.Compass +Windows.Devices.Sensors.CompassDataThreshold +Windows.Devices.Sensors.CompassReading +Windows.Devices.Sensors.CompassReadingChangedEventArgs +Windows.Devices.Sensors.IAccelerometer +Windows.Devices.Sensors.IAccelerometer2 +Windows.Devices.Sensors.IAccelerometer3 +Windows.Devices.Sensors.IAccelerometer4 +Windows.Devices.Sensors.IAccelerometer5 +Windows.Devices.Sensors.IAccelerometerDataThreshold +Windows.Devices.Sensors.IAccelerometerDeviceId +Windows.Devices.Sensors.IAccelerometerReading +Windows.Devices.Sensors.IAccelerometerReading2 +Windows.Devices.Sensors.IAccelerometerReadingChangedEventArgs +Windows.Devices.Sensors.IAccelerometerShakenEventArgs +Windows.Devices.Sensors.IAccelerometerStatics +Windows.Devices.Sensors.IAccelerometerStatics2 +Windows.Devices.Sensors.IAccelerometerStatics3 +Windows.Devices.Sensors.IActivitySensor +Windows.Devices.Sensors.IActivitySensorReading +Windows.Devices.Sensors.IActivitySensorReadingChangedEventArgs +Windows.Devices.Sensors.IActivitySensorStatics +Windows.Devices.Sensors.IBarometer +Windows.Devices.Sensors.IBarometer2 +Windows.Devices.Sensors.IBarometer3 +Windows.Devices.Sensors.IBarometerDataThreshold +Windows.Devices.Sensors.IBarometerReading +Windows.Devices.Sensors.IBarometerReading2 +Windows.Devices.Sensors.IBarometerReadingChangedEventArgs +Windows.Devices.Sensors.IBarometerStatics +Windows.Devices.Sensors.IBarometerStatics2 +Windows.Devices.Sensors.ICompass +Windows.Devices.Sensors.ICompass2 +Windows.Devices.Sensors.ICompass3 +Windows.Devices.Sensors.ICompass4 +Windows.Devices.Sensors.ICompassDataThreshold +Windows.Devices.Sensors.ICompassDeviceId +Windows.Devices.Sensors.ICompassReading +Windows.Devices.Sensors.ICompassReading2 +Windows.Devices.Sensors.ICompassReadingChangedEventArgs +Windows.Devices.Sensors.ICompassReadingHeadingAccuracy +Windows.Devices.Sensors.ICompassStatics +Windows.Devices.Sensors.ICompassStatics2 +Windows.Devices.Sensors.IInclinometer +Windows.Devices.Sensors.IInclinometer2 +Windows.Devices.Sensors.IInclinometer3 +Windows.Devices.Sensors.IInclinometer4 +Windows.Devices.Sensors.IInclinometerDataThreshold +Windows.Devices.Sensors.IInclinometerDeviceId +Windows.Devices.Sensors.IInclinometerReading +Windows.Devices.Sensors.IInclinometerReading2 +Windows.Devices.Sensors.IInclinometerReadingChangedEventArgs +Windows.Devices.Sensors.IInclinometerReadingYawAccuracy +Windows.Devices.Sensors.IInclinometerStatics +Windows.Devices.Sensors.IInclinometerStatics2 +Windows.Devices.Sensors.IInclinometerStatics3 +Windows.Devices.Sensors.IInclinometerStatics4 +Windows.Devices.Sensors.ILightSensor +Windows.Devices.Sensors.ILightSensor2 +Windows.Devices.Sensors.ILightSensor3 +Windows.Devices.Sensors.ILightSensorDataThreshold +Windows.Devices.Sensors.ILightSensorDeviceId +Windows.Devices.Sensors.ILightSensorReading +Windows.Devices.Sensors.ILightSensorReading2 +Windows.Devices.Sensors.ILightSensorReadingChangedEventArgs +Windows.Devices.Sensors.ILightSensorStatics +Windows.Devices.Sensors.ILightSensorStatics2 +Windows.Devices.Sensors.IOrientationSensor +Windows.Devices.Sensors.IOrientationSensor2 +Windows.Devices.Sensors.IOrientationSensor3 +Windows.Devices.Sensors.IOrientationSensorDeviceId +Windows.Devices.Sensors.IOrientationSensorReading +Windows.Devices.Sensors.IOrientationSensorReading2 +Windows.Devices.Sensors.IOrientationSensorReadingChangedEventArgs +Windows.Devices.Sensors.IOrientationSensorReadingYawAccuracy +Windows.Devices.Sensors.IOrientationSensorStatics +Windows.Devices.Sensors.IOrientationSensorStatics2 +Windows.Devices.Sensors.IOrientationSensorStatics3 +Windows.Devices.Sensors.IOrientationSensorStatics4 +Windows.Devices.Sensors.IPedometer +Windows.Devices.Sensors.IPedometer2 +Windows.Devices.Sensors.IPedometerDataThresholdFactory +Windows.Devices.Sensors.IPedometerReading +Windows.Devices.Sensors.IPedometerReadingChangedEventArgs +Windows.Devices.Sensors.IPedometerStatics +Windows.Devices.Sensors.IPedometerStatics2 +Windows.Devices.Sensors.IProximitySensor +Windows.Devices.Sensors.IProximitySensorDataThresholdFactory +Windows.Devices.Sensors.IProximitySensorReading +Windows.Devices.Sensors.IProximitySensorReadingChangedEventArgs +Windows.Devices.Sensors.IProximitySensorStatics +Windows.Devices.Sensors.IProximitySensorStatics2 +Windows.Devices.Sensors.ISensorDataThreshold +Windows.Devices.Sensors.ISensorDataThresholdTriggerDetails +Windows.Devices.Sensors.ISensorQuaternion +Windows.Devices.Sensors.ISensorRotationMatrix +Windows.Devices.Sensors.ISimpleOrientationSensor +Windows.Devices.Sensors.ISimpleOrientationSensor2 +Windows.Devices.Sensors.ISimpleOrientationSensorDeviceId +Windows.Devices.Sensors.ISimpleOrientationSensorOrientationChangedEventArgs +Windows.Devices.Sensors.ISimpleOrientationSensorStatics +Windows.Devices.Sensors.ISimpleOrientationSensorStatics2 +Windows.Devices.Sensors.Inclinometer +Windows.Devices.Sensors.InclinometerDataThreshold +Windows.Devices.Sensors.InclinometerReading +Windows.Devices.Sensors.InclinometerReadingChangedEventArgs +Windows.Devices.Sensors.LightSensor +Windows.Devices.Sensors.LightSensorDataThreshold +Windows.Devices.Sensors.LightSensorReading +Windows.Devices.Sensors.LightSensorReadingChangedEventArgs +Windows.Devices.Sensors.MagnetometerAccuracy +Windows.Devices.Sensors.OrientationSensor +Windows.Devices.Sensors.OrientationSensorReading +Windows.Devices.Sensors.OrientationSensorReadingChangedEventArgs +Windows.Devices.Sensors.Pedometer +Windows.Devices.Sensors.PedometerDataThreshold +Windows.Devices.Sensors.PedometerReading +Windows.Devices.Sensors.PedometerReadingChangedEventArgs +Windows.Devices.Sensors.PedometerStepKind +Windows.Devices.Sensors.ProximitySensor +Windows.Devices.Sensors.ProximitySensorDataThreshold +Windows.Devices.Sensors.ProximitySensorDisplayOnOffController +Windows.Devices.Sensors.ProximitySensorReading +Windows.Devices.Sensors.ProximitySensorReadingChangedEventArgs +Windows.Devices.Sensors.SensorDataThresholdTriggerDetails +Windows.Devices.Sensors.SensorOptimizationGoal +Windows.Devices.Sensors.SensorQuaternion +Windows.Devices.Sensors.SensorReadingType +Windows.Devices.Sensors.SensorRotationMatrix +Windows.Devices.Sensors.SensorType +Windows.Devices.Sensors.SimpleOrientation +Windows.Devices.Sensors.SimpleOrientationSensor +Windows.Devices.Sensors.SimpleOrientationSensorOrientationChangedEventArgs +Windows.Devices.SmartCards.SmartCardTriggerType +Windows.Devices.Sms.CellularClass +Windows.Devices.Sms.ISmsFilterRule +Windows.Devices.Sms.ISmsFilterRuleFactory +Windows.Devices.Sms.ISmsFilterRules +Windows.Devices.Sms.ISmsFilterRulesFactory +Windows.Devices.Sms.SmsBroadcastType +Windows.Devices.Sms.SmsFilterActionType +Windows.Devices.Sms.SmsFilterRule +Windows.Devices.Sms.SmsFilterRules +Windows.Devices.Sms.SmsMessageType +Windows.Foundation.Collections.CollectionChange +Windows.Foundation.Collections.IMapChangedEventArgs +Windows.Foundation.Collections.IObservableMap +Windows.Foundation.Collections.IObservableVector +Windows.Foundation.Collections.IPropertySet +Windows.Foundation.Collections.IVectorChangedEventArgs +Windows.Foundation.Collections.MapChangedEventHandler +Windows.Foundation.Collections.PropertySet +Windows.Foundation.Collections.StringMap +Windows.Foundation.Collections.ValueSet +Windows.Foundation.Collections.VectorChangedEventHandler +Windows.Foundation.DateTime +Windows.Foundation.Deferral +Windows.Foundation.DeferralCompletedHandler +Windows.Foundation.IClosable +Windows.Foundation.IDeferral +Windows.Foundation.IDeferralFactory +Windows.Foundation.IMemoryBuffer +Windows.Foundation.IMemoryBufferFactory +Windows.Foundation.IMemoryBufferReference +Windows.Foundation.IPropertyValue +Windows.Foundation.IReference +Windows.Foundation.IReferenceArray +Windows.Foundation.IStringable +Windows.Foundation.IUriEscapeStatics +Windows.Foundation.IUriRuntimeClass +Windows.Foundation.IUriRuntimeClassFactory +Windows.Foundation.IUriRuntimeClassWithAbsoluteCanonicalUri +Windows.Foundation.IWwwFormUrlDecoderEntry +Windows.Foundation.IWwwFormUrlDecoderRuntimeClass +Windows.Foundation.IWwwFormUrlDecoderRuntimeClassFactory +Windows.Foundation.MemoryBuffer +Windows.Foundation.Point +Windows.Foundation.PropertyType +Windows.Foundation.Rect +Windows.Foundation.Size +Windows.Foundation.TimeSpan +Windows.Foundation.TypedEventHandler +Windows.Foundation.Uri +Windows.Foundation.WwwFormUrlDecoder +Windows.Foundation.WwwFormUrlDecoderEntry +Windows.Graphics.Display.DisplayOrientations +Windows.Networking.Connectivity.AttributedNetworkUsage +Windows.Networking.Connectivity.ConnectionCost +Windows.Networking.Connectivity.ConnectionProfile +Windows.Networking.Connectivity.ConnectionProfileDeleteStatus +Windows.Networking.Connectivity.ConnectivityInterval +Windows.Networking.Connectivity.DataPlanStatus +Windows.Networking.Connectivity.DataPlanUsage +Windows.Networking.Connectivity.DataUsage +Windows.Networking.Connectivity.DataUsageGranularity +Windows.Networking.Connectivity.DomainAuthenticationKind +Windows.Networking.Connectivity.DomainConnectivityLevel +Windows.Networking.Connectivity.IAttributedNetworkUsage +Windows.Networking.Connectivity.IConnectionCost +Windows.Networking.Connectivity.IConnectionCost2 +Windows.Networking.Connectivity.IConnectionProfile +Windows.Networking.Connectivity.IConnectionProfile2 +Windows.Networking.Connectivity.IConnectionProfile3 +Windows.Networking.Connectivity.IConnectionProfile4 +Windows.Networking.Connectivity.IConnectionProfile5 +Windows.Networking.Connectivity.IConnectionProfile6 +Windows.Networking.Connectivity.IConnectivityInterval +Windows.Networking.Connectivity.IDataPlanStatus +Windows.Networking.Connectivity.IDataPlanUsage +Windows.Networking.Connectivity.IDataUsage +Windows.Networking.Connectivity.INetworkAdapter +Windows.Networking.Connectivity.INetworkItem +Windows.Networking.Connectivity.INetworkSecuritySettings +Windows.Networking.Connectivity.INetworkUsage +Windows.Networking.Connectivity.IProviderNetworkUsage +Windows.Networking.Connectivity.IWlanConnectionProfileDetails +Windows.Networking.Connectivity.IWwanConnectionProfileDetails +Windows.Networking.Connectivity.IWwanConnectionProfileDetails2 +Windows.Networking.Connectivity.NetworkAdapter +Windows.Networking.Connectivity.NetworkAuthenticationType +Windows.Networking.Connectivity.NetworkConnectivityLevel +Windows.Networking.Connectivity.NetworkCostType +Windows.Networking.Connectivity.NetworkEncryptionType +Windows.Networking.Connectivity.NetworkItem +Windows.Networking.Connectivity.NetworkSecuritySettings +Windows.Networking.Connectivity.NetworkTypes +Windows.Networking.Connectivity.NetworkUsage +Windows.Networking.Connectivity.NetworkUsageStates +Windows.Networking.Connectivity.ProviderNetworkUsage +Windows.Networking.Connectivity.RoamingStates +Windows.Networking.Connectivity.TriStates +Windows.Networking.Connectivity.WlanConnectionProfileDetails +Windows.Networking.Connectivity.WwanConnectionProfileDetails +Windows.Networking.Connectivity.WwanDataClass +Windows.Networking.Connectivity.WwanNetworkIPKind +Windows.Networking.Connectivity.WwanNetworkRegistrationState +Windows.Networking.EndpointPair +Windows.Networking.HostName +Windows.Networking.HostNameSortOptions +Windows.Networking.HostNameType +Windows.Networking.IEndpointPair +Windows.Networking.IEndpointPairFactory +Windows.Networking.IHostName +Windows.Networking.IHostNameFactory +Windows.Networking.IHostNameStatics +Windows.Networking.Sockets.BandwidthStatistics +Windows.Networking.Sockets.ISocketActivityContext +Windows.Networking.Sockets.ISocketActivityContextFactory +Windows.Networking.Sockets.IStreamSocket +Windows.Networking.Sockets.IStreamSocket2 +Windows.Networking.Sockets.IStreamSocket3 +Windows.Networking.Sockets.IStreamSocketControl +Windows.Networking.Sockets.IStreamSocketControl2 +Windows.Networking.Sockets.IStreamSocketControl3 +Windows.Networking.Sockets.IStreamSocketControl4 +Windows.Networking.Sockets.IStreamSocketInformation +Windows.Networking.Sockets.IStreamSocketInformation2 +Windows.Networking.Sockets.IStreamSocketStatics +Windows.Networking.Sockets.RoundTripTimeStatistics +Windows.Networking.Sockets.SocketActivityConnectedStandbyAction +Windows.Networking.Sockets.SocketActivityContext +Windows.Networking.Sockets.SocketProtectionLevel +Windows.Networking.Sockets.SocketQualityOfService +Windows.Networking.Sockets.SocketSslErrorSeverity +Windows.Networking.Sockets.StreamSocket +Windows.Networking.Sockets.StreamSocketControl +Windows.Networking.Sockets.StreamSocketInformation +Windows.Security.Credentials.ICredentialFactory +Windows.Security.Credentials.IPasswordCredential +Windows.Security.Credentials.PasswordCredential +Windows.Security.Cryptography.Certificates.Certificate +Windows.Security.Cryptography.Certificates.CertificateChain +Windows.Security.Cryptography.Certificates.CertificateChainPolicy +Windows.Security.Cryptography.Certificates.CertificateExtension +Windows.Security.Cryptography.Certificates.CertificateKeyUsages +Windows.Security.Cryptography.Certificates.ChainBuildingParameters +Windows.Security.Cryptography.Certificates.ChainValidationParameters +Windows.Security.Cryptography.Certificates.ChainValidationResult +Windows.Security.Cryptography.Certificates.ICertificate +Windows.Security.Cryptography.Certificates.ICertificate2 +Windows.Security.Cryptography.Certificates.ICertificate3 +Windows.Security.Cryptography.Certificates.ICertificateChain +Windows.Security.Cryptography.Certificates.ICertificateExtension +Windows.Security.Cryptography.Certificates.ICertificateFactory +Windows.Security.Cryptography.Certificates.ICertificateKeyUsages +Windows.Security.Cryptography.Certificates.IChainBuildingParameters +Windows.Security.Cryptography.Certificates.IChainValidationParameters +Windows.Security.Cryptography.Certificates.ISubjectAlternativeNameInfo +Windows.Security.Cryptography.Certificates.ISubjectAlternativeNameInfo2 +Windows.Security.Cryptography.Certificates.SubjectAlternativeNameInfo +Windows.Storage.CreationCollisionOption +Windows.Storage.FileAccessMode +Windows.Storage.FileAttributes +Windows.Storage.IStorageFile +Windows.Storage.IStorageFile2 +Windows.Storage.IStorageFilePropertiesWithAvailability +Windows.Storage.IStorageFileStatics +Windows.Storage.IStorageFileStatics2 +Windows.Storage.IStorageFolder +Windows.Storage.IStorageItem +Windows.Storage.IStorageItem2 +Windows.Storage.IStorageItemProperties +Windows.Storage.IStorageItemProperties2 +Windows.Storage.IStorageItemPropertiesWithProvider +Windows.Storage.IStorageLibrary +Windows.Storage.IStorageLibrary2 +Windows.Storage.IStorageLibrary3 +Windows.Storage.IStorageLibraryChange +Windows.Storage.IStorageLibraryChangeReader +Windows.Storage.IStorageLibraryChangeReader2 +Windows.Storage.IStorageLibraryChangeTracker +Windows.Storage.IStorageLibraryChangeTracker2 +Windows.Storage.IStorageLibraryChangeTrackerOptions +Windows.Storage.IStorageLibraryStatics +Windows.Storage.IStorageLibraryStatics2 +Windows.Storage.IStorageProvider +Windows.Storage.IStorageProvider2 +Windows.Storage.IStorageStreamTransaction +Windows.Storage.IStreamedFileDataRequest +Windows.Storage.KnownLibraryId +Windows.Storage.NameCollisionOption +Windows.Storage.StorageDeleteOption +Windows.Storage.StorageFile +Windows.Storage.StorageItemTypes +Windows.Storage.StorageLibrary +Windows.Storage.StorageLibraryChange +Windows.Storage.StorageLibraryChangeReader +Windows.Storage.StorageLibraryChangeTracker +Windows.Storage.StorageLibraryChangeTrackerOptions +Windows.Storage.StorageLibraryChangeType +Windows.Storage.StorageOpenOptions +Windows.Storage.StorageProvider +Windows.Storage.StorageStreamTransaction +Windows.Storage.StreamedFileDataRequest +Windows.Storage.StreamedFileDataRequestedHandler +Windows.Storage.StreamedFileFailureMode +Windows.Storage.Streams.Buffer +Windows.Storage.Streams.ByteOrder +Windows.Storage.Streams.DataReader +Windows.Storage.Streams.DataReaderLoadOperation +Windows.Storage.Streams.DataWriter +Windows.Storage.Streams.DataWriterStoreOperation +Windows.Storage.Streams.FileInputStream +Windows.Storage.Streams.FileOpenDisposition +Windows.Storage.Streams.FileOutputStream +Windows.Storage.Streams.FileRandomAccessStream +Windows.Storage.Streams.IBuffer +Windows.Storage.Streams.IBufferFactory +Windows.Storage.Streams.IBufferStatics +Windows.Storage.Streams.IContentTypeProvider +Windows.Storage.Streams.IDataReader +Windows.Storage.Streams.IDataReaderFactory +Windows.Storage.Streams.IDataReaderStatics +Windows.Storage.Streams.IDataWriter +Windows.Storage.Streams.IDataWriterFactory +Windows.Storage.Streams.IFileRandomAccessStreamStatics +Windows.Storage.Streams.IInputStream +Windows.Storage.Streams.IInputStreamReference +Windows.Storage.Streams.IOutputStream +Windows.Storage.Streams.IRandomAccessStream +Windows.Storage.Streams.IRandomAccessStreamReference +Windows.Storage.Streams.IRandomAccessStreamReferenceStatics +Windows.Storage.Streams.IRandomAccessStreamWithContentType +Windows.Storage.Streams.InMemoryRandomAccessStream +Windows.Storage.Streams.InputStreamOptions +Windows.Storage.Streams.InputStreamOverStream +Windows.Storage.Streams.OutputStreamOverStream +Windows.Storage.Streams.RandomAccessStreamOverStream +Windows.Storage.Streams.RandomAccessStreamReference +Windows.Storage.Streams.UnicodeEncoding +Windows.System.IUser +Windows.System.IUser2 +Windows.System.IUserAuthenticationStatusChangeDeferral +Windows.System.IUserAuthenticationStatusChangingEventArgs +Windows.System.IUserChangedEventArgs +Windows.System.IUserChangedEventArgs2 +Windows.System.IUserStatics +Windows.System.IUserStatics2 +Windows.System.IUserWatcher +Windows.System.User +Windows.System.UserAgeConsentGroup +Windows.System.UserAgeConsentResult +Windows.System.UserAuthenticationStatus +Windows.System.UserAuthenticationStatusChangeDeferral +Windows.System.UserAuthenticationStatusChangingEventArgs +Windows.System.UserChangedEventArgs +Windows.System.UserPictureSize +Windows.System.UserType +Windows.System.UserWatcher +Windows.System.UserWatcherStatus +Windows.System.UserWatcherUpdateKind +Windows.UI.Notifications.NotificationKinds +Windows.Web.Http.Headers.HttpCacheDirectiveHeaderValueCollection +Windows.Web.Http.Headers.HttpChallengeHeaderValue +Windows.Web.Http.Headers.HttpChallengeHeaderValueCollection +Windows.Web.Http.Headers.HttpConnectionOptionHeaderValue +Windows.Web.Http.Headers.HttpConnectionOptionHeaderValueCollection +Windows.Web.Http.Headers.HttpContentCodingHeaderValue +Windows.Web.Http.Headers.HttpContentCodingHeaderValueCollection +Windows.Web.Http.Headers.HttpContentCodingWithQualityHeaderValue +Windows.Web.Http.Headers.HttpContentCodingWithQualityHeaderValueCollection +Windows.Web.Http.Headers.HttpContentDispositionHeaderValue +Windows.Web.Http.Headers.HttpContentHeaderCollection +Windows.Web.Http.Headers.HttpContentRangeHeaderValue +Windows.Web.Http.Headers.HttpCookiePairHeaderValue +Windows.Web.Http.Headers.HttpCookiePairHeaderValueCollection +Windows.Web.Http.Headers.HttpCredentialsHeaderValue +Windows.Web.Http.Headers.HttpDateOrDeltaHeaderValue +Windows.Web.Http.Headers.HttpExpectationHeaderValue +Windows.Web.Http.Headers.HttpExpectationHeaderValueCollection +Windows.Web.Http.Headers.HttpLanguageRangeWithQualityHeaderValue +Windows.Web.Http.Headers.HttpLanguageRangeWithQualityHeaderValueCollection +Windows.Web.Http.Headers.HttpMediaTypeHeaderValue +Windows.Web.Http.Headers.HttpMediaTypeWithQualityHeaderValue +Windows.Web.Http.Headers.HttpMediaTypeWithQualityHeaderValueCollection +Windows.Web.Http.Headers.HttpMethodHeaderValueCollection +Windows.Web.Http.Headers.HttpNameValueHeaderValue +Windows.Web.Http.Headers.HttpProductHeaderValue +Windows.Web.Http.Headers.HttpProductInfoHeaderValue +Windows.Web.Http.Headers.HttpProductInfoHeaderValueCollection +Windows.Web.Http.Headers.HttpRequestHeaderCollection +Windows.Web.Http.Headers.HttpResponseHeaderCollection +Windows.Web.Http.Headers.HttpTransferCodingHeaderValue +Windows.Web.Http.Headers.HttpTransferCodingHeaderValueCollection +Windows.Web.Http.Headers.IHttpCacheDirectiveHeaderValueCollection +Windows.Web.Http.Headers.IHttpChallengeHeaderValue +Windows.Web.Http.Headers.IHttpChallengeHeaderValueCollection +Windows.Web.Http.Headers.IHttpChallengeHeaderValueFactory +Windows.Web.Http.Headers.IHttpChallengeHeaderValueStatics +Windows.Web.Http.Headers.IHttpConnectionOptionHeaderValue +Windows.Web.Http.Headers.IHttpConnectionOptionHeaderValueCollection +Windows.Web.Http.Headers.IHttpConnectionOptionHeaderValueFactory +Windows.Web.Http.Headers.IHttpConnectionOptionHeaderValueStatics +Windows.Web.Http.Headers.IHttpContentCodingHeaderValue +Windows.Web.Http.Headers.IHttpContentCodingHeaderValueCollection +Windows.Web.Http.Headers.IHttpContentCodingHeaderValueFactory +Windows.Web.Http.Headers.IHttpContentCodingHeaderValueStatics +Windows.Web.Http.Headers.IHttpContentCodingWithQualityHeaderValue +Windows.Web.Http.Headers.IHttpContentCodingWithQualityHeaderValueCollection +Windows.Web.Http.Headers.IHttpContentCodingWithQualityHeaderValueFactory +Windows.Web.Http.Headers.IHttpContentCodingWithQualityHeaderValueStatics +Windows.Web.Http.Headers.IHttpContentDispositionHeaderValue +Windows.Web.Http.Headers.IHttpContentDispositionHeaderValueFactory +Windows.Web.Http.Headers.IHttpContentDispositionHeaderValueStatics +Windows.Web.Http.Headers.IHttpContentHeaderCollection +Windows.Web.Http.Headers.IHttpContentRangeHeaderValue +Windows.Web.Http.Headers.IHttpContentRangeHeaderValueFactory +Windows.Web.Http.Headers.IHttpContentRangeHeaderValueStatics +Windows.Web.Http.Headers.IHttpCookiePairHeaderValue +Windows.Web.Http.Headers.IHttpCookiePairHeaderValueCollection +Windows.Web.Http.Headers.IHttpCookiePairHeaderValueFactory +Windows.Web.Http.Headers.IHttpCookiePairHeaderValueStatics +Windows.Web.Http.Headers.IHttpCredentialsHeaderValue +Windows.Web.Http.Headers.IHttpCredentialsHeaderValueFactory +Windows.Web.Http.Headers.IHttpCredentialsHeaderValueStatics +Windows.Web.Http.Headers.IHttpDateOrDeltaHeaderValue +Windows.Web.Http.Headers.IHttpDateOrDeltaHeaderValueStatics +Windows.Web.Http.Headers.IHttpExpectationHeaderValue +Windows.Web.Http.Headers.IHttpExpectationHeaderValueCollection +Windows.Web.Http.Headers.IHttpExpectationHeaderValueFactory +Windows.Web.Http.Headers.IHttpExpectationHeaderValueStatics +Windows.Web.Http.Headers.IHttpLanguageRangeWithQualityHeaderValue +Windows.Web.Http.Headers.IHttpLanguageRangeWithQualityHeaderValueCollection +Windows.Web.Http.Headers.IHttpLanguageRangeWithQualityHeaderValueFactory +Windows.Web.Http.Headers.IHttpLanguageRangeWithQualityHeaderValueStatics +Windows.Web.Http.Headers.IHttpMediaTypeHeaderValue +Windows.Web.Http.Headers.IHttpMediaTypeHeaderValueFactory +Windows.Web.Http.Headers.IHttpMediaTypeHeaderValueStatics +Windows.Web.Http.Headers.IHttpMediaTypeWithQualityHeaderValue +Windows.Web.Http.Headers.IHttpMediaTypeWithQualityHeaderValueCollection +Windows.Web.Http.Headers.IHttpMediaTypeWithQualityHeaderValueFactory +Windows.Web.Http.Headers.IHttpMediaTypeWithQualityHeaderValueStatics +Windows.Web.Http.Headers.IHttpMethodHeaderValueCollection +Windows.Web.Http.Headers.IHttpNameValueHeaderValue +Windows.Web.Http.Headers.IHttpNameValueHeaderValueFactory +Windows.Web.Http.Headers.IHttpNameValueHeaderValueStatics +Windows.Web.Http.Headers.IHttpProductHeaderValue +Windows.Web.Http.Headers.IHttpProductHeaderValueFactory +Windows.Web.Http.Headers.IHttpProductHeaderValueStatics +Windows.Web.Http.Headers.IHttpProductInfoHeaderValue +Windows.Web.Http.Headers.IHttpProductInfoHeaderValueCollection +Windows.Web.Http.Headers.IHttpProductInfoHeaderValueFactory +Windows.Web.Http.Headers.IHttpProductInfoHeaderValueStatics +Windows.Web.Http.Headers.IHttpRequestHeaderCollection +Windows.Web.Http.Headers.IHttpResponseHeaderCollection +Windows.Web.Http.Headers.IHttpTransferCodingHeaderValue +Windows.Web.Http.Headers.IHttpTransferCodingHeaderValueCollection +Windows.Web.Http.Headers.IHttpTransferCodingHeaderValueFactory +Windows.Web.Http.Headers.IHttpTransferCodingHeaderValueStatics +Windows.Web.Http.HttpBufferContent +Windows.Web.Http.HttpClient +Windows.Web.Http.HttpCompletionOption +Windows.Web.Http.HttpFormUrlEncodedContent +Windows.Web.Http.HttpGetBufferResult +Windows.Web.Http.HttpGetInputStreamResult +Windows.Web.Http.HttpGetStringResult +Windows.Web.Http.HttpMethod +Windows.Web.Http.HttpMultipartContent +Windows.Web.Http.HttpMultipartFormDataContent +Windows.Web.Http.HttpProgress +Windows.Web.Http.HttpProgressStage +Windows.Web.Http.HttpRequestMessage +Windows.Web.Http.HttpRequestResult +Windows.Web.Http.HttpResponseMessage +Windows.Web.Http.HttpResponseMessageSource +Windows.Web.Http.HttpStatusCode +Windows.Web.Http.HttpStreamContent +Windows.Web.Http.HttpStringContent +Windows.Web.Http.HttpTransportInformation +Windows.Web.Http.HttpVersion +Windows.Web.Http.IHttpBufferContentFactory +Windows.Web.Http.IHttpClient +Windows.Web.Http.IHttpClient2 +Windows.Web.Http.IHttpClient3 +Windows.Web.Http.IHttpClientFactory +Windows.Web.Http.IHttpContent +Windows.Web.Http.IHttpFormUrlEncodedContentFactory +Windows.Web.Http.IHttpGetBufferResult +Windows.Web.Http.IHttpGetInputStreamResult +Windows.Web.Http.IHttpGetStringResult +Windows.Web.Http.IHttpMethod +Windows.Web.Http.IHttpMethodFactory +Windows.Web.Http.IHttpMethodStatics +Windows.Web.Http.IHttpMultipartContent +Windows.Web.Http.IHttpMultipartContentFactory +Windows.Web.Http.IHttpMultipartFormDataContent +Windows.Web.Http.IHttpMultipartFormDataContentFactory +Windows.Web.Http.IHttpRequestMessage +Windows.Web.Http.IHttpRequestMessage2 +Windows.Web.Http.IHttpRequestMessageFactory +Windows.Web.Http.IHttpRequestResult +Windows.Web.Http.IHttpResponseMessage +Windows.Web.Http.IHttpResponseMessageFactory +Windows.Web.Http.IHttpStreamContentFactory +Windows.Web.Http.IHttpStringContentFactory +Windows.Web.Http.IHttpTransportInformation +Windows.Win32.Devices.FunctionDiscovery.PKEY_Device_FriendlyName +Windows.Win32.Devices.HumanInterfaceDevice.DI8DEVCLASS_GAMECTRL +Windows.Win32.Devices.HumanInterfaceDevice.DI8DEVTYPE_DRIVING +Windows.Win32.Devices.HumanInterfaceDevice.DIACTIONFORMATW +Windows.Win32.Devices.HumanInterfaceDevice.DIACTIONW +Windows.Win32.Devices.HumanInterfaceDevice.DICOLORSET +Windows.Win32.Devices.HumanInterfaceDevice.DICONFIGUREDEVICESPARAMSW +Windows.Win32.Devices.HumanInterfaceDevice.DICONSTANTFORCE +Windows.Win32.Devices.HumanInterfaceDevice.DIDATAFORMAT +Windows.Win32.Devices.HumanInterfaceDevice.DIDEVCAPS +Windows.Win32.Devices.HumanInterfaceDevice.DIDEVICEIMAGEINFOHEADERW +Windows.Win32.Devices.HumanInterfaceDevice.DIDEVICEIMAGEINFOW +Windows.Win32.Devices.HumanInterfaceDevice.DIDEVICEINSTANCEW +Windows.Win32.Devices.HumanInterfaceDevice.DIDEVICEOBJECTDATA +Windows.Win32.Devices.HumanInterfaceDevice.DIDEVICEOBJECTINSTANCEW +Windows.Win32.Devices.HumanInterfaceDevice.DIDFT_ANYINSTANCE +Windows.Win32.Devices.HumanInterfaceDevice.DIDFT_AXIS +Windows.Win32.Devices.HumanInterfaceDevice.DIDFT_BUTTON +Windows.Win32.Devices.HumanInterfaceDevice.DIDFT_POV +Windows.Win32.Devices.HumanInterfaceDevice.DIDF_ABSAXIS +Windows.Win32.Devices.HumanInterfaceDevice.DIEB_NOTRIGGER +Windows.Win32.Devices.HumanInterfaceDevice.DIEDFL_ATTACHEDONLY +Windows.Win32.Devices.HumanInterfaceDevice.DIEFFECT +Windows.Win32.Devices.HumanInterfaceDevice.DIEFFECTINFOW +Windows.Win32.Devices.HumanInterfaceDevice.DIEFFESCAPE +Windows.Win32.Devices.HumanInterfaceDevice.DIEFF_CARTESIAN +Windows.Win32.Devices.HumanInterfaceDevice.DIEFF_OBJECTOFFSETS +Windows.Win32.Devices.HumanInterfaceDevice.DIENUM_CONTINUE +Windows.Win32.Devices.HumanInterfaceDevice.DIENVELOPE +Windows.Win32.Devices.HumanInterfaceDevice.DIEP_START +Windows.Win32.Devices.HumanInterfaceDevice.DIEP_TYPESPECIFICPARAMS +Windows.Win32.Devices.HumanInterfaceDevice.DIFILEEFFECT +Windows.Win32.Devices.HumanInterfaceDevice.DIJOYSTATE2 +Windows.Win32.Devices.HumanInterfaceDevice.DIOBJECTDATAFORMAT +Windows.Win32.Devices.HumanInterfaceDevice.DIPROPHEADER +Windows.Win32.Devices.HumanInterfaceDevice.DISCL_BACKGROUND +Windows.Win32.Devices.HumanInterfaceDevice.DISCL_EXCLUSIVE +Windows.Win32.Devices.HumanInterfaceDevice.DirectInput8Create +Windows.Win32.Devices.HumanInterfaceDevice.GUID_POV +Windows.Win32.Devices.HumanInterfaceDevice.GUID_RxAxis +Windows.Win32.Devices.HumanInterfaceDevice.GUID_RyAxis +Windows.Win32.Devices.HumanInterfaceDevice.GUID_RzAxis +Windows.Win32.Devices.HumanInterfaceDevice.GUID_Slider +Windows.Win32.Devices.HumanInterfaceDevice.GUID_XAxis +Windows.Win32.Devices.HumanInterfaceDevice.GUID_YAxis +Windows.Win32.Devices.HumanInterfaceDevice.GUID_ZAxis +Windows.Win32.Devices.HumanInterfaceDevice.IDirectInput8W +Windows.Win32.Devices.HumanInterfaceDevice.IDirectInputDevice8W +Windows.Win32.Devices.HumanInterfaceDevice.IDirectInputEffect +Windows.Win32.Devices.HumanInterfaceDevice.LPDICONFIGUREDEVICESCALLBACK +Windows.Win32.Devices.HumanInterfaceDevice.LPDIENUMCREATEDEFFECTOBJECTSCALLBACK +Windows.Win32.Devices.HumanInterfaceDevice.LPDIENUMDEVICEOBJECTSCALLBACKW +Windows.Win32.Devices.HumanInterfaceDevice.LPDIENUMDEVICESBYSEMANTICSCBW +Windows.Win32.Devices.HumanInterfaceDevice.LPDIENUMDEVICESCALLBACKW +Windows.Win32.Devices.HumanInterfaceDevice.LPDIENUMEFFECTSCALLBACKW +Windows.Win32.Devices.HumanInterfaceDevice.LPDIENUMEFFECTSINFILECALLBACK +Windows.Win32.Devices.Properties.DEVPROPTYPE +Windows.Win32.Foundation.COLORREF +Windows.Win32.Foundation.CloseHandle +Windows.Win32.Foundation.DATA_S_SAMEFORMATETC +Windows.Win32.Foundation.DECIMAL +Windows.Win32.Foundation.DEVPROPKEY +Windows.Win32.Foundation.DRAGDROP_S_CANCEL +Windows.Win32.Foundation.DRAGDROP_S_DROP +Windows.Win32.Foundation.DRAGDROP_S_USEDEFAULTCURSORS +Windows.Win32.Foundation.DV_E_DVASPECT +Windows.Win32.Foundation.DV_E_FORMATETC +Windows.Win32.Foundation.DV_E_LINDEX +Windows.Win32.Foundation.DV_E_TYMED +Windows.Win32.Foundation.E_NOTIMPL +Windows.Win32.Foundation.E_UNEXPECTED +Windows.Win32.Foundation.FARPROC +Windows.Win32.Foundation.FILETIME +Windows.Win32.Foundation.FreeLibrary +Windows.Win32.Foundation.GlobalFree +Windows.Win32.Foundation.HANDLE +Windows.Win32.Foundation.HANDLE_FLAGS +Windows.Win32.Foundation.HANDLE_FLAG_INHERIT +Windows.Win32.Foundation.HGLOBAL +Windows.Win32.Foundation.HINSTANCE +Windows.Win32.Foundation.HMODULE +Windows.Win32.Foundation.HWND +Windows.Win32.Foundation.LPARAM +Windows.Win32.Foundation.LRESULT +Windows.Win32.Foundation.LUID +Windows.Win32.Foundation.OLE_E_ADVISENOTSUPPORTED +Windows.Win32.Foundation.POINT +Windows.Win32.Foundation.POINTL +Windows.Win32.Foundation.PROPERTYKEY +Windows.Win32.Foundation.RECT +Windows.Win32.Foundation.SIZE +Windows.Win32.Foundation.S_FALSE +Windows.Win32.Foundation.S_OK +Windows.Win32.Foundation.SetHandleInformation +Windows.Win32.Foundation.VARIANT_BOOL +Windows.Win32.Foundation.WAIT_EVENT +Windows.Win32.Foundation.WAIT_OBJECT_0 +Windows.Win32.Foundation.WAIT_TIMEOUT +Windows.Win32.Foundation.WPARAM +Windows.Win32.Graphics.Direct3D.D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST +Windows.Win32.Graphics.Direct3D.D3D_DRIVER_TYPE +Windows.Win32.Graphics.Direct3D.D3D_DRIVER_TYPE_UNKNOWN +Windows.Win32.Graphics.Direct3D.D3D_FEATURE_LEVEL +Windows.Win32.Graphics.Direct3D.D3D_FEATURE_LEVEL_11_0 +Windows.Win32.Graphics.Direct3D.D3D_INCLUDE_TYPE +Windows.Win32.Graphics.Direct3D.D3D_PRIMITIVE_TOPOLOGY +Windows.Win32.Graphics.Direct3D.D3D_SHADER_MACRO +Windows.Win32.Graphics.Direct3D.D3D_SRV_DIMENSION +Windows.Win32.Graphics.Direct3D.D3D_SRV_DIMENSION_TEXTURECUBE +Windows.Win32.Graphics.Direct3D.Fxc.D3DCompile +Windows.Win32.Graphics.Direct3D.ID3DBlob +Windows.Win32.Graphics.Direct3D.ID3DInclude +Windows.Win32.Graphics.Direct3D11.D3D11CreateDevice +Windows.Win32.Graphics.Direct3D11.D3D11_AUTHENTICATED_CONFIGURE_OUTPUT +Windows.Win32.Graphics.Direct3D11.D3D11_BIND_CONSTANT_BUFFER +Windows.Win32.Graphics.Direct3D11.D3D11_BIND_DECODER +Windows.Win32.Graphics.Direct3D11.D3D11_BIND_DEPTH_STENCIL +Windows.Win32.Graphics.Direct3D11.D3D11_BIND_FLAG +Windows.Win32.Graphics.Direct3D11.D3D11_BIND_INDEX_BUFFER +Windows.Win32.Graphics.Direct3D11.D3D11_BIND_RENDER_TARGET +Windows.Win32.Graphics.Direct3D11.D3D11_BIND_SHADER_RESOURCE +Windows.Win32.Graphics.Direct3D11.D3D11_BIND_VERTEX_BUFFER +Windows.Win32.Graphics.Direct3D11.D3D11_BLEND +Windows.Win32.Graphics.Direct3D11.D3D11_BLEND_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_BLEND_DESC1 +Windows.Win32.Graphics.Direct3D11.D3D11_BLEND_INV_SRC_ALPHA +Windows.Win32.Graphics.Direct3D11.D3D11_BLEND_ONE +Windows.Win32.Graphics.Direct3D11.D3D11_BLEND_OP +Windows.Win32.Graphics.Direct3D11.D3D11_BLEND_OP_ADD +Windows.Win32.Graphics.Direct3D11.D3D11_BOX +Windows.Win32.Graphics.Direct3D11.D3D11_BUFFEREX_SRV +Windows.Win32.Graphics.Direct3D11.D3D11_BUFFER_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_BUFFER_RTV +Windows.Win32.Graphics.Direct3D11.D3D11_BUFFER_SRV +Windows.Win32.Graphics.Direct3D11.D3D11_BUFFER_UAV +Windows.Win32.Graphics.Direct3D11.D3D11_CLASS_INSTANCE_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_CLEAR_DEPTH +Windows.Win32.Graphics.Direct3D11.D3D11_CLEAR_FLAG +Windows.Win32.Graphics.Direct3D11.D3D11_CLEAR_STENCIL +Windows.Win32.Graphics.Direct3D11.D3D11_COLOR_WRITE_ENABLE +Windows.Win32.Graphics.Direct3D11.D3D11_COLOR_WRITE_ENABLE_ALL +Windows.Win32.Graphics.Direct3D11.D3D11_COMPARISON_ALWAYS +Windows.Win32.Graphics.Direct3D11.D3D11_COMPARISON_FUNC +Windows.Win32.Graphics.Direct3D11.D3D11_COMPARISON_LESS_EQUAL +Windows.Win32.Graphics.Direct3D11.D3D11_CONSERVATIVE_RASTERIZATION_MODE +Windows.Win32.Graphics.Direct3D11.D3D11_CONTEXT_TYPE +Windows.Win32.Graphics.Direct3D11.D3D11_COUNTER +Windows.Win32.Graphics.Direct3D11.D3D11_COUNTER_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_COUNTER_INFO +Windows.Win32.Graphics.Direct3D11.D3D11_COUNTER_TYPE +Windows.Win32.Graphics.Direct3D11.D3D11_CPU_ACCESS_FLAG +Windows.Win32.Graphics.Direct3D11.D3D11_CPU_ACCESS_WRITE +Windows.Win32.Graphics.Direct3D11.D3D11_CREATE_DEVICE_FLAG +Windows.Win32.Graphics.Direct3D11.D3D11_CRYPTO_SESSION_STATUS +Windows.Win32.Graphics.Direct3D11.D3D11_CULL_BACK +Windows.Win32.Graphics.Direct3D11.D3D11_CULL_MODE +Windows.Win32.Graphics.Direct3D11.D3D11_CULL_NONE +Windows.Win32.Graphics.Direct3D11.D3D11_DEPTH_STENCILOP_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_DEPTH_STENCIL_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_DEPTH_STENCIL_VIEW_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_DEPTH_WRITE_MASK +Windows.Win32.Graphics.Direct3D11.D3D11_DEPTH_WRITE_MASK_ALL +Windows.Win32.Graphics.Direct3D11.D3D11_DEPTH_WRITE_MASK_ZERO +Windows.Win32.Graphics.Direct3D11.D3D11_DEVICE_CONTEXT_TYPE +Windows.Win32.Graphics.Direct3D11.D3D11_DSV_DIMENSION +Windows.Win32.Graphics.Direct3D11.D3D11_DSV_DIMENSION_TEXTURE2D +Windows.Win32.Graphics.Direct3D11.D3D11_ENCRYPTED_BLOCK_INFO +Windows.Win32.Graphics.Direct3D11.D3D11_FEATURE +Windows.Win32.Graphics.Direct3D11.D3D11_FENCE_FLAG +Windows.Win32.Graphics.Direct3D11.D3D11_FILL_MODE +Windows.Win32.Graphics.Direct3D11.D3D11_FILL_SOLID +Windows.Win32.Graphics.Direct3D11.D3D11_FILTER +Windows.Win32.Graphics.Direct3D11.D3D11_INPUT_CLASSIFICATION +Windows.Win32.Graphics.Direct3D11.D3D11_INPUT_ELEMENT_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_INPUT_PER_INSTANCE_DATA +Windows.Win32.Graphics.Direct3D11.D3D11_INPUT_PER_VERTEX_DATA +Windows.Win32.Graphics.Direct3D11.D3D11_LOGIC_OP +Windows.Win32.Graphics.Direct3D11.D3D11_MAP +Windows.Win32.Graphics.Direct3D11.D3D11_MAPPED_SUBRESOURCE +Windows.Win32.Graphics.Direct3D11.D3D11_MAP_WRITE_DISCARD +Windows.Win32.Graphics.Direct3D11.D3D11_OMAC +Windows.Win32.Graphics.Direct3D11.D3D11_PACKED_MIP_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_QUERY +Windows.Win32.Graphics.Direct3D11.D3D11_QUERY_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_QUERY_DESC1 +Windows.Win32.Graphics.Direct3D11.D3D11_QUERY_EVENT +Windows.Win32.Graphics.Direct3D11.D3D11_RASTERIZER_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_RASTERIZER_DESC1 +Windows.Win32.Graphics.Direct3D11.D3D11_RASTERIZER_DESC2 +Windows.Win32.Graphics.Direct3D11.D3D11_RENDER_TARGET_BLEND_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_RENDER_TARGET_BLEND_DESC1 +Windows.Win32.Graphics.Direct3D11.D3D11_RENDER_TARGET_VIEW_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_RENDER_TARGET_VIEW_DESC1 +Windows.Win32.Graphics.Direct3D11.D3D11_RESOURCE_DIMENSION +Windows.Win32.Graphics.Direct3D11.D3D11_RESOURCE_MISC_FLAG +Windows.Win32.Graphics.Direct3D11.D3D11_RESOURCE_MISC_TEXTURECUBE +Windows.Win32.Graphics.Direct3D11.D3D11_RTV_DIMENSION +Windows.Win32.Graphics.Direct3D11.D3D11_RTV_DIMENSION_TEXTURE2DARRAY +Windows.Win32.Graphics.Direct3D11.D3D11_SAMPLER_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_SDK_VERSION +Windows.Win32.Graphics.Direct3D11.D3D11_SHADER_RESOURCE_VIEW_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_SHADER_RESOURCE_VIEW_DESC1 +Windows.Win32.Graphics.Direct3D11.D3D11_SO_DECLARATION_ENTRY +Windows.Win32.Graphics.Direct3D11.D3D11_STENCIL_OP +Windows.Win32.Graphics.Direct3D11.D3D11_STENCIL_OP_REPLACE +Windows.Win32.Graphics.Direct3D11.D3D11_SUBRESOURCE_DATA +Windows.Win32.Graphics.Direct3D11.D3D11_SUBRESOURCE_TILING +Windows.Win32.Graphics.Direct3D11.D3D11_TEX1D_ARRAY_DSV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX1D_ARRAY_RTV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX1D_ARRAY_SRV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX1D_ARRAY_UAV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX1D_DSV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX1D_RTV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX1D_SRV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX1D_UAV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2DMS_ARRAY_DSV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2DMS_ARRAY_RTV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2DMS_ARRAY_SRV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2DMS_DSV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2DMS_RTV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2DMS_SRV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_ARRAY_DSV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_ARRAY_RTV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_ARRAY_RTV1 +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_ARRAY_SRV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_ARRAY_SRV1 +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_ARRAY_UAV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_ARRAY_UAV1 +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_ARRAY_VPOV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_DSV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_RTV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_RTV1 +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_SRV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_SRV1 +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_UAV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_UAV1 +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_VDOV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_VPIV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX2D_VPOV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX3D_RTV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX3D_SRV +Windows.Win32.Graphics.Direct3D11.D3D11_TEX3D_UAV +Windows.Win32.Graphics.Direct3D11.D3D11_TEXCUBE_ARRAY_SRV +Windows.Win32.Graphics.Direct3D11.D3D11_TEXCUBE_SRV +Windows.Win32.Graphics.Direct3D11.D3D11_TEXTURE1D_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_TEXTURE2D_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_TEXTURE2D_DESC1 +Windows.Win32.Graphics.Direct3D11.D3D11_TEXTURE3D_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_TEXTURE3D_DESC1 +Windows.Win32.Graphics.Direct3D11.D3D11_TEXTURE_ADDRESS_MODE +Windows.Win32.Graphics.Direct3D11.D3D11_TEXTURE_LAYOUT +Windows.Win32.Graphics.Direct3D11.D3D11_TILED_RESOURCE_COORDINATE +Windows.Win32.Graphics.Direct3D11.D3D11_TILE_REGION_SIZE +Windows.Win32.Graphics.Direct3D11.D3D11_TILE_SHAPE +Windows.Win32.Graphics.Direct3D11.D3D11_UAV_DIMENSION +Windows.Win32.Graphics.Direct3D11.D3D11_UNORDERED_ACCESS_VIEW_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_UNORDERED_ACCESS_VIEW_DESC1 +Windows.Win32.Graphics.Direct3D11.D3D11_USAGE +Windows.Win32.Graphics.Direct3D11.D3D11_USAGE_DEFAULT +Windows.Win32.Graphics.Direct3D11.D3D11_USAGE_DYNAMIC +Windows.Win32.Graphics.Direct3D11.D3D11_VDOV_DIMENSION +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_COLOR +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_COLOR_RGBA +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_COLOR_YCbCrA +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_DECODER_BUFFER_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_DECODER_BUFFER_DESC1 +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_DECODER_BUFFER_DESC2 +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_DECODER_BUFFER_TYPE +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_DECODER_CONFIG +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_DECODER_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_DECODER_EXTENSION +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_DECODER_SUB_SAMPLE_MAPPING_BLOCK +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_FRAME_FORMAT +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_ALPHA_FILL_MODE +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_CAPS +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_COLOR_SPACE +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_CONTENT_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_CUSTOM_RATE +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_FILTER +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_FILTER_RANGE +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_OUTPUT_RATE +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_ROTATION +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_STEREO_FLIP_MODE +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_STEREO_FORMAT +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_STREAM +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_PROCESSOR_STREAM_BEHAVIOR_HINT +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_SAMPLE_DESC +Windows.Win32.Graphics.Direct3D11.D3D11_VIDEO_USAGE +Windows.Win32.Graphics.Direct3D11.D3D11_VIEWPORT +Windows.Win32.Graphics.Direct3D11.D3D11_VPIV_DIMENSION +Windows.Win32.Graphics.Direct3D11.D3D11_VPOV_DIMENSION +Windows.Win32.Graphics.Direct3D11.ID3D11Asynchronous +Windows.Win32.Graphics.Direct3D11.ID3D11AuthenticatedChannel +Windows.Win32.Graphics.Direct3D11.ID3D11BlendState +Windows.Win32.Graphics.Direct3D11.ID3D11BlendState1 +Windows.Win32.Graphics.Direct3D11.ID3D11Buffer +Windows.Win32.Graphics.Direct3D11.ID3D11ClassInstance +Windows.Win32.Graphics.Direct3D11.ID3D11ClassLinkage +Windows.Win32.Graphics.Direct3D11.ID3D11CommandList +Windows.Win32.Graphics.Direct3D11.ID3D11ComputeShader +Windows.Win32.Graphics.Direct3D11.ID3D11Counter +Windows.Win32.Graphics.Direct3D11.ID3D11CryptoSession +Windows.Win32.Graphics.Direct3D11.ID3D11DepthStencilState +Windows.Win32.Graphics.Direct3D11.ID3D11DepthStencilView +Windows.Win32.Graphics.Direct3D11.ID3D11Device +Windows.Win32.Graphics.Direct3D11.ID3D11Device1 +Windows.Win32.Graphics.Direct3D11.ID3D11Device2 +Windows.Win32.Graphics.Direct3D11.ID3D11Device3 +Windows.Win32.Graphics.Direct3D11.ID3D11Device4 +Windows.Win32.Graphics.Direct3D11.ID3D11Device5 +Windows.Win32.Graphics.Direct3D11.ID3D11DeviceChild +Windows.Win32.Graphics.Direct3D11.ID3D11DeviceContext +Windows.Win32.Graphics.Direct3D11.ID3D11DeviceContext1 +Windows.Win32.Graphics.Direct3D11.ID3D11DeviceContext2 +Windows.Win32.Graphics.Direct3D11.ID3D11DeviceContext3 +Windows.Win32.Graphics.Direct3D11.ID3D11DeviceContext4 +Windows.Win32.Graphics.Direct3D11.ID3D11DomainShader +Windows.Win32.Graphics.Direct3D11.ID3D11Fence +Windows.Win32.Graphics.Direct3D11.ID3D11GeometryShader +Windows.Win32.Graphics.Direct3D11.ID3D11HullShader +Windows.Win32.Graphics.Direct3D11.ID3D11InputLayout +Windows.Win32.Graphics.Direct3D11.ID3D11Multithread +Windows.Win32.Graphics.Direct3D11.ID3D11PixelShader +Windows.Win32.Graphics.Direct3D11.ID3D11Predicate +Windows.Win32.Graphics.Direct3D11.ID3D11Query +Windows.Win32.Graphics.Direct3D11.ID3D11Query1 +Windows.Win32.Graphics.Direct3D11.ID3D11RasterizerState +Windows.Win32.Graphics.Direct3D11.ID3D11RasterizerState1 +Windows.Win32.Graphics.Direct3D11.ID3D11RasterizerState2 +Windows.Win32.Graphics.Direct3D11.ID3D11RenderTargetView +Windows.Win32.Graphics.Direct3D11.ID3D11RenderTargetView1 +Windows.Win32.Graphics.Direct3D11.ID3D11Resource +Windows.Win32.Graphics.Direct3D11.ID3D11SamplerState +Windows.Win32.Graphics.Direct3D11.ID3D11ShaderResourceView +Windows.Win32.Graphics.Direct3D11.ID3D11ShaderResourceView1 +Windows.Win32.Graphics.Direct3D11.ID3D11Texture1D +Windows.Win32.Graphics.Direct3D11.ID3D11Texture2D +Windows.Win32.Graphics.Direct3D11.ID3D11Texture2D1 +Windows.Win32.Graphics.Direct3D11.ID3D11Texture3D +Windows.Win32.Graphics.Direct3D11.ID3D11Texture3D1 +Windows.Win32.Graphics.Direct3D11.ID3D11UnorderedAccessView +Windows.Win32.Graphics.Direct3D11.ID3D11UnorderedAccessView1 +Windows.Win32.Graphics.Direct3D11.ID3D11VertexShader +Windows.Win32.Graphics.Direct3D11.ID3D11VideoContext +Windows.Win32.Graphics.Direct3D11.ID3D11VideoContext1 +Windows.Win32.Graphics.Direct3D11.ID3D11VideoContext2 +Windows.Win32.Graphics.Direct3D11.ID3D11VideoContext3 +Windows.Win32.Graphics.Direct3D11.ID3D11VideoDecoder +Windows.Win32.Graphics.Direct3D11.ID3D11VideoDecoderOutputView +Windows.Win32.Graphics.Direct3D11.ID3D11VideoProcessor +Windows.Win32.Graphics.Direct3D11.ID3D11VideoProcessorEnumerator +Windows.Win32.Graphics.Direct3D11.ID3D11VideoProcessorEnumerator1 +Windows.Win32.Graphics.Direct3D11.ID3D11VideoProcessorInputView +Windows.Win32.Graphics.Direct3D11.ID3D11VideoProcessorOutputView +Windows.Win32.Graphics.Direct3D11.ID3D11View +Windows.Win32.Graphics.Direct3D11.ID3DDeviceContextState +Windows.Win32.Graphics.Dwm.DWMNCRENDERINGPOLICY +Windows.Win32.Graphics.Dwm.DWMNCRP_ENABLED +Windows.Win32.Graphics.Dwm.DWMSBT_MAINWINDOW +Windows.Win32.Graphics.Dwm.DWMSBT_NONE +Windows.Win32.Graphics.Dwm.DWMSBT_TABBEDWINDOW +Windows.Win32.Graphics.Dwm.DWMSBT_TRANSIENTWINDOW +Windows.Win32.Graphics.Dwm.DWMWA_BORDER_COLOR +Windows.Win32.Graphics.Dwm.DWMWA_COLOR_NONE +Windows.Win32.Graphics.Dwm.DWMWA_NCRENDERING_POLICY +Windows.Win32.Graphics.Dwm.DWMWA_SYSTEMBACKDROP_TYPE +Windows.Win32.Graphics.Dwm.DWMWA_WINDOW_CORNER_PREFERENCE +Windows.Win32.Graphics.Dwm.DWMWCP_ROUND +Windows.Win32.Graphics.Dwm.DWMWCP_ROUNDSMALL +Windows.Win32.Graphics.Dwm.DWMWINDOWATTRIBUTE +Windows.Win32.Graphics.Dwm.DWM_SYSTEMBACKDROP_TYPE +Windows.Win32.Graphics.Dwm.DWM_WINDOW_CORNER_PREFERENCE +Windows.Win32.Graphics.Dwm.DwmExtendFrameIntoClientArea +Windows.Win32.Graphics.Dwm.DwmSetWindowAttribute +Windows.Win32.Graphics.Dxgi.Common.DXGI_ALPHA_MODE +Windows.Win32.Graphics.Dxgi.Common.DXGI_ALPHA_MODE_IGNORE +Windows.Win32.Graphics.Dxgi.Common.DXGI_COLOR_SPACE_TYPE +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_B8G8R8A8_UNORM +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_D32_FLOAT +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_NV12 +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R16_FLOAT +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R32G32B32A32_FLOAT +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R32G32B32A32_SINT +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R32G32B32A32_UINT +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R32G32B32_FLOAT +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R32G32B32_SINT +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R32G32B32_UINT +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R32G32_FLOAT +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R32G32_SINT +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R32G32_UINT +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R32_FLOAT +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R32_SINT +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R32_UINT +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R8G8B8A8_UNORM +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R8G8_UNORM +Windows.Win32.Graphics.Dxgi.Common.DXGI_FORMAT_R8_UNORM +Windows.Win32.Graphics.Dxgi.Common.DXGI_GAMMA_CONTROL +Windows.Win32.Graphics.Dxgi.Common.DXGI_GAMMA_CONTROL_CAPABILITIES +Windows.Win32.Graphics.Dxgi.Common.DXGI_MODE_DESC +Windows.Win32.Graphics.Dxgi.Common.DXGI_MODE_ROTATION +Windows.Win32.Graphics.Dxgi.Common.DXGI_MODE_SCALING +Windows.Win32.Graphics.Dxgi.Common.DXGI_MODE_SCANLINE_ORDER +Windows.Win32.Graphics.Dxgi.Common.DXGI_RATIONAL +Windows.Win32.Graphics.Dxgi.Common.DXGI_RGB +Windows.Win32.Graphics.Dxgi.Common.DXGI_SAMPLE_DESC +Windows.Win32.Graphics.Dxgi.CreateDXGIFactory2 +Windows.Win32.Graphics.Dxgi.DXGI_ADAPTER_DESC +Windows.Win32.Graphics.Dxgi.DXGI_ADAPTER_DESC1 +Windows.Win32.Graphics.Dxgi.DXGI_ADAPTER_DESC2 +Windows.Win32.Graphics.Dxgi.DXGI_ADAPTER_DESC3 +Windows.Win32.Graphics.Dxgi.DXGI_ADAPTER_FLAG3 +Windows.Win32.Graphics.Dxgi.DXGI_COMPUTE_PREEMPTION_GRANULARITY +Windows.Win32.Graphics.Dxgi.DXGI_CREATE_FACTORY_FLAGS +Windows.Win32.Graphics.Dxgi.DXGI_ENUM_MODES +Windows.Win32.Graphics.Dxgi.DXGI_ERROR_WAS_STILL_DRAWING +Windows.Win32.Graphics.Dxgi.DXGI_FEATURE +Windows.Win32.Graphics.Dxgi.DXGI_FRAME_STATISTICS +Windows.Win32.Graphics.Dxgi.DXGI_GPU_PREFERENCE +Windows.Win32.Graphics.Dxgi.DXGI_GRAPHICS_PREEMPTION_GRANULARITY +Windows.Win32.Graphics.Dxgi.DXGI_HDR_METADATA_TYPE +Windows.Win32.Graphics.Dxgi.DXGI_MAPPED_RECT +Windows.Win32.Graphics.Dxgi.DXGI_MAP_FLAGS +Windows.Win32.Graphics.Dxgi.DXGI_MATRIX_3X2_F +Windows.Win32.Graphics.Dxgi.DXGI_MEMORY_SEGMENT_GROUP +Windows.Win32.Graphics.Dxgi.DXGI_MODE_DESC1 +Windows.Win32.Graphics.Dxgi.DXGI_MWA_FLAGS +Windows.Win32.Graphics.Dxgi.DXGI_OFFER_RESOURCE_FLAGS +Windows.Win32.Graphics.Dxgi.DXGI_OFFER_RESOURCE_PRIORITY +Windows.Win32.Graphics.Dxgi.DXGI_OUTDUPL_DESC +Windows.Win32.Graphics.Dxgi.DXGI_OUTDUPL_FRAME_INFO +Windows.Win32.Graphics.Dxgi.DXGI_OUTDUPL_MOVE_RECT +Windows.Win32.Graphics.Dxgi.DXGI_OUTDUPL_POINTER_POSITION +Windows.Win32.Graphics.Dxgi.DXGI_OUTDUPL_POINTER_SHAPE_INFO +Windows.Win32.Graphics.Dxgi.DXGI_OUTPUT_DESC +Windows.Win32.Graphics.Dxgi.DXGI_OUTPUT_DESC1 +Windows.Win32.Graphics.Dxgi.DXGI_PRESENT +Windows.Win32.Graphics.Dxgi.DXGI_PRESENT_DO_NOT_WAIT +Windows.Win32.Graphics.Dxgi.DXGI_PRESENT_PARAMETERS +Windows.Win32.Graphics.Dxgi.DXGI_QUERY_VIDEO_MEMORY_INFO +Windows.Win32.Graphics.Dxgi.DXGI_RECLAIM_RESOURCE_RESULTS +Windows.Win32.Graphics.Dxgi.DXGI_RESIDENCY +Windows.Win32.Graphics.Dxgi.DXGI_RESOURCE_PRIORITY +Windows.Win32.Graphics.Dxgi.DXGI_RGBA +Windows.Win32.Graphics.Dxgi.DXGI_SCALING +Windows.Win32.Graphics.Dxgi.DXGI_SCALING_NONE +Windows.Win32.Graphics.Dxgi.DXGI_SHARED_RESOURCE +Windows.Win32.Graphics.Dxgi.DXGI_SURFACE_DESC +Windows.Win32.Graphics.Dxgi.DXGI_SWAP_CHAIN_DESC +Windows.Win32.Graphics.Dxgi.DXGI_SWAP_CHAIN_DESC1 +Windows.Win32.Graphics.Dxgi.DXGI_SWAP_CHAIN_FLAG +Windows.Win32.Graphics.Dxgi.DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT +Windows.Win32.Graphics.Dxgi.DXGI_SWAP_CHAIN_FULLSCREEN_DESC +Windows.Win32.Graphics.Dxgi.DXGI_SWAP_EFFECT +Windows.Win32.Graphics.Dxgi.DXGI_SWAP_EFFECT_FLIP_DISCARD +Windows.Win32.Graphics.Dxgi.DXGI_USAGE +Windows.Win32.Graphics.Dxgi.DXGI_USAGE_RENDER_TARGET_OUTPUT +Windows.Win32.Graphics.Dxgi.IDXGIAdapter +Windows.Win32.Graphics.Dxgi.IDXGIAdapter1 +Windows.Win32.Graphics.Dxgi.IDXGIAdapter2 +Windows.Win32.Graphics.Dxgi.IDXGIAdapter3 +Windows.Win32.Graphics.Dxgi.IDXGIAdapter4 +Windows.Win32.Graphics.Dxgi.IDXGIDevice +Windows.Win32.Graphics.Dxgi.IDXGIDevice1 +Windows.Win32.Graphics.Dxgi.IDXGIDevice2 +Windows.Win32.Graphics.Dxgi.IDXGIDevice3 +Windows.Win32.Graphics.Dxgi.IDXGIDevice4 +Windows.Win32.Graphics.Dxgi.IDXGIDeviceSubObject +Windows.Win32.Graphics.Dxgi.IDXGIFactory +Windows.Win32.Graphics.Dxgi.IDXGIFactory1 +Windows.Win32.Graphics.Dxgi.IDXGIFactory2 +Windows.Win32.Graphics.Dxgi.IDXGIFactory3 +Windows.Win32.Graphics.Dxgi.IDXGIFactory4 +Windows.Win32.Graphics.Dxgi.IDXGIFactory5 +Windows.Win32.Graphics.Dxgi.IDXGIFactory6 +Windows.Win32.Graphics.Dxgi.IDXGIFactory7 +Windows.Win32.Graphics.Dxgi.IDXGIKeyedMutex +Windows.Win32.Graphics.Dxgi.IDXGIObject +Windows.Win32.Graphics.Dxgi.IDXGIOutput +Windows.Win32.Graphics.Dxgi.IDXGIOutput1 +Windows.Win32.Graphics.Dxgi.IDXGIOutput2 +Windows.Win32.Graphics.Dxgi.IDXGIOutput3 +Windows.Win32.Graphics.Dxgi.IDXGIOutput4 +Windows.Win32.Graphics.Dxgi.IDXGIOutput5 +Windows.Win32.Graphics.Dxgi.IDXGIOutput6 +Windows.Win32.Graphics.Dxgi.IDXGIOutputDuplication +Windows.Win32.Graphics.Dxgi.IDXGIResource +Windows.Win32.Graphics.Dxgi.IDXGIResource1 +Windows.Win32.Graphics.Dxgi.IDXGISurface +Windows.Win32.Graphics.Dxgi.IDXGISurface1 +Windows.Win32.Graphics.Dxgi.IDXGISurface2 +Windows.Win32.Graphics.Dxgi.IDXGISwapChain +Windows.Win32.Graphics.Dxgi.IDXGISwapChain1 +Windows.Win32.Graphics.Dxgi.IDXGISwapChain2 +Windows.Win32.Graphics.Dxgi.IDXGISwapChain3 +Windows.Win32.Graphics.Dxgi.IDXGISwapChain4 +Windows.Win32.Graphics.Gdi.CreateSolidBrush +Windows.Win32.Graphics.Gdi.DeleteEnhMetaFile +Windows.Win32.Graphics.Gdi.DeleteObject +Windows.Win32.Graphics.Gdi.GET_DEVICE_CAPS_INDEX +Windows.Win32.Graphics.Gdi.GetDC +Windows.Win32.Graphics.Gdi.GetDeviceCaps +Windows.Win32.Graphics.Gdi.HBITMAP +Windows.Win32.Graphics.Gdi.HBRUSH +Windows.Win32.Graphics.Gdi.HDC +Windows.Win32.Graphics.Gdi.HENHMETAFILE +Windows.Win32.Graphics.Gdi.HFONT +Windows.Win32.Graphics.Gdi.HGDIOBJ +Windows.Win32.Graphics.Gdi.HMONITOR +Windows.Win32.Graphics.Gdi.HPALETTE +Windows.Win32.Graphics.Gdi.HPEN +Windows.Win32.Graphics.Gdi.HRGN +Windows.Win32.Graphics.Gdi.LOGPIXELSX +Windows.Win32.Graphics.Gdi.MONITOR_DEFAULTTONEAREST +Windows.Win32.Graphics.Gdi.MONITOR_FROM_FLAGS +Windows.Win32.Graphics.Gdi.MonitorFromWindow +Windows.Win32.Graphics.Gdi.ScreenToClient +Windows.Win32.Media.Audio.AUDCLNT_SHAREMODE +Windows.Win32.Media.Audio.AUDCLNT_SHAREMODE_SHARED +Windows.Win32.Media.Audio.AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM +Windows.Win32.Media.Audio.AUDCLNT_STREAMFLAGS_EVENTCALLBACK +Windows.Win32.Media.Audio.AUDCLNT_STREAMFLAGS_LOOPBACK +Windows.Win32.Media.Audio.AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY +Windows.Win32.Media.Audio.AUDCLNT_STREAMOPTIONS +Windows.Win32.Media.Audio.AUDIO_STREAM_CATEGORY +Windows.Win32.Media.Audio.AudioClientProperties +Windows.Win32.Media.Audio.AudioObjectType +Windows.Win32.Media.Audio.DEVICE_STATE +Windows.Win32.Media.Audio.DEVICE_STATE_ACTIVE +Windows.Win32.Media.Audio.EDataFlow +Windows.Win32.Media.Audio.ERole +Windows.Win32.Media.Audio.IAudioCaptureClient +Windows.Win32.Media.Audio.IAudioClient +Windows.Win32.Media.Audio.IAudioClient2 +Windows.Win32.Media.Audio.IAudioClient3 +Windows.Win32.Media.Audio.IAudioRenderClient +Windows.Win32.Media.Audio.IMMDevice +Windows.Win32.Media.Audio.IMMDeviceCollection +Windows.Win32.Media.Audio.IMMDeviceEnumerator +Windows.Win32.Media.Audio.IMMNotificationClient +Windows.Win32.Media.Audio.ISpatialAudioMetadataItems +Windows.Win32.Media.Audio.MMDeviceEnumerator +Windows.Win32.Media.Audio.SpatialAudioMetadataItemsInfo +Windows.Win32.Media.Audio.WAVEFORMATEX +Windows.Win32.Media.Audio.WAVEFORMATEXTENSIBLE +Windows.Win32.Media.Audio.eAll +Windows.Win32.Media.Audio.eCapture +Windows.Win32.Media.Audio.eConsole +Windows.Win32.Media.Audio.eRender +Windows.Win32.Media.KernelStreaming.WAVE_FORMAT_EXTENSIBLE +Windows.Win32.Media.MediaFoundation.CLSID_MFMediaEngineClassFactory +Windows.Win32.Media.MediaFoundation.CODECAPI_AVEncMPVGOPSize +Windows.Win32.Media.MediaFoundation.DEVICE_INFO +Windows.Win32.Media.MediaFoundation.ICodecAPI +Windows.Win32.Media.MediaFoundation.IMFASFMutualExclusion +Windows.Win32.Media.MediaFoundation.IMFASFProfile +Windows.Win32.Media.MediaFoundation.IMFASFStreamConfig +Windows.Win32.Media.MediaFoundation.IMFASFStreamPrioritization +Windows.Win32.Media.MediaFoundation.IMFActivate +Windows.Win32.Media.MediaFoundation.IMFAsyncCallback +Windows.Win32.Media.MediaFoundation.IMFAsyncCallbackLogging +Windows.Win32.Media.MediaFoundation.IMFAsyncResult +Windows.Win32.Media.MediaFoundation.IMFAttributes +Windows.Win32.Media.MediaFoundation.IMFAudioMediaType +Windows.Win32.Media.MediaFoundation.IMFByteStream +Windows.Win32.Media.MediaFoundation.IMFCameraControlDefaults +Windows.Win32.Media.MediaFoundation.IMFCameraControlDefaultsCollection +Windows.Win32.Media.MediaFoundation.IMFCameraSyncObject +Windows.Win32.Media.MediaFoundation.IMFCdmSuspendNotify +Windows.Win32.Media.MediaFoundation.IMFClock +Windows.Win32.Media.MediaFoundation.IMFClockStateSink +Windows.Win32.Media.MediaFoundation.IMFCollection +Windows.Win32.Media.MediaFoundation.IMFDXGIBuffer +Windows.Win32.Media.MediaFoundation.IMFDXGIDeviceManager +Windows.Win32.Media.MediaFoundation.IMFFinalizableMediaSink +Windows.Win32.Media.MediaFoundation.IMFMediaBuffer +Windows.Win32.Media.MediaFoundation.IMFMediaEngine +Windows.Win32.Media.MediaFoundation.IMFMediaEngineClassFactory +Windows.Win32.Media.MediaFoundation.IMFMediaEngineClassFactoryEx +Windows.Win32.Media.MediaFoundation.IMFMediaEngineEx +Windows.Win32.Media.MediaFoundation.IMFMediaEngineNotify +Windows.Win32.Media.MediaFoundation.IMFMediaEngineSrcElements +Windows.Win32.Media.MediaFoundation.IMFMediaEngineSrcElementsEx +Windows.Win32.Media.MediaFoundation.IMFMediaError +Windows.Win32.Media.MediaFoundation.IMFMediaEvent +Windows.Win32.Media.MediaFoundation.IMFMediaEventGenerator +Windows.Win32.Media.MediaFoundation.IMFMediaKeySession +Windows.Win32.Media.MediaFoundation.IMFMediaKeySession2 +Windows.Win32.Media.MediaFoundation.IMFMediaKeySessionNotify +Windows.Win32.Media.MediaFoundation.IMFMediaKeySessionNotify2 +Windows.Win32.Media.MediaFoundation.IMFMediaKeys +Windows.Win32.Media.MediaFoundation.IMFMediaKeys2 +Windows.Win32.Media.MediaFoundation.IMFMediaSession +Windows.Win32.Media.MediaFoundation.IMFMediaSharingEngine +Windows.Win32.Media.MediaFoundation.IMFMediaSink +Windows.Win32.Media.MediaFoundation.IMFMediaSource +Windows.Win32.Media.MediaFoundation.IMFMediaSource2 +Windows.Win32.Media.MediaFoundation.IMFMediaSourceEx +Windows.Win32.Media.MediaFoundation.IMFMediaSourceExtension +Windows.Win32.Media.MediaFoundation.IMFMediaStream +Windows.Win32.Media.MediaFoundation.IMFMediaStream2 +Windows.Win32.Media.MediaFoundation.IMFMediaTimeRange +Windows.Win32.Media.MediaFoundation.IMFMediaType +Windows.Win32.Media.MediaFoundation.IMFMediaTypeHandler +Windows.Win32.Media.MediaFoundation.IMFOutputPolicy +Windows.Win32.Media.MediaFoundation.IMFOutputSchema +Windows.Win32.Media.MediaFoundation.IMFPresentationClock +Windows.Win32.Media.MediaFoundation.IMFPresentationDescriptor +Windows.Win32.Media.MediaFoundation.IMFPresentationTimeSource +Windows.Win32.Media.MediaFoundation.IMFSample +Windows.Win32.Media.MediaFoundation.IMFSampleGrabberSinkCallback +Windows.Win32.Media.MediaFoundation.IMFSampleGrabberSinkCallback2 +Windows.Win32.Media.MediaFoundation.IMFSensorStream +Windows.Win32.Media.MediaFoundation.IMFSinkWriter +Windows.Win32.Media.MediaFoundation.IMFSinkWriterEx +Windows.Win32.Media.MediaFoundation.IMFSourceBuffer +Windows.Win32.Media.MediaFoundation.IMFSourceBufferList +Windows.Win32.Media.MediaFoundation.IMFSourceBufferNotify +Windows.Win32.Media.MediaFoundation.IMFSourceReader +Windows.Win32.Media.MediaFoundation.IMFSourceReaderCallback +Windows.Win32.Media.MediaFoundation.IMFSourceReaderCallback2 +Windows.Win32.Media.MediaFoundation.IMFSourceReaderEx +Windows.Win32.Media.MediaFoundation.IMFSpatialAudioObjectBuffer +Windows.Win32.Media.MediaFoundation.IMFSpatialAudioSample +Windows.Win32.Media.MediaFoundation.IMFStreamDescriptor +Windows.Win32.Media.MediaFoundation.IMFStreamSink +Windows.Win32.Media.MediaFoundation.IMFTopology +Windows.Win32.Media.MediaFoundation.IMFTopologyNode +Windows.Win32.Media.MediaFoundation.IMFTransform +Windows.Win32.Media.MediaFoundation.IMFVideoMediaType +Windows.Win32.Media.MediaFoundation.IMFVideoPresenter +Windows.Win32.Media.MediaFoundation.IMFVirtualCamera +Windows.Win32.Media.MediaFoundation.MEDIA_EVENT_GENERATOR_GET_EVENT_FLAGS +Windows.Win32.Media.MediaFoundation.MF3DVideoOutputType +Windows.Win32.Media.MediaFoundation.MFARGB +Windows.Win32.Media.MediaFoundation.MFASYNCRESULT +Windows.Win32.Media.MediaFoundation.MFAYUVSample +Windows.Win32.Media.MediaFoundation.MFAudioFormat_AAC +Windows.Win32.Media.MediaFoundation.MFAudioFormat_Float +Windows.Win32.Media.MediaFoundation.MFAudioFormat_PCM +Windows.Win32.Media.MediaFoundation.MFBYTESTREAM_SEEK_ORIGIN +Windows.Win32.Media.MediaFoundation.MFCLOCK_PROPERTIES +Windows.Win32.Media.MediaFoundation.MFCLOCK_STATE +Windows.Win32.Media.MediaFoundation.MFCreateAttributes +Windows.Win32.Media.MediaFoundation.MFCreateDXGIDeviceManager +Windows.Win32.Media.MediaFoundation.MFCreateMFByteStreamOnStream +Windows.Win32.Media.MediaFoundation.MFCreateMediaType +Windows.Win32.Media.MediaFoundation.MFCreateMemoryBuffer +Windows.Win32.Media.MediaFoundation.MFCreateSample +Windows.Win32.Media.MediaFoundation.MFCreateSinkWriterFromURL +Windows.Win32.Media.MediaFoundation.MFCreateSourceReaderFromByteStream +Windows.Win32.Media.MediaFoundation.MFCreateSourceReaderFromMediaSource +Windows.Win32.Media.MediaFoundation.MFCreateSourceReaderFromURL +Windows.Win32.Media.MediaFoundation.MFEnumDeviceSources +Windows.Win32.Media.MediaFoundation.MFMediaKeyStatus +Windows.Win32.Media.MediaFoundation.MFMediaType_Audio +Windows.Win32.Media.MediaFoundation.MFMediaType_Video +Windows.Win32.Media.MediaFoundation.MFNominalRange +Windows.Win32.Media.MediaFoundation.MFNominalRange_0_255 +Windows.Win32.Media.MediaFoundation.MFNominalRange_16_235 +Windows.Win32.Media.MediaFoundation.MFOffset +Windows.Win32.Media.MediaFoundation.MFPaletteEntry +Windows.Win32.Media.MediaFoundation.MFRatio +Windows.Win32.Media.MediaFoundation.MFSTARTUP_FULL +Windows.Win32.Media.MediaFoundation.MFSTREAMSINK_MARKER_TYPE +Windows.Win32.Media.MediaFoundation.MFShutdown +Windows.Win32.Media.MediaFoundation.MFStartup +Windows.Win32.Media.MediaFoundation.MFT_CATEGORY_VIDEO_ENCODER +Windows.Win32.Media.MediaFoundation.MFT_ENUM_HARDWARE_URL_Attribute +Windows.Win32.Media.MediaFoundation.MFT_FRIENDLY_NAME_Attribute +Windows.Win32.Media.MediaFoundation.MFT_INPUT_STREAM_INFO +Windows.Win32.Media.MediaFoundation.MFT_MESSAGE_TYPE +Windows.Win32.Media.MediaFoundation.MFT_OUTPUT_DATA_BUFFER +Windows.Win32.Media.MediaFoundation.MFT_OUTPUT_STREAM_INFO +Windows.Win32.Media.MediaFoundation.MFTranscodeContainerType_MPEG4 +Windows.Win32.Media.MediaFoundation.MFVIDEOFORMAT +Windows.Win32.Media.MediaFoundation.MFVP_MESSAGE_TYPE +Windows.Win32.Media.MediaFoundation.MFVideoArea +Windows.Win32.Media.MediaFoundation.MFVideoChromaSubsampling +Windows.Win32.Media.MediaFoundation.MFVideoCompressedInfo +Windows.Win32.Media.MediaFoundation.MFVideoFormat_H264 +Windows.Win32.Media.MediaFoundation.MFVideoFormat_HEVC +Windows.Win32.Media.MediaFoundation.MFVideoFormat_MJPG +Windows.Win32.Media.MediaFoundation.MFVideoFormat_NV12 +Windows.Win32.Media.MediaFoundation.MFVideoFormat_RGB24 +Windows.Win32.Media.MediaFoundation.MFVideoFormat_YUY2 +Windows.Win32.Media.MediaFoundation.MFVideoInfo +Windows.Win32.Media.MediaFoundation.MFVideoInterlaceMode +Windows.Win32.Media.MediaFoundation.MFVideoInterlace_Progressive +Windows.Win32.Media.MediaFoundation.MFVideoLighting +Windows.Win32.Media.MediaFoundation.MFVideoNormalizedRect +Windows.Win32.Media.MediaFoundation.MFVideoPrimaries +Windows.Win32.Media.MediaFoundation.MFVideoSurfaceInfo +Windows.Win32.Media.MediaFoundation.MFVideoTransferFunction +Windows.Win32.Media.MediaFoundation.MFVideoTransferMatrix +Windows.Win32.Media.MediaFoundation.MFVideoTransferMatrix_BT2020_10 +Windows.Win32.Media.MediaFoundation.MFVideoTransferMatrix_BT2020_12 +Windows.Win32.Media.MediaFoundation.MFVideoTransferMatrix_BT601 +Windows.Win32.Media.MediaFoundation.MFVideoTransferMatrix_BT709 +Windows.Win32.Media.MediaFoundation.MF_ATTRIBUTES_MATCH_TYPE +Windows.Win32.Media.MediaFoundation.MF_ATTRIBUTE_TYPE +Windows.Win32.Media.MediaFoundation.MF_BYTESTREAM_CONTENT_TYPE +Windows.Win32.Media.MediaFoundation.MF_CAMERA_CONTROL_CONFIGURATION_TYPE +Windows.Win32.Media.MediaFoundation.MF_CAMERA_CONTROL_RANGE_INFO +Windows.Win32.Media.MediaFoundation.MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME +Windows.Win32.Media.MediaFoundation.MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE +Windows.Win32.Media.MediaFoundation.MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID +Windows.Win32.Media.MediaFoundation.MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK +Windows.Win32.Media.MediaFoundation.MF_MEDIAKEYSESSION_MESSAGETYPE +Windows.Win32.Media.MediaFoundation.MF_MEDIAKEYSESSION_TYPE +Windows.Win32.Media.MediaFoundation.MF_MEDIAKEY_STATUS +Windows.Win32.Media.MediaFoundation.MF_MEDIA_ENGINE_CALLBACK +Windows.Win32.Media.MediaFoundation.MF_MEDIA_ENGINE_CANPLAY +Windows.Win32.Media.MediaFoundation.MF_MEDIA_ENGINE_DXGI_MANAGER +Windows.Win32.Media.MediaFoundation.MF_MEDIA_ENGINE_ERR +Windows.Win32.Media.MediaFoundation.MF_MEDIA_ENGINE_EVENT +Windows.Win32.Media.MediaFoundation.MF_MEDIA_ENGINE_EVENT_CANPLAY +Windows.Win32.Media.MediaFoundation.MF_MEDIA_ENGINE_EVENT_ENDED +Windows.Win32.Media.MediaFoundation.MF_MEDIA_ENGINE_EVENT_ERROR +Windows.Win32.Media.MediaFoundation.MF_MEDIA_ENGINE_EVENT_FORMATCHANGE +Windows.Win32.Media.MediaFoundation.MF_MEDIA_ENGINE_PRELOAD +Windows.Win32.Media.MediaFoundation.MF_MEDIA_ENGINE_S3D_PACKING_MODE +Windows.Win32.Media.MediaFoundation.MF_MEDIA_ENGINE_SEEK_MODE +Windows.Win32.Media.MediaFoundation.MF_MEDIA_ENGINE_STATISTIC +Windows.Win32.Media.MediaFoundation.MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT +Windows.Win32.Media.MediaFoundation.MF_MSE_ERROR +Windows.Win32.Media.MediaFoundation.MF_MSE_READY +Windows.Win32.Media.MediaFoundation.MF_MT_ALL_SAMPLES_INDEPENDENT +Windows.Win32.Media.MediaFoundation.MF_MT_AUDIO_AVG_BYTES_PER_SECOND +Windows.Win32.Media.MediaFoundation.MF_MT_AUDIO_BITS_PER_SAMPLE +Windows.Win32.Media.MediaFoundation.MF_MT_AUDIO_BLOCK_ALIGNMENT +Windows.Win32.Media.MediaFoundation.MF_MT_AUDIO_NUM_CHANNELS +Windows.Win32.Media.MediaFoundation.MF_MT_AUDIO_SAMPLES_PER_SECOND +Windows.Win32.Media.MediaFoundation.MF_MT_AVG_BITRATE +Windows.Win32.Media.MediaFoundation.MF_MT_DEFAULT_STRIDE +Windows.Win32.Media.MediaFoundation.MF_MT_FRAME_RATE +Windows.Win32.Media.MediaFoundation.MF_MT_FRAME_SIZE +Windows.Win32.Media.MediaFoundation.MF_MT_INTERLACE_MODE +Windows.Win32.Media.MediaFoundation.MF_MT_MAJOR_TYPE +Windows.Win32.Media.MediaFoundation.MF_MT_MINIMUM_DISPLAY_APERTURE +Windows.Win32.Media.MediaFoundation.MF_MT_PIXEL_ASPECT_RATIO +Windows.Win32.Media.MediaFoundation.MF_MT_SUBTYPE +Windows.Win32.Media.MediaFoundation.MF_MT_VIDEO_NOMINAL_RANGE +Windows.Win32.Media.MediaFoundation.MF_MT_VIDEO_PROFILE +Windows.Win32.Media.MediaFoundation.MF_MT_YUV_MATRIX +Windows.Win32.Media.MediaFoundation.MF_PD_DURATION +Windows.Win32.Media.MediaFoundation.MF_READWRITE_DISABLE_CONVERTERS +Windows.Win32.Media.MediaFoundation.MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS +Windows.Win32.Media.MediaFoundation.MF_SA_D3D11_BINDFLAGS +Windows.Win32.Media.MediaFoundation.MF_SINK_WRITER_DISABLE_THROTTLING +Windows.Win32.Media.MediaFoundation.MF_SINK_WRITER_STATISTICS +Windows.Win32.Media.MediaFoundation.MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED +Windows.Win32.Media.MediaFoundation.MF_SOURCE_READERF_ENDOFSTREAM +Windows.Win32.Media.MediaFoundation.MF_SOURCE_READERF_STREAMTICK +Windows.Win32.Media.MediaFoundation.MF_SOURCE_READER_ALL_STREAMS +Windows.Win32.Media.MediaFoundation.MF_SOURCE_READER_ASYNC_CALLBACK +Windows.Win32.Media.MediaFoundation.MF_SOURCE_READER_CONSTANTS +Windows.Win32.Media.MediaFoundation.MF_SOURCE_READER_D3D11_BIND_FLAGS +Windows.Win32.Media.MediaFoundation.MF_SOURCE_READER_D3D_MANAGER +Windows.Win32.Media.MediaFoundation.MF_SOURCE_READER_DISABLE_DXVA +Windows.Win32.Media.MediaFoundation.MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING +Windows.Win32.Media.MediaFoundation.MF_SOURCE_READER_FIRST_AUDIO_STREAM +Windows.Win32.Media.MediaFoundation.MF_SOURCE_READER_FIRST_VIDEO_STREAM +Windows.Win32.Media.MediaFoundation.MF_SOURCE_READER_FLAG +Windows.Win32.Media.MediaFoundation.MF_SOURCE_READER_MEDIASOURCE +Windows.Win32.Media.MediaFoundation.MF_STREAM_STATE +Windows.Win32.Media.MediaFoundation.MF_TOPOLOGY_TYPE +Windows.Win32.Media.MediaFoundation.MF_TRANSCODE_CONTAINERTYPE +Windows.Win32.Media.MediaFoundation.MF_VERSION +Windows.Win32.Media.MediaFoundation.eAVEncH264VProfile +Windows.Win32.Media.MediaFoundation.eAVEncH264VProfile_Main +Windows.Win32.Media.MediaFoundation.eAVEncH265VProfile +Windows.Win32.Media.MediaFoundation.eAVEncH265VProfile_Main_420_8 +Windows.Win32.Media.Multimedia.KSDATAFORMAT_SUBTYPE_IEEE_FLOAT +Windows.Win32.Security.SECURITY_ATTRIBUTES +Windows.Win32.System.Com.ADVANCED_FEATURE_FLAGS +Windows.Win32.System.Com.BINDPTR +Windows.Win32.System.Com.BIND_OPTS +Windows.Win32.System.Com.BLOB +Windows.Win32.System.Com.CALLCONV +Windows.Win32.System.Com.CLSCTX +Windows.Win32.System.Com.CLSCTX_ALL +Windows.Win32.System.Com.CLSCTX_INPROC_SERVER +Windows.Win32.System.Com.COINIT +Windows.Win32.System.Com.COINIT_APARTMENTTHREADED +Windows.Win32.System.Com.COINIT_MULTITHREADED +Windows.Win32.System.Com.CUSTDATA +Windows.Win32.System.Com.CUSTDATAITEM +Windows.Win32.System.Com.CY +Windows.Win32.System.Com.CoCreateInstance +Windows.Win32.System.Com.CoInitializeEx +Windows.Win32.System.Com.CoTaskMemFree +Windows.Win32.System.Com.DATADIR +Windows.Win32.System.Com.DATADIR_GET +Windows.Win32.System.Com.DESCKIND +Windows.Win32.System.Com.DISPATCH_FLAGS +Windows.Win32.System.Com.DISPPARAMS +Windows.Win32.System.Com.DVASPECT +Windows.Win32.System.Com.DVASPECT_CONTENT +Windows.Win32.System.Com.DVTARGETDEVICE +Windows.Win32.System.Com.ELEMDESC +Windows.Win32.System.Com.EXCEPINFO +Windows.Win32.System.Com.FORMATETC +Windows.Win32.System.Com.FUNCDESC +Windows.Win32.System.Com.FUNCFLAGS +Windows.Win32.System.Com.FUNCKIND +Windows.Win32.System.Com.GetRunningObjectTable +Windows.Win32.System.Com.IAdviseSink +Windows.Win32.System.Com.IAdviseSink2 +Windows.Win32.System.Com.IBindCtx +Windows.Win32.System.Com.IDLDESC +Windows.Win32.System.Com.IDLFLAGS +Windows.Win32.System.Com.IDataObject +Windows.Win32.System.Com.IDispatch +Windows.Win32.System.Com.IEnumFORMATETC +Windows.Win32.System.Com.IEnumMoniker +Windows.Win32.System.Com.IEnumSTATDATA +Windows.Win32.System.Com.IEnumString +Windows.Win32.System.Com.IMPLTYPEFLAGS +Windows.Win32.System.Com.IMoniker +Windows.Win32.System.Com.INVOKEKIND +Windows.Win32.System.Com.IPersist +Windows.Win32.System.Com.IPersistFile +Windows.Win32.System.Com.IPersistMemory +Windows.Win32.System.Com.IPersistStream +Windows.Win32.System.Com.IPersistStreamInit +Windows.Win32.System.Com.IRunningObjectTable +Windows.Win32.System.Com.ISequentialStream +Windows.Win32.System.Com.IStream +Windows.Win32.System.Com.ITypeComp +Windows.Win32.System.Com.ITypeInfo +Windows.Win32.System.Com.ITypeInfo2 +Windows.Win32.System.Com.ITypeLib +Windows.Win32.System.Com.ITypeLib2 +Windows.Win32.System.Com.LOCKTYPE +Windows.Win32.System.Com.LPEXCEPFINO_DEFERRED_FILLIN +Windows.Win32.System.Com.ROT_FLAGS +Windows.Win32.System.Com.SAFEARRAY +Windows.Win32.System.Com.SAFEARRAYBOUND +Windows.Win32.System.Com.STATDATA +Windows.Win32.System.Com.STATFLAG +Windows.Win32.System.Com.STATSTG +Windows.Win32.System.Com.STGC +Windows.Win32.System.Com.STGM +Windows.Win32.System.Com.STGMEDIUM +Windows.Win32.System.Com.STGM_READ +Windows.Win32.System.Com.STREAM_SEEK +Windows.Win32.System.Com.SYSKIND +Windows.Win32.System.Com.StructuredStorage.BSTRBLOB +Windows.Win32.System.Com.StructuredStorage.CABOOL +Windows.Win32.System.Com.StructuredStorage.CABSTR +Windows.Win32.System.Com.StructuredStorage.CABSTRBLOB +Windows.Win32.System.Com.StructuredStorage.CAC +Windows.Win32.System.Com.StructuredStorage.CACLIPDATA +Windows.Win32.System.Com.StructuredStorage.CACLSID +Windows.Win32.System.Com.StructuredStorage.CACY +Windows.Win32.System.Com.StructuredStorage.CADATE +Windows.Win32.System.Com.StructuredStorage.CADBL +Windows.Win32.System.Com.StructuredStorage.CAFILETIME +Windows.Win32.System.Com.StructuredStorage.CAFLT +Windows.Win32.System.Com.StructuredStorage.CAH +Windows.Win32.System.Com.StructuredStorage.CAI +Windows.Win32.System.Com.StructuredStorage.CAL +Windows.Win32.System.Com.StructuredStorage.CALPSTR +Windows.Win32.System.Com.StructuredStorage.CALPWSTR +Windows.Win32.System.Com.StructuredStorage.CAPROPVARIANT +Windows.Win32.System.Com.StructuredStorage.CASCODE +Windows.Win32.System.Com.StructuredStorage.CAUB +Windows.Win32.System.Com.StructuredStorage.CAUH +Windows.Win32.System.Com.StructuredStorage.CAUI +Windows.Win32.System.Com.StructuredStorage.CAUL +Windows.Win32.System.Com.StructuredStorage.CLIPDATA +Windows.Win32.System.Com.StructuredStorage.IEnumSTATSTG +Windows.Win32.System.Com.StructuredStorage.IStorage +Windows.Win32.System.Com.StructuredStorage.PROPVARIANT +Windows.Win32.System.Com.StructuredStorage.STGMOVE +Windows.Win32.System.Com.StructuredStorage.VERSIONEDSTREAM +Windows.Win32.System.Com.TLIBATTR +Windows.Win32.System.Com.TYMED +Windows.Win32.System.Com.TYMED_HGLOBAL +Windows.Win32.System.Com.TYPEATTR +Windows.Win32.System.Com.TYPEDESC +Windows.Win32.System.Com.TYPEKIND +Windows.Win32.System.Com.VARDESC +Windows.Win32.System.Com.VARFLAGS +Windows.Win32.System.Com.VARKIND +Windows.Win32.System.Console.COORD +Windows.Win32.System.Console.ClosePseudoConsole +Windows.Win32.System.Console.CreatePseudoConsole +Windows.Win32.System.Console.HPCON +Windows.Win32.System.Console.ResizePseudoConsole +Windows.Win32.System.DataExchange.CloseClipboard +Windows.Win32.System.DataExchange.EmptyClipboard +Windows.Win32.System.DataExchange.GetClipboardData +Windows.Win32.System.DataExchange.OpenClipboard +Windows.Win32.System.DataExchange.SetClipboardData +Windows.Win32.System.LibraryLoader.GetModuleHandleW +Windows.Win32.System.LibraryLoader.GetProcAddress +Windows.Win32.System.LibraryLoader.LoadLibraryA +Windows.Win32.System.Memory.GLOBAL_ALLOC_FLAGS +Windows.Win32.System.Memory.GMEM_FIXED +Windows.Win32.System.Memory.GMEM_ZEROINIT +Windows.Win32.System.Memory.GlobalAlloc +Windows.Win32.System.Memory.GlobalLock +Windows.Win32.System.Memory.GlobalSize +Windows.Win32.System.Memory.GlobalUnlock +Windows.Win32.System.Ole.ARRAYDESC +Windows.Win32.System.Ole.CF_HDROP +Windows.Win32.System.Ole.CF_UNICODETEXT +Windows.Win32.System.Ole.CLIPBOARD_FORMAT +Windows.Win32.System.Ole.DROPEFFECT +Windows.Win32.System.Ole.DROPEFFECT_COPY +Windows.Win32.System.Ole.DROPEFFECT_LINK +Windows.Win32.System.Ole.DROPEFFECT_MOVE +Windows.Win32.System.Ole.DoDragDrop +Windows.Win32.System.Ole.IDropSource +Windows.Win32.System.Ole.IDropTarget +Windows.Win32.System.Ole.IRecordInfo +Windows.Win32.System.Ole.OleInitialize +Windows.Win32.System.Ole.PARAMDESC +Windows.Win32.System.Ole.PARAMDESCEX +Windows.Win32.System.Ole.PARAMFLAGS +Windows.Win32.System.Ole.RegisterDragDrop +Windows.Win32.System.Ole.ReleaseStgMedium +Windows.Win32.System.Performance.QueryPerformanceCounter +Windows.Win32.System.Performance.QueryPerformanceFrequency +Windows.Win32.System.Pipes.CreatePipe +Windows.Win32.System.SystemServices.MK_CONTROL +Windows.Win32.System.SystemServices.MK_LBUTTON +Windows.Win32.System.SystemServices.MK_SHIFT +Windows.Win32.System.SystemServices.MODIFIERKEYS_FLAGS +Windows.Win32.System.Threading.AvSetMmThreadCharacteristicsW +Windows.Win32.System.Threading.CreateEventA +Windows.Win32.System.Threading.CreateProcessW +Windows.Win32.System.Threading.DeleteProcThreadAttributeList +Windows.Win32.System.Threading.EXTENDED_STARTUPINFO_PRESENT +Windows.Win32.System.Threading.ExitProcess +Windows.Win32.System.Threading.InitializeProcThreadAttributeList +Windows.Win32.System.Threading.LPPROC_THREAD_ATTRIBUTE_LIST +Windows.Win32.System.Threading.PROCESS_CREATION_FLAGS +Windows.Win32.System.Threading.PROCESS_INFORMATION +Windows.Win32.System.Threading.PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE +Windows.Win32.System.Threading.STARTUPINFOEXW +Windows.Win32.System.Threading.STARTUPINFOW +Windows.Win32.System.Threading.STARTUPINFOW_FLAGS +Windows.Win32.System.Threading.SetEvent +Windows.Win32.System.Threading.TerminateProcess +Windows.Win32.System.Threading.UpdateProcThreadAttribute +Windows.Win32.System.Threading.WaitForSingleObject +Windows.Win32.System.Variant.VARENUM +Windows.Win32.System.Variant.VARIANT +Windows.Win32.System.Variant.VT_UI8 +Windows.Win32.System.WinRT.IBufferByteAccess +Windows.Win32.System.WindowsProgramming.GMEM_DDESHARE +Windows.Win32.UI.Controls.MARGINS +Windows.Win32.UI.Controls.WM_MOUSELEAVE +Windows.Win32.UI.HiDpi.DPI_AWARENESS_CONTEXT +Windows.Win32.UI.HiDpi.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE +Windows.Win32.UI.HiDpi.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 +Windows.Win32.UI.HiDpi.MDT_EFFECTIVE_DPI +Windows.Win32.UI.HiDpi.MONITOR_DPI_TYPE +Windows.Win32.UI.HiDpi.PROCESS_DPI_AWARENESS +Windows.Win32.UI.HiDpi.PROCESS_PER_MONITOR_DPI_AWARE +Windows.Win32.UI.Input.Ime.CFS_POINT +Windows.Win32.UI.Input.Ime.COMPOSITIONFORM +Windows.Win32.UI.Input.Ime.GCS_COMPSTR +Windows.Win32.UI.Input.Ime.GCS_RESULTSTR +Windows.Win32.UI.Input.Ime.HIMC +Windows.Win32.UI.Input.Ime.IME_COMPOSITION_STRING +Windows.Win32.UI.Input.Ime.ImmAssociateContext +Windows.Win32.UI.Input.Ime.ImmDestroyContext +Windows.Win32.UI.Input.Ime.ImmGetCompositionStringW +Windows.Win32.UI.Input.Ime.ImmGetContext +Windows.Win32.UI.Input.Ime.ImmReleaseContext +Windows.Win32.UI.Input.Ime.ImmSetCompositionWindow +Windows.Win32.UI.Input.KeyboardAndMouse.GetKeyState +Windows.Win32.UI.Input.KeyboardAndMouse.ReleaseCapture +Windows.Win32.UI.Input.KeyboardAndMouse.SetCapture +Windows.Win32.UI.Input.KeyboardAndMouse.TME_LEAVE +Windows.Win32.UI.Input.KeyboardAndMouse.TRACKMOUSEEVENT +Windows.Win32.UI.Input.KeyboardAndMouse.TRACKMOUSEEVENT_FLAGS +Windows.Win32.UI.Input.KeyboardAndMouse.TrackMouseEvent +Windows.Win32.UI.Input.KeyboardAndMouse.VIRTUAL_KEY +Windows.Win32.UI.Input.KeyboardAndMouse.VK_0 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_1 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_2 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_3 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_4 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_5 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_6 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_7 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_8 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_9 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_A +Windows.Win32.UI.Input.KeyboardAndMouse.VK_ADD +Windows.Win32.UI.Input.KeyboardAndMouse.VK_B +Windows.Win32.UI.Input.KeyboardAndMouse.VK_BACK +Windows.Win32.UI.Input.KeyboardAndMouse.VK_C +Windows.Win32.UI.Input.KeyboardAndMouse.VK_CAPITAL +Windows.Win32.UI.Input.KeyboardAndMouse.VK_CONTROL +Windows.Win32.UI.Input.KeyboardAndMouse.VK_D +Windows.Win32.UI.Input.KeyboardAndMouse.VK_DECIMAL +Windows.Win32.UI.Input.KeyboardAndMouse.VK_DELETE +Windows.Win32.UI.Input.KeyboardAndMouse.VK_DIVIDE +Windows.Win32.UI.Input.KeyboardAndMouse.VK_DOWN +Windows.Win32.UI.Input.KeyboardAndMouse.VK_E +Windows.Win32.UI.Input.KeyboardAndMouse.VK_END +Windows.Win32.UI.Input.KeyboardAndMouse.VK_ESCAPE +Windows.Win32.UI.Input.KeyboardAndMouse.VK_F +Windows.Win32.UI.Input.KeyboardAndMouse.VK_F1 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_F10 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_F11 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_F12 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_F2 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_F3 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_F4 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_F5 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_F6 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_F7 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_F8 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_F9 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_FPARAM +Windows.Win32.UI.Input.KeyboardAndMouse.VK_G +Windows.Win32.UI.Input.KeyboardAndMouse.VK_H +Windows.Win32.UI.Input.KeyboardAndMouse.VK_HOME +Windows.Win32.UI.Input.KeyboardAndMouse.VK_I +Windows.Win32.UI.Input.KeyboardAndMouse.VK_INSERT +Windows.Win32.UI.Input.KeyboardAndMouse.VK_J +Windows.Win32.UI.Input.KeyboardAndMouse.VK_K +Windows.Win32.UI.Input.KeyboardAndMouse.VK_L +Windows.Win32.UI.Input.KeyboardAndMouse.VK_LCONTROL +Windows.Win32.UI.Input.KeyboardAndMouse.VK_LEFT +Windows.Win32.UI.Input.KeyboardAndMouse.VK_LMENU +Windows.Win32.UI.Input.KeyboardAndMouse.VK_LSHIFT +Windows.Win32.UI.Input.KeyboardAndMouse.VK_LWIN +Windows.Win32.UI.Input.KeyboardAndMouse.VK_M +Windows.Win32.UI.Input.KeyboardAndMouse.VK_MENU +Windows.Win32.UI.Input.KeyboardAndMouse.VK_MULTIPLY +Windows.Win32.UI.Input.KeyboardAndMouse.VK_N +Windows.Win32.UI.Input.KeyboardAndMouse.VK_NEXT +Windows.Win32.UI.Input.KeyboardAndMouse.VK_NUMLOCK +Windows.Win32.UI.Input.KeyboardAndMouse.VK_NUMPAD0 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_NUMPAD1 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_NUMPAD2 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_NUMPAD3 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_NUMPAD4 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_NUMPAD5 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_NUMPAD6 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_NUMPAD7 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_NUMPAD8 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_NUMPAD9 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_O +Windows.Win32.UI.Input.KeyboardAndMouse.VK_OEM_1 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_OEM_2 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_OEM_3 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_OEM_4 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_OEM_5 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_OEM_6 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_OEM_7 +Windows.Win32.UI.Input.KeyboardAndMouse.VK_OEM_COMMA +Windows.Win32.UI.Input.KeyboardAndMouse.VK_OEM_MINUS +Windows.Win32.UI.Input.KeyboardAndMouse.VK_OEM_PERIOD +Windows.Win32.UI.Input.KeyboardAndMouse.VK_OEM_PLUS +Windows.Win32.UI.Input.KeyboardAndMouse.VK_P +Windows.Win32.UI.Input.KeyboardAndMouse.VK_PAUSE +Windows.Win32.UI.Input.KeyboardAndMouse.VK_PRIOR +Windows.Win32.UI.Input.KeyboardAndMouse.VK_Q +Windows.Win32.UI.Input.KeyboardAndMouse.VK_R +Windows.Win32.UI.Input.KeyboardAndMouse.VK_RCONTROL +Windows.Win32.UI.Input.KeyboardAndMouse.VK_RETURN +Windows.Win32.UI.Input.KeyboardAndMouse.VK_RIGHT +Windows.Win32.UI.Input.KeyboardAndMouse.VK_RMENU +Windows.Win32.UI.Input.KeyboardAndMouse.VK_RSHIFT +Windows.Win32.UI.Input.KeyboardAndMouse.VK_RWIN +Windows.Win32.UI.Input.KeyboardAndMouse.VK_S +Windows.Win32.UI.Input.KeyboardAndMouse.VK_SCROLL +Windows.Win32.UI.Input.KeyboardAndMouse.VK_SHIFT +Windows.Win32.UI.Input.KeyboardAndMouse.VK_SNAPSHOT +Windows.Win32.UI.Input.KeyboardAndMouse.VK_SPACE +Windows.Win32.UI.Input.KeyboardAndMouse.VK_SUBTRACT +Windows.Win32.UI.Input.KeyboardAndMouse.VK_T +Windows.Win32.UI.Input.KeyboardAndMouse.VK_TAB +Windows.Win32.UI.Input.KeyboardAndMouse.VK_U +Windows.Win32.UI.Input.KeyboardAndMouse.VK_UP +Windows.Win32.UI.Input.KeyboardAndMouse.VK_V +Windows.Win32.UI.Input.KeyboardAndMouse.VK_W +Windows.Win32.UI.Input.KeyboardAndMouse.VK_X +Windows.Win32.UI.Input.KeyboardAndMouse.VK_Y +Windows.Win32.UI.Input.KeyboardAndMouse.VK_Z +Windows.Win32.UI.Input.KeyboardAndMouse._TrackMouseEvent +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD_A +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD_B +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD_BACK +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD_BUTTON_FLAGS +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD_DPAD_DOWN +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD_DPAD_LEFT +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD_DPAD_RIGHT +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD_DPAD_UP +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD_LEFT_SHOULDER +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD_LEFT_THUMB +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD_RIGHT_SHOULDER +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD_RIGHT_THUMB +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD_START +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD_X +Windows.Win32.UI.Input.XboxController.XINPUT_GAMEPAD_Y +Windows.Win32.UI.Input.XboxController.XINPUT_STATE +Windows.Win32.UI.Input.XboxController.XInputGetState +Windows.Win32.UI.Shell.FOLDERID_LocalAppData +Windows.Win32.UI.Shell.KF_FLAG_DEFAULT +Windows.Win32.UI.Shell.KNOWN_FOLDER_FLAG +Windows.Win32.UI.Shell.PropertiesSystem.IPropertyStore +Windows.Win32.UI.Shell.PropertiesSystem.IPropertyStoreCache +Windows.Win32.UI.Shell.PropertiesSystem.PSC_STATE +Windows.Win32.UI.Shell.SHCreateMemStream +Windows.Win32.UI.Shell.SHGetKnownFolderPath +Windows.Win32.UI.WindowsAndMessaging.AdjustWindowRectEx +Windows.Win32.UI.WindowsAndMessaging.CS_OWNDC +Windows.Win32.UI.WindowsAndMessaging.CW_USEDEFAULT +Windows.Win32.UI.WindowsAndMessaging.CreateWindowExW +Windows.Win32.UI.WindowsAndMessaging.DefWindowProcW +Windows.Win32.UI.WindowsAndMessaging.DestroyCursor +Windows.Win32.UI.WindowsAndMessaging.DestroyIcon +Windows.Win32.UI.WindowsAndMessaging.DestroyMenu +Windows.Win32.UI.WindowsAndMessaging.DestroyWindow +Windows.Win32.UI.WindowsAndMessaging.DispatchMessageW +Windows.Win32.UI.WindowsAndMessaging.GDI_IMAGE_TYPE +Windows.Win32.UI.WindowsAndMessaging.GWLP_USERDATA +Windows.Win32.UI.WindowsAndMessaging.GWL_EXSTYLE +Windows.Win32.UI.WindowsAndMessaging.GWL_STYLE +Windows.Win32.UI.WindowsAndMessaging.GetClientRect +Windows.Win32.UI.WindowsAndMessaging.GetForegroundWindow +Windows.Win32.UI.WindowsAndMessaging.GetMessageW +Windows.Win32.UI.WindowsAndMessaging.GetSystemMetrics +Windows.Win32.UI.WindowsAndMessaging.GetWindowLongPtrW +Windows.Win32.UI.WindowsAndMessaging.GetWindowLongW +Windows.Win32.UI.WindowsAndMessaging.GetWindowPlacement +Windows.Win32.UI.WindowsAndMessaging.GetWindowRect +Windows.Win32.UI.WindowsAndMessaging.HCURSOR +Windows.Win32.UI.WindowsAndMessaging.HICON +Windows.Win32.UI.WindowsAndMessaging.HMENU +Windows.Win32.UI.WindowsAndMessaging.HTBOTTOM +Windows.Win32.UI.WindowsAndMessaging.HTBOTTOMLEFT +Windows.Win32.UI.WindowsAndMessaging.HTBOTTOMRIGHT +Windows.Win32.UI.WindowsAndMessaging.HTCAPTION +Windows.Win32.UI.WindowsAndMessaging.HTCLIENT +Windows.Win32.UI.WindowsAndMessaging.HTLEFT +Windows.Win32.UI.WindowsAndMessaging.HTRIGHT +Windows.Win32.UI.WindowsAndMessaging.HTSYSMENU +Windows.Win32.UI.WindowsAndMessaging.HTTOP +Windows.Win32.UI.WindowsAndMessaging.HTTOPLEFT +Windows.Win32.UI.WindowsAndMessaging.HTTOPRIGHT +Windows.Win32.UI.WindowsAndMessaging.HWND_NOTOPMOST +Windows.Win32.UI.WindowsAndMessaging.HWND_TOPMOST +Windows.Win32.UI.WindowsAndMessaging.IDC_ARROW +Windows.Win32.UI.WindowsAndMessaging.IDC_CROSS +Windows.Win32.UI.WindowsAndMessaging.IDC_HAND +Windows.Win32.UI.WindowsAndMessaging.IDC_HELP +Windows.Win32.UI.WindowsAndMessaging.IDC_IBEAM +Windows.Win32.UI.WindowsAndMessaging.IDC_NO +Windows.Win32.UI.WindowsAndMessaging.IDC_SIZEALL +Windows.Win32.UI.WindowsAndMessaging.IDC_SIZENESW +Windows.Win32.UI.WindowsAndMessaging.IDC_SIZENS +Windows.Win32.UI.WindowsAndMessaging.IDC_SIZENWSE +Windows.Win32.UI.WindowsAndMessaging.IDC_SIZEWE +Windows.Win32.UI.WindowsAndMessaging.IDI_WINLOGO +Windows.Win32.UI.WindowsAndMessaging.IMAGE_FLAGS +Windows.Win32.UI.WindowsAndMessaging.IMAGE_ICON +Windows.Win32.UI.WindowsAndMessaging.IsGUIThread +Windows.Win32.UI.WindowsAndMessaging.IsProcessDPIAware +Windows.Win32.UI.WindowsAndMessaging.KillTimer +Windows.Win32.UI.WindowsAndMessaging.LAYERED_WINDOW_ATTRIBUTES_FLAGS +Windows.Win32.UI.WindowsAndMessaging.LR_DEFAULTCOLOR +Windows.Win32.UI.WindowsAndMessaging.LWA_ALPHA +Windows.Win32.UI.WindowsAndMessaging.LoadCursorW +Windows.Win32.UI.WindowsAndMessaging.LoadIconW +Windows.Win32.UI.WindowsAndMessaging.LoadImageW +Windows.Win32.UI.WindowsAndMessaging.MSG +Windows.Win32.UI.WindowsAndMessaging.MoveWindow +Windows.Win32.UI.WindowsAndMessaging.NCCALCSIZE_PARAMS +Windows.Win32.UI.WindowsAndMessaging.PEEK_MESSAGE_REMOVE_TYPE +Windows.Win32.UI.WindowsAndMessaging.PM_NOREMOVE +Windows.Win32.UI.WindowsAndMessaging.PM_REMOVE +Windows.Win32.UI.WindowsAndMessaging.PeekMessageW +Windows.Win32.UI.WindowsAndMessaging.PostMessageW +Windows.Win32.UI.WindowsAndMessaging.RegisterClassExW +Windows.Win32.UI.WindowsAndMessaging.SET_WINDOW_POS_FLAGS +Windows.Win32.UI.WindowsAndMessaging.SHOW_WINDOW_CMD +Windows.Win32.UI.WindowsAndMessaging.SM_CXICON +Windows.Win32.UI.WindowsAndMessaging.SM_CXSMICON +Windows.Win32.UI.WindowsAndMessaging.SM_CYICON +Windows.Win32.UI.WindowsAndMessaging.SM_CYSMICON +Windows.Win32.UI.WindowsAndMessaging.SWP_FRAMECHANGED +Windows.Win32.UI.WindowsAndMessaging.SWP_NOACTIVATE +Windows.Win32.UI.WindowsAndMessaging.SWP_NOMOVE +Windows.Win32.UI.WindowsAndMessaging.SWP_NOSIZE +Windows.Win32.UI.WindowsAndMessaging.SWP_NOZORDER +Windows.Win32.UI.WindowsAndMessaging.SW_MAXIMIZE +Windows.Win32.UI.WindowsAndMessaging.SW_MINIMIZE +Windows.Win32.UI.WindowsAndMessaging.SW_RESTORE +Windows.Win32.UI.WindowsAndMessaging.SW_SHOW +Windows.Win32.UI.WindowsAndMessaging.SYSTEM_METRICS_INDEX +Windows.Win32.UI.WindowsAndMessaging.SendMessageW +Windows.Win32.UI.WindowsAndMessaging.SetCursor +Windows.Win32.UI.WindowsAndMessaging.SetLayeredWindowAttributes +Windows.Win32.UI.WindowsAndMessaging.SetTimer +Windows.Win32.UI.WindowsAndMessaging.SetWindowLongPtrW +Windows.Win32.UI.WindowsAndMessaging.SetWindowLongW +Windows.Win32.UI.WindowsAndMessaging.SetWindowPos +Windows.Win32.UI.WindowsAndMessaging.ShowCursor +Windows.Win32.UI.WindowsAndMessaging.ShowWindow +Windows.Win32.UI.WindowsAndMessaging.TIMERPROC +Windows.Win32.UI.WindowsAndMessaging.TranslateMessage +Windows.Win32.UI.WindowsAndMessaging.WA_ACTIVE +Windows.Win32.UI.WindowsAndMessaging.WINDOWPLACEMENT +Windows.Win32.UI.WindowsAndMessaging.WINDOWPLACEMENT_FLAGS +Windows.Win32.UI.WindowsAndMessaging.WINDOWPOS +Windows.Win32.UI.WindowsAndMessaging.WINDOW_EX_STYLE +Windows.Win32.UI.WindowsAndMessaging.WINDOW_LONG_PTR_INDEX +Windows.Win32.UI.WindowsAndMessaging.WINDOW_STYLE +Windows.Win32.UI.WindowsAndMessaging.WM_ACTIVATE +Windows.Win32.UI.WindowsAndMessaging.WM_CHAR +Windows.Win32.UI.WindowsAndMessaging.WM_CLOSE +Windows.Win32.UI.WindowsAndMessaging.WM_DESTROY +Windows.Win32.UI.WindowsAndMessaging.WM_DPICHANGED +Windows.Win32.UI.WindowsAndMessaging.WM_ENTERSIZEMOVE +Windows.Win32.UI.WindowsAndMessaging.WM_ERASEBKGND +Windows.Win32.UI.WindowsAndMessaging.WM_EXITSIZEMOVE +Windows.Win32.UI.WindowsAndMessaging.WM_IME_COMPOSITION +Windows.Win32.UI.WindowsAndMessaging.WM_IME_ENDCOMPOSITION +Windows.Win32.UI.WindowsAndMessaging.WM_IME_STARTCOMPOSITION +Windows.Win32.UI.WindowsAndMessaging.WM_KEYDOWN +Windows.Win32.UI.WindowsAndMessaging.WM_KEYUP +Windows.Win32.UI.WindowsAndMessaging.WM_LBUTTONDOWN +Windows.Win32.UI.WindowsAndMessaging.WM_LBUTTONUP +Windows.Win32.UI.WindowsAndMessaging.WM_MBUTTONDOWN +Windows.Win32.UI.WindowsAndMessaging.WM_MBUTTONUP +Windows.Win32.UI.WindowsAndMessaging.WM_MOUSEMOVE +Windows.Win32.UI.WindowsAndMessaging.WM_MOUSEWHEEL +Windows.Win32.UI.WindowsAndMessaging.WM_NCCALCSIZE +Windows.Win32.UI.WindowsAndMessaging.WM_NCHITTEST +Windows.Win32.UI.WindowsAndMessaging.WM_QUIT +Windows.Win32.UI.WindowsAndMessaging.WM_RBUTTONDOWN +Windows.Win32.UI.WindowsAndMessaging.WM_RBUTTONUP +Windows.Win32.UI.WindowsAndMessaging.WM_SIZE +Windows.Win32.UI.WindowsAndMessaging.WM_SYSKEYDOWN +Windows.Win32.UI.WindowsAndMessaging.WM_SYSKEYUP +Windows.Win32.UI.WindowsAndMessaging.WM_USER +Windows.Win32.UI.WindowsAndMessaging.WM_XBUTTONDOWN +Windows.Win32.UI.WindowsAndMessaging.WM_XBUTTONUP +Windows.Win32.UI.WindowsAndMessaging.WNDCLASSEXW +Windows.Win32.UI.WindowsAndMessaging.WNDCLASS_STYLES +Windows.Win32.UI.WindowsAndMessaging.WNDPROC +Windows.Win32.UI.WindowsAndMessaging.WS_BORDER +Windows.Win32.UI.WindowsAndMessaging.WS_CAPTION +Windows.Win32.UI.WindowsAndMessaging.WS_CLIPCHILDREN +Windows.Win32.UI.WindowsAndMessaging.WS_CLIPSIBLINGS +Windows.Win32.UI.WindowsAndMessaging.WS_EX_ACCEPTFILES +Windows.Win32.UI.WindowsAndMessaging.WS_EX_APPWINDOW +Windows.Win32.UI.WindowsAndMessaging.WS_EX_LAYERED +Windows.Win32.UI.WindowsAndMessaging.WS_EX_TOOLWINDOW +Windows.Win32.UI.WindowsAndMessaging.WS_EX_TOPMOST +Windows.Win32.UI.WindowsAndMessaging.WS_EX_WINDOWEDGE +Windows.Win32.UI.WindowsAndMessaging.WS_OVERLAPPEDWINDOW +Windows.Win32.UI.WindowsAndMessaging.WS_POPUP +Windows.Win32.UI.WindowsAndMessaging.WS_THICKFRAME diff --git a/tools/windows_bindgen/src/main.rs b/tools/windows_bindgen/src/main.rs new file mode 100644 index 000000000..c29edb928 --- /dev/null +++ b/tools/windows_bindgen/src/main.rs @@ -0,0 +1,240 @@ +//! Regenerate the vendored `windows` crate bindings. +//! +//! `libs/windows/windows-rs` is upstream `windows` 0.62.2 with ONE generated +//! file, `src/Windows/mod.rs`, holding exactly the APIs this repo uses (plus +//! their metadata dependencies) instead of the 10M-line full crate. This tool +//! is the only way that file changes: +//! +//! ```text +//! cd tools/windows_bindgen && cargo run --release +//! ``` +//! +//! It runs `windows-bindgen` 0.62.1 in `--package --implement` mode over +//! `filter.txt` (one fully-qualified type, function, constant or namespace per +//! line; `#` comments allowed), closes the set over every dependency the +//! generator would otherwise skip a member for, folds the per-namespace files +//! into the single nested-module file the crate `include!`s (keeping every +//! `#[cfg(feature = "...")]` gate, module-level ones included, so the feature +//! algebra is exactly upstream's), and normalizes +//! the two spots where the published 0.62.1 generator predates the vendored +//! windows-core 0.62.2 (`Error::from_thread`, `imp::array_proxy`). Item-level +//! A consumer enables the features for the namespaces it uses, as with the +//! upstream crate. +//! +//! To use a new Windows API: add it (or its namespace) to `filter.txt`, run +//! this, and `cargo check --target x86_64-pc-windows-msvc` the consumers +//! (platform, platform/video, platform/network, libs/system_speech, mpterm). + +use std::collections::BTreeSet; +use std::fs; +use std::path::{Path, PathBuf}; + +fn main() { + let tool_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let repo = tool_dir + .parent() + .and_then(Path::parent) + .expect("tools/windows_bindgen sits two levels below the repo root"); + let filter = tool_dir.join("filter.txt"); + let out_file = repo.join("libs/windows/windows-rs/src/Windows/mod.rs"); + let pkg_dir = tool_dir.join("target/bindgen-package"); + + let filter_text = fs::read_to_string(&filter).expect("read filter.txt"); + let mut wanted: BTreeSet = filter_text + .lines() + .map(|line| line.split('#').next().unwrap_or("").trim()) + .filter(|line| !line.is_empty()) + .map(str::to_string) + .collect(); + eprintln!("windows-bindgen: {} filter entries", wanted.len()); + + // A member whose parameter or return type is outside the set is skipped by + // the generator — but its `_Impl` vtable slot is still emitted, and the two + // disagree (a `usize` placeholder against a fn item). Closing the set over + // those dependencies removes every skip, so the output is self-consistent. + for round in 1..=20 { + let _ = fs::remove_dir_all(&pkg_dir); + fs::create_dir_all(&pkg_dir).expect("create package dir"); + let warnings = generate(&pkg_dir, &wanted); + let missing = missing_dependencies(&warnings.to_string()); + if missing.is_empty() { + break; + } + eprintln!("round {round}: {} skipped members, adding {} dependency types", warnings.len(), missing.len()); + let before = wanted.len(); + wanted.extend(missing); + if wanted.len() == before { + panic!("the generator keeps skipping members it was already given:\n{warnings}"); + } + } + + let flat = normalize(&flatten(&pkg_dir.join("src/Windows"))); + fs::write(&out_file, &flat).expect("write mod.rs"); + eprintln!("wrote {} ({} lines)", out_file.display(), flat.lines().count()); +} + +fn generate(pkg_dir: &Path, wanted: &BTreeSet) -> windows_bindgen::Warnings { + let mut args: Vec = vec![ + "--in".into(), + "default".into(), + "--package".into(), + "--no-toml".into(), + // Upstream generates the `*_Impl` traits too; consumers implement COM + // interfaces (drop targets, MF callbacks) through them. + "--implement".into(), + // Upstream links Win32 imports through windows_core, not windows_link; + // the vendored crate has no windows-link dependency. + "--link".into(), + "windows_core".into(), + // Upstream's own rustfmt.toml: one item per line, 800 columns. The repo + // root's rustfmt.toml disables formatting; override it here or the + // generator falls back to raw token soup. + "--rustfmt".into(), + "disable_all_formatting=false,max_width=800,newline_style=Unix".into(), + "--out".into(), + pkg_dir.to_string_lossy().into_owned(), + "--filter".into(), + ]; + args.extend(wanted.iter().cloned()); + windows_bindgen::bindgen(args.iter().map(String::as_str)) +} + +/// The types named under "due to missing dependencies:" in the warnings. +fn missing_dependencies(warnings: &str) -> BTreeSet { + let mut out = BTreeSet::new(); + let mut in_list = false; + for line in warnings.lines() { + if line.contains("due to missing dependencies") { + in_list = true; + continue; + } + if in_list { + if let Some(name) = line.strip_prefix(" Windows.") { + out.insert(format!("Windows.{}", name.trim())); + continue; + } + in_list = false; + } + } + out +} + +/// Fold one package-mode namespace directory: its items first, then each +/// submodule as `#[cfg(feature = "..")] pub mod Name{ ... }`, recursively. The +/// per-file header (generator comment, `#![allow(..)]`) is dropped; the +/// module declarations become inline modules with the same gate; everything +/// else is kept verbatim. +fn flatten(dir: &Path) -> String { + let text = fs::read_to_string(dir.join("mod.rs")).unwrap_or_else(|e| panic!("{}: {e}", dir.display())); + let lines: Vec<&str> = text.lines().collect(); + let mut i = 0; + while i < lines.len() && (lines[i].starts_with("// Bindings generated") || lines[i].trim().is_empty()) { + i += 1; + } + if i < lines.len() && lines[i].starts_with("#![allow(") { + // One line at max_width=800, several at rustfmt defaults. + while i < lines.len() && !lines[i].trim_end().ends_with(")]") { + i += 1; + } + i += 1; + while i < lines.len() && lines[i].trim().is_empty() { + i += 1; + } + } + let mut items = String::new(); + let mut mods: Vec<(Option<&str>, &str)> = Vec::new(); + while i < lines.len() { + let line = lines[i]; + if let Some(name) = submodule_decl(line) { + mods.push((None, name)); + i += 1; + continue; + } + if line.starts_with("#[cfg(") && line.ends_with(")]") { + if let Some(name) = lines.get(i + 1).and_then(|l| submodule_decl(l)) { + mods.push((Some(line), name)); + i += 2; + continue; + } + } + items.push_str(line); + items.push('\n'); + i += 1; + } + let mut out = items; + for (cfg, name) in mods { + if let Some(cfg) = cfg { + out.push_str(cfg); + out.push('\n'); + } + out.push_str("pub mod "); + out.push_str(name); + out.push_str("{\n"); + out.push_str(&flatten(&dir.join(name))); + out.push_str("}\n"); + } + out +} + +fn submodule_decl(line: &str) -> Option<&str> { + line.strip_prefix("pub mod ")?.strip_suffix(';') +} + +/// The published windows-bindgen 0.62.1 targets windows-core 0.62.1; the +/// vendored core is 0.62.2, which renamed the last-error constructor and moved +/// the implement-side array proxy. These are the only two differences the +/// generated code shows against the upstream 0.62.2 sources. +fn normalize(text: &str) -> String { + let mut out = String::with_capacity(text.len()); + for line in text.lines() { + let line = line.replace("windows_core::Error::from_win32", "windows_core::Error::from_thread"); + let line = rewrite_array_proxy(&line); + out.push_str(&line); + out.push('\n'); + } + out +} + +/// `windows_core::ArrayProxy::from_raw_parts(ARGS).as_array()` -> +/// `&mut windows_core::imp::array_proxy(ARGS)` (what upstream 0.62.2 emits). +fn rewrite_array_proxy(line: &str) -> String { + const OLD: &str = "windows_core::ArrayProxy::from_raw_parts("; + const TAIL: &str = ").as_array()"; + let mut rest = line; + let mut out = String::new(); + while let Some(start) = rest.find(OLD) { + out.push_str(&rest[..start]); + let after = &rest[start + OLD.len()..]; + let Some(end) = after.find(TAIL) else { + panic!("unexpected array proxy form: {line}"); + }; + out.push_str("&mut windows_core::imp::array_proxy("); + out.push_str(&after[..end]); + out.push(')'); + rest = &after[end + TAIL.len()..]; + } + out.push_str(rest); + out +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn array_proxy_call_sites_take_the_upstream_form() { + let line = "IPropertyValue_Impl::GetUInt8Array(this, windows_core::ArrayProxy::from_raw_parts(core::mem::transmute_copy(&value), value_array_size).as_array()).into()"; + assert_eq!( + rewrite_array_proxy(line), + "IPropertyValue_Impl::GetUInt8Array(this, &mut windows_core::imp::array_proxy(core::mem::transmute_copy(&value), value_array_size)).into()" + ); + } + + #[test] + fn missing_dependency_lists_are_parsed() { + let text = "skipping `A.B` due to missing dependencies:\n Windows.Win32.System.Search.Common.CONDITION_OPERATION\n Windows.Foundation.X\nskipping `C` due to missing dependencies:\n Windows.Foundation.X\n"; + let missing = missing_dependencies(text); + assert_eq!(missing.len(), 2); + assert!(missing.contains("Windows.Foundation.X")); + } +} From 97e9572f429fb46bb6dbd702ab5287d1d3753ce9 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 23:32:35 +0200 Subject: [PATCH 028/417] speech: one STT/TTS API on every platform, through the ai-hub Apps ask the hub for a recognizer or a voice and get one; where it runs is the hub's decision. AiHub::start_stt / start_tts return poll-driven sessions shaped like the chat session. The Auto ladder is Whisper/Kokoro in this process (weights present, machine election), on the machine node over loopback, on a LAN node, else the OS engine; SpeechReach::Local is the "don't reach out" knob. Audio always comes back as PCM: the app owns the device. Three layers: - makepad-ai-speech is the whole speech model family, engines only. libs/voice (Whisper + Silero VAD) folds in as the `whisper` and `vad` modules next to kokoro and indextts, each a cargo feature; the Apple bridges and the Speaker/VoiceTranscriber selection leave it. - makepad-system-speech (new) is the OS speech services as blocking fns: Apple SpeechAnalyzer/AVSpeechSynthesizer via Swift, Windows.Media.Speech* on the vendored bindings, Android SpeechRecognizer/TextToSpeech through MakepadSpeech.java (API 26 floor), espeak-ng on Linux. It models the two STT shapes honestly: PCM in (Whisper, Apple) versus an engine that owns the microphone (Android, Windows), with capabilities the caller reads. - the hub grows speech sessions, in-process Whisper/Kokoro workers with the residency election, a `whisper` wire backend (stt domain, registry entry pinned to ggerganov/whisper.cpp) so a Mac can serve a Quest, and a `language` field on the generate request. Consumers: the Window voice input runs on an STT session and switches to engine-mic mode when the recognizer owns the microphone; converse's SpeechOutput is a lazily started TTS session plus a pump thread; route drops its private speech copy for converse; vj's lyrics fallback and the alignment bakes call the engines directly. Verified here: speech-roundtrip through the real sessions (Apple voice in, in-process Whisper on Metal out, 4.3% WER); system-speech-test TTS->STT verbatim; hub/converse/system-speech unit tests; msvc, aarch64-android and linux-gnu cross-checks; Java against android-34. Windows, Android and Linux bridges are compile-checked only. Co-Authored-By: Claude Fable 5.1 --- Cargo.toml | 2 +- apps/route/Cargo.toml | 1 - apps/route/src/main.rs | 15 +- apps/route/src/speech.rs | 225 -------- apps/vj/Cargo.toml | 3 +- apps/vj/src/bin/karaoke_align.rs | 4 +- apps/vj/src/lyrics.rs | 58 +- libs/ai/cuda/build.rs | 2 +- libs/ai/hub/Cargo.toml | 20 +- libs/ai/hub/registry.json | 26 + libs/ai/hub/src/backend.rs | 13 + libs/ai/hub/src/bin/speech_roundtrip.rs | 248 +++++++++ libs/ai/hub/src/control_backend.rs | 1 + libs/ai/hub/src/hub.rs | 15 + libs/ai/hub/src/inpaint_backend.rs | 1 + libs/ai/hub/src/jobs.rs | 1 + libs/ai/hub/src/lib.rs | 4 + libs/ai/hub/src/protocol.rs | 25 + libs/ai/hub/src/registry.rs | 5 + libs/ai/hub/src/speech/mod.rs | 508 ++++++++++++++++++ libs/ai/hub/src/speech/remote.rs | 189 +++++++ libs/ai/hub/src/speech/stt_worker.rs | 364 +++++++++++++ libs/ai/hub/src/speech/tts_worker.rs | 312 +++++++++++ libs/ai/hub/src/speech/weights.rs | 182 +++++++ libs/ai/hub/src/whisper_backend.rs | 282 ++++++++++ libs/ai/models/speech/Cargo.toml | 57 +- libs/ai/models/speech/build.rs | 192 ++++--- libs/ai/models/speech/examples/roundtrip.rs | 130 ----- libs/ai/models/speech/examples/score_wav.rs | 98 ---- libs/ai/models/speech/src/apple.rs | 48 -- .../speech}/src/bin/metal_strip_unused.rs | 0 libs/ai/models/speech/src/bin/tts_test.rs | 117 ++-- .../models/speech}/src/bin/vad_test.rs | 2 +- .../models/speech}/src/bin/whisper_parity.rs | 12 +- .../models/speech}/src/bin/whisper_test.rs | 6 +- libs/ai/models/speech/src/convert.rs | 4 +- libs/ai/models/speech/src/lib.rs | 27 +- libs/ai/models/speech/src/tts.rs | 105 +--- libs/{voice => ai/models/speech}/src/vad.rs | 0 .../models/speech/src/whisper}/accel.rs | 16 +- .../models/speech/src/whisper}/cpu/align.rs | 6 +- .../speech/src/whisper}/cpu/decode_loop.rs | 48 +- .../models/speech/src/whisper}/cpu/decoder.rs | 34 +- .../models/speech/src/whisper}/cpu/encoder.rs | 40 +- .../models/speech/src/whisper}/cpu/mel.rs | 2 +- .../models/speech/src/whisper}/cpu/model.rs | 6 +- .../models/speech/src/whisper}/cpu/quant.rs | 0 .../models/speech/src/whisper}/cpu/tensor.rs | 66 +-- .../speech/src/whisper}/cuda/backend.rs | 16 +- .../speech/src/whisper}/metal/backend.rs | 28 +- .../speech/src/whisper}/metal/ggml/LICENSE | 0 .../src/whisper}/metal/ggml/ggml-common.h | 0 .../src/whisper}/metal/ggml/ggml-metal-impl.h | 0 .../src/whisper}/metal/ggml/ggml-metal.metal | 0 .../models/speech/src/whisper/mod.rs} | 14 - .../models/speech/src/whisper}/settings.rs | 0 libs/ai/models/speech/swift/tts_bridge.swift | 98 ---- .../tests/fixtures/silero_ref_speech.txt | 0 .../tests/fixtures/silero_ref_synth.txt | 0 .../models/speech}/tests/silero_vad.rs | 2 +- libs/audio_lyrics/Cargo.toml | 2 +- libs/audio_lyrics/src/align.rs | 6 +- libs/audio_lyrics/src/bake.rs | 10 +- libs/converse/Cargo.toml | 9 +- libs/converse/src/speech.rs | 249 +++++---- libs/system_speech/Cargo.toml | 46 ++ libs/system_speech/build.rs | 198 +++++++ .../src/bin/system_speech_test.rs | 133 +++++ libs/system_speech/src/lib.rs | 424 +++++++++++++++ libs/system_speech/src/platform/android.rs | 457 ++++++++++++++++ libs/system_speech/src/platform/apple.rs | 185 +++++++ libs/system_speech/src/platform/linux.rs | 360 +++++++++++++ libs/system_speech/src/platform/mod.rs | 51 ++ libs/system_speech/src/platform/none.rs | 47 ++ libs/system_speech/src/platform/windows.rs | 506 +++++++++++++++++ libs/system_speech/src/wav.rs | 157 ++++++ .../swift/stt_bridge.swift} | 89 ++- libs/system_speech/swift/tts_bridge.swift | 148 +++++ libs/voice/Cargo.toml | 37 -- libs/voice/build.rs | 362 ------------- libs/voice/src/apple/speech.rs | 90 ---- libs/voice/src/bin/apple_speech_test.rs | 116 ---- libs/voice/src/transcriber.rs | 298 ---------- tools/cargo_makepad/src/android/compile.rs | 1 + .../dev/makepad/android/MakepadActivity.java | 44 ++ .../dev/makepad/android/MakepadSpeech.java | 463 ++++++++++++++++ tools/cargo_makepad/src/android/mod.rs | 10 + widgets/Cargo.toml | 8 +- widgets/src/window_voice_input.rs | 178 ++++-- 89 files changed, 6160 insertions(+), 2204 deletions(-) delete mode 100644 apps/route/src/speech.rs create mode 100644 libs/ai/hub/src/bin/speech_roundtrip.rs create mode 100644 libs/ai/hub/src/speech/mod.rs create mode 100644 libs/ai/hub/src/speech/remote.rs create mode 100644 libs/ai/hub/src/speech/stt_worker.rs create mode 100644 libs/ai/hub/src/speech/tts_worker.rs create mode 100644 libs/ai/hub/src/speech/weights.rs create mode 100644 libs/ai/hub/src/whisper_backend.rs delete mode 100644 libs/ai/models/speech/examples/roundtrip.rs delete mode 100644 libs/ai/models/speech/examples/score_wav.rs delete mode 100644 libs/ai/models/speech/src/apple.rs rename libs/{voice => ai/models/speech}/src/bin/metal_strip_unused.rs (100%) rename libs/{voice => ai/models/speech}/src/bin/vad_test.rs (98%) rename libs/{voice => ai/models/speech}/src/bin/whisper_parity.rs (94%) rename libs/{voice => ai/models/speech}/src/bin/whisper_test.rs (96%) rename libs/{voice => ai/models/speech}/src/vad.rs (100%) rename libs/{voice/src => ai/models/speech/src/whisper}/accel.rs (95%) rename libs/{voice/src => ai/models/speech/src/whisper}/cpu/align.rs (99%) rename libs/{voice/src => ai/models/speech/src/whisper}/cpu/decode_loop.rs (94%) rename libs/{voice/src => ai/models/speech/src/whisper}/cpu/decoder.rs (95%) rename libs/{voice/src => ai/models/speech/src/whisper}/cpu/encoder.rs (89%) rename libs/{voice/src => ai/models/speech/src/whisper}/cpu/mel.rs (99%) rename libs/{voice/src => ai/models/speech/src/whisper}/cpu/model.rs (99%) rename libs/{voice/src => ai/models/speech/src/whisper}/cpu/quant.rs (100%) rename libs/{voice/src => ai/models/speech/src/whisper}/cpu/tensor.rs (96%) rename libs/{voice/src => ai/models/speech/src/whisper}/cuda/backend.rs (98%) rename libs/{voice/src => ai/models/speech/src/whisper}/metal/backend.rs (99%) rename libs/{voice/src => ai/models/speech/src/whisper}/metal/ggml/LICENSE (100%) rename libs/{voice/src => ai/models/speech/src/whisper}/metal/ggml/ggml-common.h (100%) rename libs/{voice/src => ai/models/speech/src/whisper}/metal/ggml/ggml-metal-impl.h (100%) rename libs/{voice/src => ai/models/speech/src/whisper}/metal/ggml/ggml-metal.metal (100%) rename libs/{voice/src/lib.rs => ai/models/speech/src/whisper/mod.rs} (90%) rename libs/{voice/src => ai/models/speech/src/whisper}/settings.rs (100%) delete mode 100644 libs/ai/models/speech/swift/tts_bridge.swift rename libs/{voice => ai/models/speech}/tests/fixtures/silero_ref_speech.txt (100%) rename libs/{voice => ai/models/speech}/tests/fixtures/silero_ref_synth.txt (100%) rename libs/{voice => ai/models/speech}/tests/silero_vad.rs (98%) create mode 100644 libs/system_speech/Cargo.toml create mode 100644 libs/system_speech/build.rs create mode 100644 libs/system_speech/src/bin/system_speech_test.rs create mode 100644 libs/system_speech/src/lib.rs create mode 100644 libs/system_speech/src/platform/android.rs create mode 100644 libs/system_speech/src/platform/apple.rs create mode 100644 libs/system_speech/src/platform/linux.rs create mode 100644 libs/system_speech/src/platform/mod.rs create mode 100644 libs/system_speech/src/platform/none.rs create mode 100644 libs/system_speech/src/platform/windows.rs create mode 100644 libs/system_speech/src/wav.rs rename libs/{voice/swift/speech_bridge.swift => system_speech/swift/stt_bridge.swift} (62%) create mode 100644 libs/system_speech/swift/tts_bridge.swift delete mode 100644 libs/voice/Cargo.toml delete mode 100644 libs/voice/build.rs delete mode 100644 libs/voice/src/apple/speech.rs delete mode 100644 libs/voice/src/bin/apple_speech_test.rs delete mode 100644 libs/voice/src/transcriber.rs create mode 100644 tools/cargo_makepad/src/android/java/dev/makepad/android/MakepadSpeech.java diff --git a/Cargo.toml b/Cargo.toml index 93abc404c..43ddada9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -137,6 +137,7 @@ workspace.members = [ "tools/map_tiles", "tools/map_bake", "tools/remote", + "libs/system_speech", # === tests === "platform/script/test", ] @@ -155,7 +156,6 @@ workspace.exclude = [ "libs/diffusion", # the AI model workspace (loader + cuda/metal stores + model crates) — aiarch.md "libs/ai", - "libs/voice", "widgets/test", "libs/stitch", "libs/wasm_bridge/test", diff --git a/apps/route/Cargo.toml b/apps/route/Cargo.toml index 05ae34020..9d6ce916a 100644 --- a/apps/route/Cargo.toml +++ b/apps/route/Cargo.toml @@ -10,7 +10,6 @@ makepad-widgets = { path = "../../widgets", version = "2.0.0", features = ["maps mp-theme = { path = "../../libs/mp_theme" } makepad-map-nav = { path = "../../libs/map_nav" } # M1: route.* tools (search + A* graph) makepad-map-build = { path = "../../libs/map_build", features = ["faces"] } # first run: download + bake a test map -makepad-ai-speech = { path = "../../libs/ai/models/speech" } # kokoro voice output (🔊) makepad-geodata = { path = "../../libs/geodata" } # M1: geo.* corridor queries, rain radar makepad-mbtile-reader = { path = "../../libs/mbtile_reader" } # terrain drape landcover source serde_json = "1" # geodata FeatureHit attrs diff --git a/apps/route/src/main.rs b/apps/route/src/main.rs index e74e2780f..deb597dcd 100644 --- a/apps/route/src/main.rs +++ b/apps/route/src/main.rs @@ -22,7 +22,6 @@ mod layers; mod local_agent; mod nav; mod nav_data; -mod speech; mod testmap; mod tools; mod trip; @@ -34,7 +33,7 @@ use history::DriveLog; use layers::{LayerState, TerrainUpdate, WindUpdate}; use nav::{ActiveNav, NavAction, NavTick}; use nav_data::{NavData, NavLoad, RadarData}; -use speech::Speech; +use makepad_converse::SpeechOutput; use testmap::{Stage as TestMapStage, TestMapBuild}; use trip::TripModel; use voice::{GateResult, VoiceGate}; @@ -918,7 +917,7 @@ pub struct App { terrain_rx: ToUIReceiver, /// Kokoro voice output (🔊 button). None until first startup. #[rust] - speech: Option, + speech: Option, /// Last nav banner instruction spoken, so each maneuver is announced once. #[rust] last_spoken_banner: String, @@ -1046,8 +1045,10 @@ impl App { self.adopt_map_source(cx); nav_data::start_radar_worker(self.radar_rx.sender()); cx.start_location_updates(); - let speech = Speech::new(); - speech.install_audio_output(cx); + // Kokoro af_heart when weights are in reach (this process, the machine + // node, a LAN box), else the OS voice — the hub decides. + let speech = SpeechOutput::new("af_heart"); + speech.install_audio_output(cx, 0); self.speech = Some(speech); self.init_agent(cx); self.update_ai_status(cx); @@ -1594,7 +1595,7 @@ impl App { if tick.banner != self.last_spoken_banner { self.last_spoken_banner = tick.banner.clone(); if let Some(speech) = &self.speech { - speech.say(&tick.banner); + speech.enqueue(&tick.banner); } } } @@ -1608,7 +1609,7 @@ impl App { .unwrap_or_default(); self.push_line(cx, &format!("🏁 arrived at {dest}")); if let Some(speech) = &self.speech { - speech.say(&format!("You have arrived at {dest}.")); + speech.enqueue(&format!("You have arrived at {dest}.")); } self.active_nav = None; let map = self.ui.map_view(cx, ids!(map)); diff --git a/apps/route/src/speech.rs b/apps/route/src/speech.rs deleted file mode 100644 index 118011a8c..000000000 --- a/apps/route/src/speech.rs +++ /dev/null @@ -1,225 +0,0 @@ -//! Kokoro voice output (ported from examples/godot): a synthesis worker -//! fills a PCM buffer that the `cx.audio_output` callback drains. Muting is -//! "stop feeding the buffer", which also makes it instant. Streamed reply -//! text is spoken sentence-by-sentence so the voice keeps pace with -//! generation; nav turn instructions go through `say` directly. - -use makepad_ai_speech::Speaker; -use makepad_widgets::*; -use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; -use std::sync::{mpsc, Arc, Mutex}; - -/// The buffer the audio callback plays from. Written by the synthesis -/// worker, read by the audio thread. -#[derive(Default)] -pub struct Playback { - samples: Vec, - cursor: f64, - source_rate: f64, -} - -pub struct Speech { - say_tx: mpsc::Sender<(u64, String)>, - playback: Arc>, - muted: Arc, - /// Bumped on stop. Requests from an older generation are dropped, so a - /// sentence that was already being synthesized never plays after a cancel. - generation: Arc, - /// Streamed reply text not yet spoken. - pending: String, -} - -/// Don't speak a fragment shorter than this — one-word clips sound like hiccups. -const MIN_SPOKEN_CHARS: usize = 16; - -impl Speech { - pub fn new() -> Self { - let playback = Arc::new(Mutex::new(Playback::default())); - let muted = Arc::new(AtomicBool::new(false)); - let generation = Arc::new(AtomicU64::new(0)); - let (say_tx, requests) = mpsc::channel::<(u64, String)>(); - - let worker_playback = playback.clone(); - let worker_generation = generation.clone(); - std::thread::spawn(move || { - // Off the main thread on purpose: synthesis blocks until the - // whole utterance is rendered. - let mut speaker = Speaker::from_makepad_env_with_voice("af_heart.mkvoice"); - log!("tts: backend {:?}", speaker.kind()); - // Discarded warm-up: Kokoro's first synthesis initializes the - // Metal context on this thread; better now than on the first turn. - let _ = speaker.synthesize("Hi."); - while let Ok((generation, text)) = requests.recv() { - if generation != worker_generation.load(Ordering::Relaxed) { - continue; - } - match speaker.synthesize(&text) { - Ok(audio) if !audio.is_empty() => { - // Re-check: synthesis is slow enough that a cancel - // can land while it runs. - if generation != worker_generation.load(Ordering::Relaxed) { - continue; - } - let mut playback = worker_playback.lock().unwrap(); - if playback.source_rate != audio.sample_rate as f64 { - playback.samples.clear(); - playback.cursor = 0.0; - playback.source_rate = audio.sample_rate as f64; - } - // Append, don't replace: sentences queue up. - playback.samples.extend_from_slice(&audio.samples); - } - Ok(_) => {} - Err(err) => log!("tts: {err:?}"), - } - } - }); - - Self { - say_tx, - playback, - muted, - generation, - pending: String::new(), - } - } - - /// Install the playback callback. Output device selection stays with the - /// app's AudioDevices handler (`cx.use_audio_outputs`). - pub fn install_audio_output(&self, cx: &mut Cx) { - let playback = self.playback.clone(); - let muted = self.muted.clone(); - cx.audio_output(0, move |info, output| { - output.zero(); - if muted.load(Ordering::Relaxed) { - return; - } - let Ok(mut playback) = playback.lock() else { - return; - }; - if playback.samples.is_empty() || playback.source_rate <= 0.0 { - return; - } - // Resample on the fly: the backend's rate is not the device's. - let step = playback.source_rate / info.sample_rate; - let channels = output.channel_count(); - for frame in 0..output.frame_count() { - let index = playback.cursor as usize; - if index + 1 >= playback.samples.len() { - playback.samples.clear(); - playback.cursor = 0.0; - break; - } - let fraction = (playback.cursor - index as f64) as f32; - let a = playback.samples[index]; - let b = playback.samples[index + 1]; - let sample = a + (b - a) * fraction; - for channel in 0..channels { - output.channel_mut(channel)[frame] = sample; - } - playback.cursor += step; - } - // Sentences append while earlier ones play, so drop the consumed - // prefix periodically or the buffer grows for the whole reply. - if playback.cursor > 2.0 * playback.source_rate { - let consumed = playback.cursor as usize; - playback.samples.drain(..consumed); - playback.cursor -= consumed as f64; - } - }); - } - - /// Feed streamed reply text. Each finished sentence is spoken as soon - /// as it lands. - pub fn feed(&mut self, delta: &str) { - self.pending.push_str(delta); - while let Some(sentence) = self.take_sentence() { - self.enqueue(&sentence); - } - } - - /// Speak whatever is left over at the end of a turn. - pub fn flush(&mut self) { - let rest = std::mem::take(&mut self.pending); - self.enqueue(&rest); - } - - /// Speak a standalone phrase now (nav turn instructions). - pub fn say(&self, text: &str) { - self.enqueue(text); - } - - /// True while synthesized audio is still playing — used to drop mic - /// transcripts of the assistant's own voice (no echo cancellation yet). - pub fn is_speaking(&self) -> bool { - self.playback - .lock() - .map(|p| !p.samples.is_empty()) - .unwrap_or(false) - } - - fn take_sentence(&mut self) -> Option { - let mut split_at = None; - for (index, ch) in self.pending.char_indices() { - let boundary = matches!(ch, '.' | '!' | '?' | '\n' | ':'); - if boundary && index + ch.len_utf8() >= MIN_SPOKEN_CHARS { - split_at = Some(index + ch.len_utf8()); - break; - } - } - let at = split_at?; - let rest = self.pending.split_off(at); - Some(std::mem::replace(&mut self.pending, rest)) - } - - fn enqueue(&self, raw: &str) { - if self.muted.load(Ordering::Relaxed) { - return; - } - let text = spoken_text(raw); - if text.is_empty() { - return; - } - let _ = self - .say_tx - .send((self.generation.load(Ordering::Relaxed), text)); - } - - pub fn stop(&mut self) { - self.generation.fetch_add(1, Ordering::Relaxed); - self.pending.clear(); - if let Ok(mut playback) = self.playback.lock() { - playback.samples.clear(); - playback.cursor = 0.0; - } - } - - pub fn is_muted(&self) -> bool { - self.muted.load(Ordering::Relaxed) - } - - pub fn set_muted(&mut self, muted: bool) { - self.muted.store(muted, Ordering::Relaxed); - if muted { - self.stop(); - } - } -} - -/// Text is for reading, not speaking: drop markdown/markup symbols and -/// emoji-ish prefixes that would be read aloud as punctuation soup. -fn spoken_text(text: &str) -> String { - let mut spoken = String::with_capacity(text.len()); - for line in text.lines() { - let cleaned: String = line - .chars() - .filter(|c| !matches!(c, '*' | '_' | '`' | '#' | '>' | '|' | '→' | '⚙' | '·')) - .collect(); - let cleaned = cleaned.trim(); - if !cleaned.is_empty() { - spoken.push_str(cleaned); - spoken.push(' '); - } - } - spoken.trim().to_string() -} diff --git a/apps/vj/Cargo.toml b/apps/vj/Cargo.toml index b83fb23eb..f542d3de2 100644 --- a/apps/vj/Cargo.toml +++ b/apps/vj/Cargo.toml @@ -24,7 +24,8 @@ makepad-audio-decode = { path = "../../libs/audio_decode" } # Four-stem source separation for the music decks' stem mix. makepad-ai-stems = { path = "../../libs/ai/models/stems" } # Whisper transcription of the separated vocals stem: karaoke subtitles. -makepad-voice = { path = "../../libs/voice" } +makepad-ai-speech = { path = "../../libs/ai/models/speech", default-features = false, features = ["whisper"] } # whisper for lyrics alignment +makepad-system-speech = { path = "../../libs/system_speech" } # OS recognizer fallback for lyrics alignment makepad-audio-lyrics = { path = "../../libs/audio_lyrics" } # Stems + lyrics as server-stored side-channels: the encode/role/publish # implementation shared with the asset-ui bake. diff --git a/apps/vj/src/bin/karaoke_align.rs b/apps/vj/src/bin/karaoke_align.rs index b90b3402a..9c2959794 100644 --- a/apps/vj/src/bin/karaoke_align.rs +++ b/apps/vj/src/bin/karaoke_align.rs @@ -28,7 +28,7 @@ use makepad_audio_lyrics::align as lyrics_align; use lyrics_align::{OnsetPreset, SegmentWords, TimedLine, VocalAnalysis}; -use makepad_voice::{WhisperModel, WhisperParams, WhisperState}; +use makepad_ai_speech::whisper::{WhisperModel, WhisperParams, WhisperState}; use std::io::Write as _; use std::path::{Path, PathBuf}; @@ -431,7 +431,7 @@ fn audit_track( aligned.len(), aligned.iter().map(|segment| segment.words.len()).sum::(), started.elapsed().as_secs_f64(), - makepad_voice::accel_backend_name(), + makepad_ai_speech::whisper::accel_backend_name(), )); // Stage snapshots. diff --git a/apps/vj/src/lyrics.rs b/apps/vj/src/lyrics.rs index 3ffc13d59..d8904aa8a 100644 --- a/apps/vj/src/lyrics.rs +++ b/apps/vj/src/lyrics.rs @@ -1493,7 +1493,7 @@ fn run_job( // The Apple fallback yields to whisper the moment a checkpoint appears // (the INSTALL MODELS flow drops one in mid-session): whisper's measured // word path is strictly better than the dictation-tuned fallback. - if let Some(Transcriber::NativeApple(_)) = backend.as_ref() { + if let Some(Transcriber::System) = backend.as_ref() { if whisper_model_path().is_some() { *backend = None; } @@ -1630,7 +1630,7 @@ fn read_vocals_mono(job: &LyricsJob) -> Result<(Vec, f64), String> { // the transcriber // --------------------------------------------------------------------------- -/// Which of `makepad-voice`'s two backends is doing the work. +/// Which of `makepad-ai-speech`'s two backends is doing the work. /// /// Whisper is preferred and is what ships: `ggml-large-v3-turbo` transcribes /// SUNG speech, returns segment timestamps on a 20 ms grid, and takes a whole @@ -1639,39 +1639,38 @@ fn read_vocals_mono(job: &LyricsJob) -> Result<(Vec, f64), String> { /// timings are coarser. enum Transcriber { Whisper { - model: Box, - state: makepad_voice::WhisperState, + model: Box, + state: makepad_ai_speech::whisper::WhisperState, path: String, }, - NativeApple(makepad_voice::VoiceTranscriber), + /// The OS recognizer (makepad-system-speech): PCM in, coarse timings. + System, } impl Transcriber { fn open() -> Result { if let Some(path) = whisper_model_path() { let text = path.to_string_lossy().to_string(); - let model = makepad_voice::WhisperModel::load_file(&text) + let model = makepad_ai_speech::whisper::WhisperModel::load_file(&text) .map_err(|error| format!("whisper model: {error}"))?; - let state = makepad_voice::WhisperState::new(&model); + let state = makepad_ai_speech::whisper::WhisperState::new(&model); return Ok(Transcriber::Whisper { model: Box::new(model), state, path: text, }); } - let mut apple = - makepad_voice::VoiceTranscriber::new(makepad_voice::VoiceBackendKind::NativeApple); - let params = makepad_voice::VoiceTranscribeParams::default(); - apple - .preload(¶ms) - .map_err(|_| "no whisper checkpoint and no native recognizer".to_string())?; - Ok(Transcriber::NativeApple(apple)) + if !makepad_system_speech::stt::capabilities().pcm_input { + return Err("no whisper checkpoint and no PCM-input system recognizer".to_string()); + } + let _ = makepad_system_speech::stt::prepare("en"); + Ok(Transcriber::System) } fn name(&self) -> &'static str { match self { Transcriber::Whisper { .. } => "whisper", - Transcriber::NativeApple(_) => "apple-native", + Transcriber::System => makepad_system_speech::stt::engine_name(), } } @@ -1681,7 +1680,7 @@ impl Transcriber { .rsplit(['/', '\\']) .next() .unwrap_or(WHISPER_MODEL_FILE), - Transcriber::NativeApple(_) => "SFSpeechRecognizer", + Transcriber::System => "system", } } @@ -1702,7 +1701,7 @@ impl Transcriber { )> { match self { Transcriber::Whisper { model, state, .. } => { - let mut params = makepad_voice::WhisperParams::default(); + let mut params = makepad_ai_speech::whisper::WhisperParams::default(); params.language = language.to_string(); params.no_timestamps = false; params.single_segment = false; @@ -1724,7 +1723,7 @@ impl Transcriber { &config, )) } - Transcriber::NativeApple(_) => None, + Transcriber::System => None, } } @@ -1733,7 +1732,7 @@ impl Transcriber { samples: &[f32], language: &str, ) -> Result, String> { - let mut params = makepad_voice::WhisperParams::default(); + let mut params = makepad_ai_speech::whisper::WhisperParams::default(); params.language = language.to_string(); params.no_timestamps = false; params.single_segment = false; @@ -1741,14 +1740,19 @@ impl Transcriber { params.suppress_blank = true; let segments = match self { Transcriber::Whisper { model, state, .. } => state.transcribe(model, samples, ¶ms), - Transcriber::NativeApple(apple) => { - let mut voice = makepad_voice::VoiceTranscribeParams::default(); - voice.language = language.to_string(); - voice.include_timestamps = true; - voice.single_segment = false; - apple - .transcribe(samples, &voice) - .map_err(|error| format!("{error:?}"))? + Transcriber::System => { + let options = makepad_system_speech::SttOptions { + language: language.to_string(), + timestamps: true, + ..Default::default() + }; + let transcript = makepad_system_speech::stt::transcribe(samples, &options) + .map_err(|error| error.to_string())?; + return Ok(transcript + .segments + .into_iter() + .map(|segment| (segment.start_ms, segment.end_ms, segment.text)) + .collect()); } }; Ok(segments diff --git a/libs/ai/cuda/build.rs b/libs/ai/cuda/build.rs index a660e210a..7648a4ff4 100644 --- a/libs/ai/cuda/build.rs +++ b/libs/ai/cuda/build.rs @@ -21,7 +21,7 @@ use std::time::{Duration, Instant}; // Because this crate sets `links = "makepad_ai_cuda"`, the answer travels to // its immediate dependents as `DEP_MAKEPAD_AI_CUDA_KERNELS` (=1) and // `DEP_MAKEPAD_AI_CUDA_ARCH`. makepad-ai-llm, makepad-ai-metal, -// makepad-ai-common and makepad-voice gate their CUDA code on exactly that +// makepad-ai-common and makepad-ai-speech (whisper) gate their CUDA code on exactly that // and MUST NOT probe for a toolkit themselves: "nvcc exists on this machine" // and "kernels were built and will link" are different questions, and a // dependent that answers the first one locally is how a machine WITH the diff --git a/libs/ai/hub/Cargo.toml b/libs/ai/hub/Cargo.toml index 2a6919ec2..ce9c69072 100644 --- a/libs/ai/hub/Cargo.toml +++ b/libs/ai/hub/Cargo.toml @@ -20,6 +20,8 @@ default = [ "llm", "tts", "indextts", + "speech", + "stt", "video", "interpolate", "audio", @@ -49,10 +51,15 @@ paint = ["dep:makepad-ai-paint", "dep:makepad-gltf", "dep:makepad-remesh", "dep: paint-cuda = ["paint", "makepad-ai-paint/cuda-taps"] # Real LLM prompt expansion via makepad-ai-llm (Qwen3.5/3.6 GGUF). llm = ["dep:makepad-ai-llm"] +# Speech sessions (AiHub::start_stt / start_tts): the OS engines as the +# stt.system / tts.system pipes plus the in-process / machine / LAN ladder. +speech = ["dep:makepad-system-speech"] +# Whisper speech-to-text (stt.whisper), in-process and on the wire. +stt = ["speech", "dep:makepad-ai-speech", "makepad-ai-speech/whisper"] # Real Kokoro speech synthesis via makepad-ai-speech. -tts = ["dep:makepad-ai-speech"] +tts = ["dep:makepad-ai-speech", "makepad-ai-speech/kokoro"] # Real IndexTTS-2.5 character-voice TTS via makepad-ai-speech. -indextts = ["dep:makepad-ai-speech", "dep:makepad-ai-common"] +indextts = ["dep:makepad-ai-speech", "makepad-ai-speech/indextts", "dep:makepad-ai-common"] # Real MiniMax H3 video generation via makepad-ai-h3 plus the hardware # video file encoder (makepad-video). Does NOT pull the UI platform crate. video = ["dep:makepad-ai-h3", "dep:makepad-ai-common", "dep:makepad-video"] @@ -123,7 +130,8 @@ makepad-gltf = { path = "../../gltf", optional = true } makepad-xatlas = { path = "../../xatlas", optional = true } makepad-render = { path = "../../render", optional = true } makepad-ai-llm = { path = "../../ai/llm", optional = true } -makepad-ai-speech = { path = "../../ai/models/speech", optional = true } +makepad-ai-speech = { path = "../../ai/models/speech", default-features = false, optional = true } +makepad-system-speech = { path = "../../system_speech", optional = true } makepad-video = { path = "../../../platform/video", optional = true } # The `mkfl` motion payload: ONE definition, shared with the VJ's import # converter (which fills the same box from a classical, model-free flow @@ -169,3 +177,9 @@ path = "src/bin/context_ladder.rs" [[bin]] name = "ocr-bench" path = "src/bin/ocr_bench.rs" + +# TTS -> STT through the hub's own speech sessions, scored as word error rate: +# the scoreboard for comparing engines and the end-to-end check of the ladder. +[[bin]] +name = "speech-roundtrip" +path = "src/bin/speech_roundtrip.rs" diff --git a/libs/ai/hub/registry.json b/libs/ai/hub/registry.json index 3b92a32b7..cfe5cccd7 100644 --- a/libs/ai/hub/registry.json +++ b/libs/ai/hub/registry.json @@ -623,6 +623,32 @@ } ] }, + { + "id": "whisper-large-v3-turbo", + "domain": "stt", + "backend": "whisper", + "available": true, + "gated": false, + "license": { + "name": "MIT License", + "url": "https://huggingface.co/ggerganov/whisper.cpp", + "summary": "OpenAI Whisper large-v3-turbo weights in ggml format as distributed by ggerganov/whisper.cpp (MIT). Permissive use, including commercial.", + "restriction": "none" + }, + "vram_gb": 2.0, + "note": "Whisper large-v3-turbo speech-to-text via the in-repo pure-Rust port (makepad-ai-speech whisper module; Metal/CUDA/CPU). Request: input_b64 audio/wav (any rate/channels, downmixed + resampled to 16 kHz) + language. Output: one application/json TranscriptJson {text, segments[{start_ms,end_ms,text}]}. The wire side of the stt.whisper pipe; apps reach it through AiHub::start_stt.", + "files": [ + { + "repo": "ggerganov/whisper.cpp", + "path": "ggml-large-v3-turbo.bin", + "revision": "5359861c739e955e79d9a303bcbc70fb988958b1", + "cache_as": "stt/ggml-large-v3-turbo.bin", + "size": 1624555275, + "sha256": "1fc70f774d38eb169993ac391eea357ef47c88757ef72ee5943879b7e8e2bc69", + "local": false + } + ] + }, { "id": "kokoro", "domain": "speech", diff --git a/libs/ai/hub/src/backend.rs b/libs/ai/hub/src/backend.rs index bc05842ba..49d1b9fd9 100644 --- a/libs/ai/hub/src/backend.rs +++ b/libs/ai/hub/src/backend.rs @@ -93,6 +93,8 @@ pub struct GenerateParams { pub text: String, pub voice: String, pub speed: f32, + /// Speech language hint (`language` on the wire); "" = model default. + pub language: String, /// 8-slot emotion vector (indextts), validated to length 8 and clamped /// per-slot to [0, 1.2]; `None` = neutral. pub emotion: Option<[f32; 8]>, @@ -343,6 +345,7 @@ impl GenerateParams { text: request.text.clone().unwrap_or_default(), voice: request.voice.clone().unwrap_or_default(), + language: request.language.clone().unwrap_or_default(), speed: if speed.is_finite() && speed > 0.0 { speed.clamp(0.25, 4.0) as f32 } else { @@ -1567,6 +1570,7 @@ pub fn backend_compiled(name: &str) -> bool { "vision" => cfg!(feature = "llm"), "ocr" => cfg!(feature = "llm"), "kokoro" => cfg!(feature = "tts"), + "whisper" => cfg!(feature = "stt"), "indextts" => cfg!(feature = "indextts"), // The `fast` (FastH3) lane rides the H3 pipeline: same feature. "h3" | "fast" => cfg!(feature = "video"), @@ -1830,6 +1834,15 @@ pub fn create_backend(spec: &ModelSpec) -> Result, Asset "model {} needs a build with the 'llm' cargo feature", spec.id ))), + #[cfg(feature = "stt")] + "whisper" => Ok(Box::new(crate::whisper_backend::WhisperBackend::new_whisper( + &spec.id, + ))), + #[cfg(not(feature = "stt"))] + "whisper" => Err(AssetAiError::Unavailable(format!( + "model {} needs a build with the 'stt' cargo feature", + spec.id + ))), #[cfg(feature = "tts")] "kokoro" => Ok(Box::new(crate::kokoro_backend::KokoroBackend::new_kokoro( &spec.id, diff --git a/libs/ai/hub/src/bin/speech_roundtrip.rs b/libs/ai/hub/src/bin/speech_roundtrip.rs new file mode 100644 index 000000000..3b8786f2f --- /dev/null +++ b/libs/ai/hub/src/bin/speech_roundtrip.rs @@ -0,0 +1,248 @@ +//! Speak sentences through the hub's TTS session, hear them back through its +//! STT session, and score the word error rate. +//! +//! "It made noise" is not a test. This closes the loop through the SAME +//! sessions apps use — whichever engines the hub picks (Kokoro or the OS +//! voice; Whisper here, on the machine node, on a LAN box, or the OS +//! recognizer) — so it is also the scoreboard for comparing them: +//! +//! ```text +//! cd libs/ai/hub && cargo run --release --bin speech-roundtrip +//! cd libs/ai/hub && cargo run --release --bin speech-roundtrip -- --tts system --stt system --reach local +//! cd libs/ai/hub && cargo run --release --bin speech-roundtrip -- score clip.wav "what it should say" +//! ``` +//! +//! `score` transcribes a WAV from anywhere (a reference export, a file on +//! disk) through the same STT session and scores it against the words it +//! should contain. + +use makepad_ai_hub::hub::AiHub; +use makepad_ai_hub::speech::{ + SpeechReach, SttConfig, SttEngine, SttEvent, TtsConfig, TtsEngine, TtsEvent, STT_SAMPLE_RATE, +}; +use std::time::{Duration, Instant}; + +const SENTENCES: &[&str] = &[ + "Hi! I make games with you.", + "I made the player jump higher.", + "Escape the Gummer, a squishy purple blob.", + "You scored forty two points.", + "The little guy can run and jump on the platforms.", + "I gave the ghost bigger eyes and made it chase you faster.", +]; + +fn arg(args: &[String], flag: &str) -> Option { + args.iter().position(|a| a == flag).and_then(|i| args.get(i + 1).cloned()) +} + +fn main() { + // Apple's synthesizer hands its audio back through the process's main run + // loop: run the tool on a thread and keep main pumping. Everything ends + // through `std::process::exit`, which is how the pump stops. + #[cfg(target_os = "macos")] + { + std::thread::spawn(|| { + run(); + std::process::exit(0); + }); + unsafe { CFRunLoopRun() }; + } + #[cfg(not(target_os = "macos"))] + run(); +} + +#[cfg(target_os = "macos")] +#[link(name = "CoreFoundation", kind = "framework")] +extern "C" { + fn CFRunLoopRun(); +} + +fn run() { + let args: Vec = std::env::args().skip(1).collect(); + let reach = match arg(&args, "--reach").as_deref() { + Some("local") => SpeechReach::Local, + Some("machine") => SpeechReach::Machine, + _ => SpeechReach::Lan, + }; + let tts_engine = match arg(&args, "--tts").as_deref() { + Some("system") => TtsEngine::System, + Some("kokoro") => TtsEngine::Kokoro, + _ => TtsEngine::Auto, + }; + let stt_engine = match arg(&args, "--stt").as_deref() { + Some("system") => SttEngine::System, + Some("whisper") => SttEngine::Whisper, + _ => SttEngine::Auto, + }; + + let hub = AiHub::in_process(); + if args.first().map(String::as_str) == Some("score") { + return score(&hub, &args[1..], stt_engine, reach); + } + let tts = hub.start_tts(TtsConfig { engine: tts_engine, reach, voice: arg(&args, "--voice"), ..TtsConfig::default() }); + let stt = hub.start_stt(SttConfig { engine: stt_engine, reach, ..SttConfig::default() }); + + // Wait for both engines; print what the hub chose. + let deadline = Instant::now() + Duration::from_secs(180); + let (mut tts_ready, mut stt_ready) = (false, false); + while !(tts_ready && stt_ready) { + for event in tts.poll() { + match event { + TtsEvent::Loading { phase, fraction } => eprintln!("tts loading: {phase} {:.0}%", fraction * 100.0), + TtsEvent::Ready(info) => { + println!("tts : {} via {}{} ({} voices)", info.engine, info.pipe, remote(&info.remote), info.voices.len()); + tts_ready = true; + } + TtsEvent::Failed(why) => { + eprintln!("tts failed: {why}"); + std::process::exit(1); + } + other => eprintln!("tts: unexpected {other:?}"), + } + } + for event in stt.poll() { + match event { + SttEvent::Loading { phase, fraction } => eprintln!("stt loading: {phase} {:.0}%", fraction * 100.0), + SttEvent::Ready(info) => { + println!("stt : {} via {}{} caps={:?}", info.engine, info.pipe, remote(&info.remote), info.capabilities); + if !info.capabilities.pcm_input { + eprintln!("this recognizer only listens on the microphone; the roundtrip needs PCM input"); + std::process::exit(1); + } + stt_ready = true; + } + SttEvent::Failed(why) => { + eprintln!("stt failed: {why}"); + std::process::exit(1); + } + other => eprintln!("stt: unexpected {other:?}"), + } + } + if Instant::now() > deadline { + eprintln!("engines did not come up in time"); + std::process::exit(1); + } + std::thread::sleep(Duration::from_millis(20)); + } + println!(); + + let (mut total_words, mut total_errors) = (0usize, 0usize); + let started = Instant::now(); + for sentence in SENTENCES { + let id = tts.say(*sentence); + let audio = loop { + let mut got = None; + for event in tts.poll() { + match event { + TtsEvent::Audio { utterance, audio, .. } if utterance == id => got = Some(audio), + TtsEvent::Error { message, .. } => { + eprintln!("tts error: {message}"); + std::process::exit(1); + } + _ => {} + } + } + if let Some(audio) = got { + break audio; + } + std::thread::sleep(Duration::from_millis(10)); + }; + let pcm = audio.resampled(STT_SAMPLE_RATE); + let synth_secs = audio.duration_secs(); + let id = stt.transcribe(pcm.samples); + let heard = loop { + let mut got = None; + for event in stt.poll() { + match event { + SttEvent::Final { utterance, transcript, .. } if utterance == id => got = Some(transcript.text()), + SttEvent::Error { message, .. } => { + eprintln!("stt error: {message}"); + std::process::exit(1); + } + _ => {} + } + } + if let Some(text) = got { + break text; + } + std::thread::sleep(Duration::from_millis(10)); + }; + let expected = words(sentence); + let got = words(&heard); + let errors = edit_distance(&expected, &got); + total_words += expected.len(); + total_errors += errors; + println!("said : {sentence}"); + println!("heard : {heard}"); + println!(" {synth_secs:.1}s audio, {errors} word error(s)\n"); + } + println!( + "word error rate: {:.1}% ({total_errors}/{total_words}) in {:.1}s", + 100.0 * total_errors as f64 / total_words.max(1) as f64, + started.elapsed().as_secs_f64() + ); +} + +fn remote(node: &Option) -> String { + node.as_ref().map(|n| format!(" on {n}")).unwrap_or_default() +} + +fn words(text: &str) -> Vec { + text.split_whitespace() + .map(|w| w.chars().filter(|c| c.is_alphanumeric()).collect::().to_lowercase()) + .filter(|w| !w.is_empty()) + .collect() +} + +fn edit_distance(a: &[String], b: &[String]) -> usize { + let mut prev: Vec = (0..=b.len()).collect(); + for (i, wa) in a.iter().enumerate() { + let mut cur = vec![i + 1]; + for (j, wb) in b.iter().enumerate() { + let cost = if wa == wb { 0 } else { 1 }; + cur.push((prev[j] + cost).min(prev[j + 1] + 1).min(cur[j] + 1)); + } + prev = cur; + } + prev[b.len()] +} + +/// `score [expected words...]`: transcribe one file through the hub's +/// STT session and report the word error rate against the expected text. +fn score(hub: &AiHub, args: &[String], engine: SttEngine, reach: SpeechReach) { + let Some(path) = args.first() else { + eprintln!("usage: speech-roundtrip score [expected text]"); + std::process::exit(2); + }; + let expected = args[1..].join(" "); + let bytes = std::fs::read(path).expect("read wav"); + let (samples, rate) = makepad_ai_hub::wav::decode_wav_to_mono_f32(&bytes).expect("decode wav"); + let audio = makepad_ai_hub::speech::SpeechAudio { samples, sample_rate: rate }; + println!("wav : {path} ({:.2}s @ {rate} Hz)", audio.duration_secs()); + let stt = hub.start_stt(SttConfig { engine, reach, ..SttConfig::default() }); + let id = stt.transcribe(audio.resampled(STT_SAMPLE_RATE).samples); + let deadline = Instant::now() + Duration::from_secs(300); + let heard = loop { + match stt.recv_timeout(Duration::from_millis(50)) { + Some(SttEvent::Ready(info)) => println!("stt : {} via {}{}", info.engine, info.pipe, remote(&info.remote)), + Some(SttEvent::Loading { phase, fraction }) => eprintln!("stt loading: {phase} {:.0}%", fraction * 100.0), + Some(SttEvent::Final { utterance, transcript, .. }) if utterance == id => break transcript.text(), + Some(SttEvent::Failed(why)) | Some(SttEvent::Error { message: why, .. }) => { + eprintln!("stt failed: {why}"); + std::process::exit(1); + } + _ => {} + } + if Instant::now() > deadline { + eprintln!("no transcript in time"); + std::process::exit(1); + } + }; + println!("heard : {heard}"); + if !expected.is_empty() { + let (e, g) = (words(&expected), words(&heard)); + let errors = edit_distance(&e, &g); + println!("expected : {expected}"); + println!("WER : {:.1}% ({errors}/{} words)", 100.0 * errors as f64 / e.len().max(1) as f64, e.len()); + } +} diff --git a/libs/ai/hub/src/control_backend.rs b/libs/ai/hub/src/control_backend.rs index 405ad4dd2..6fbe37955 100644 --- a/libs/ai/hub/src/control_backend.rs +++ b/libs/ai/hub/src/control_backend.rs @@ -691,6 +691,7 @@ mod tests { variants: 1, text: String::new(), voice: String::new(), + language: String::new(), speed: 1.0, emotion: None, seconds: None, diff --git a/libs/ai/hub/src/hub.rs b/libs/ai/hub/src/hub.rs index 4aa3e5b78..3e9947620 100644 --- a/libs/ai/hub/src/hub.rs +++ b/libs/ai/hub/src/hub.rs @@ -60,6 +60,21 @@ impl AiHub { }) } + /// Start speech-to-text. The worker picks the engine — Whisper here, on + /// the machine node, or on a LAN node, else the OS recognizer — and + /// reports it in `Ready`; the app feeds PCM or asks the engine to listen. + #[cfg(feature = "speech")] + pub fn start_stt(&self, config: crate::speech::SttConfig) -> crate::speech::SttSession { + crate::speech::SttSession::start(config) + } + + /// Start text-to-speech: Kokoro wherever it is, else the OS voice. Text + /// in, PCM out; the app owns playback. + #[cfg(feature = "speech")] + pub fn start_tts(&self, config: crate::speech::TtsConfig) -> crate::speech::TtsSession { + crate::speech::TtsSession::start(config) + } + /// The pipe id the in-process local model publishes (machine-local only). pub fn local_llm_pipe() -> PipeId { PipeId::new("llm.local") diff --git a/libs/ai/hub/src/inpaint_backend.rs b/libs/ai/hub/src/inpaint_backend.rs index 1ca9fdba4..2118b4c58 100644 --- a/libs/ai/hub/src/inpaint_backend.rs +++ b/libs/ai/hub/src/inpaint_backend.rs @@ -775,6 +775,7 @@ mod tests { variants: 1, text: String::new(), voice: String::new(), + language: String::new(), speed: 1.0, emotion: None, seconds: None, diff --git a/libs/ai/hub/src/jobs.rs b/libs/ai/hub/src/jobs.rs index 0a2365cea..fa92a3f3e 100644 --- a/libs/ai/hub/src/jobs.rs +++ b/libs/ai/hub/src/jobs.rs @@ -812,6 +812,7 @@ pub(crate) mod tests { variants: 1, text: String::new(), voice: String::new(), + language: String::new(), speed: 1.0, emotion: None, seconds: None, diff --git a/libs/ai/hub/src/lib.rs b/libs/ai/hub/src/lib.rs index a1a59dcaf..c80f84adf 100644 --- a/libs/ai/hub/src/lib.rs +++ b/libs/ai/hub/src/lib.rs @@ -58,6 +58,10 @@ pub mod lane_advert; pub mod lease; pub mod indextts_backend; pub mod kokoro_backend; +#[cfg(feature = "stt")] +pub mod whisper_backend; +#[cfg(feature = "speech")] +pub mod speech; pub mod llm_backend; #[cfg(feature = "llm")] pub mod local_llm; diff --git a/libs/ai/hub/src/protocol.rs b/libs/ai/hub/src/protocol.rs index 363a23b56..0c50ebdd5 100644 --- a/libs/ai/hub/src/protocol.rs +++ b/libs/ai/hub/src/protocol.rs @@ -513,6 +513,10 @@ pub struct GenerateRequestJson { pub voice: Option, /// Speaking-rate multiplier, 0.25..=4.0. Default 1.0. pub speed: Option, + /// Language for speech models: ISO 639-1 (`"en"`) or a BCP-47 tag. + /// STT (`whisper`): the spoken language; TTS: the voice language when + /// `voice` is unset. Absent = the model default (English). + pub language: Option, /// Emotion vector for emotion-controllable TTS (indextts): exactly 8 /// floats in [0,1.2], order [happy, angry, sad, afraid, disgusted, /// melancholic, surprised, calm]. Omitted = neutral (the reference @@ -1261,3 +1265,24 @@ pub struct ByeRequestJson { pub struct ByeResponseJson { pub cancelled: u64, } + +// --------------------------------------------------------------------------- +// Speech-to-text (stt domain) artifact +// --------------------------------------------------------------------------- + +/// One timed span of a transcript. +#[derive(Clone, Debug, PartialEq, SerJson, DeJson)] +pub struct TranscriptSegmentJson { + pub start_ms: i64, + pub end_ms: i64, + pub text: String, +} + +/// The `application/json` artifact an `stt` job produces: the segments with +/// millisecond timing plus the joined text, so a client that only wants the +/// words never has to walk the segments. +#[derive(Clone, Debug, Default, PartialEq, SerJson, DeJson)] +pub struct TranscriptJson { + pub text: String, + pub segments: Vec, +} diff --git a/libs/ai/hub/src/registry.rs b/libs/ai/hub/src/registry.rs index e8a723429..4896cb035 100644 --- a/libs/ai/hub/src/registry.rs +++ b/libs/ai/hub/src/registry.rs @@ -195,6 +195,9 @@ pub enum Domain { Vision, /// Scanned page -> HTML transcription (Chandra 2 on the vision tower). Ocr, + /// Speech audio -> timed transcript (Whisper). The `stt.whisper` pipe; + /// `Speech` stays text-to-speech, so the two never share affinity. + Stt, } impl Domain { @@ -223,6 +226,7 @@ impl Domain { "splat" => Some(Domain::Splat), "vision" => Some(Domain::Vision), "ocr" => Some(Domain::Ocr), + "stt" => Some(Domain::Stt), _ => None, } } @@ -252,6 +256,7 @@ impl Domain { Domain::Splat => "splat", Domain::Vision => "vision", Domain::Ocr => "ocr", + Domain::Stt => "stt", } } } diff --git a/libs/ai/hub/src/speech/mod.rs b/libs/ai/hub/src/speech/mod.rs new file mode 100644 index 000000000..3e6d536ea --- /dev/null +++ b/libs/ai/hub/src/speech/mod.rs @@ -0,0 +1,508 @@ +//! Speech in the hub: speech-to-text and text-to-speech as sessions, the same +//! shape as [`crate::hub_chat::HubChatSession`] — poll-driven, headless, one +//! worker thread, events out, a wake hook for sleeping UIs. +//! +//! An app asks for a session and gets *a* recognizer or *a* voice; which one +//! is the hub's decision, made once at start and reported in `Ready`: +//! +//! ```text +//! stt.whisper in-process (weights here, machine election) ─┐ +//! stt.whisper machine node over loopback ├─ Auto ladder, +//! stt.whisper LAN node (a Mac serving a Quest) │ best first +//! stt.system the OS recognizer (makepad-system-speech) ─┘ +//! ``` +//! +//! and the mirror image for `tts.kokoro` / `tts.system`. [`SpeechReach`] is +//! the "don't reach out" knob: `Local` never touches a socket, `Machine` uses +//! loopback only, `Lan` uses everything. The API is identical either way. +//! +//! **Two STT input shapes.** Whisper and the Apple recognizer take PCM the +//! app recorded ([`SttSession::transcribe`], fed by the app's own VAD +//! pipeline). Android and Windows recognizers only listen to the microphone +//! themselves ([`SttSession::listen`]). `Ready` carries the capabilities so +//! the app picks the shape its engine supports instead of guessing. +//! +//! Audio always comes back as PCM: the app owns the device. + +mod remote; +mod stt_worker; +mod tts_worker; +pub mod weights; + +pub use makepad_system_speech::{Segment, SpeechAudio, SttCapabilities, Transcript, Voice, VoiceGender}; + +use crate::pipe::PipeId; +use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::mpsc::{channel, Receiver, Sender}; +use std::sync::Arc; +use std::thread; + +/// Called after every event so a sleeping consumer wakes up (UI apps pass +/// their platform signal). The same type as the chat session's hook. +pub type WakeHook = Arc; + +/// The rate [`SttSession::transcribe`] expects: mono f32 at 16 kHz. +pub const STT_SAMPLE_RATE: u32 = 16_000; + +/// How far a session may look for an engine. Ordered: each level includes +/// the ones below it. +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum SpeechReach { + /// This process only: in-process engines and the OS engine. No sockets. + Local, + /// Plus the other nodes on this machine, over loopback. + Machine, + /// Plus dedicated nodes on the LAN. + Lan, +} + +impl Default for SpeechReach { + fn default() -> Self { + SpeechReach::Lan + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] +pub enum SttEngine { + /// Whisper wherever it is (in-process, machine, LAN), else the OS engine. + #[default] + Auto, + /// The OS recognizer only. + System, + /// Whisper only; fails when none is in reach. + Whisper, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] +pub enum TtsEngine { + /// Kokoro wherever it is, else the OS voice. + #[default] + Auto, + /// The OS synthesizer only. + System, + /// Kokoro only; fails when none is in reach. + Kokoro, +} + +#[derive(Clone)] +pub struct SttConfig { + pub engine: SttEngine, + pub reach: SpeechReach, + /// ISO 639-1 (`"en"`) or BCP-47; engines take what they need from it. + pub language: String, + /// `listen` mode: emit partial hypotheses when the engine can. + pub partial_results: bool, + /// Prefer on-device recognition when the OS engine offers the choice. + pub prefer_offline: bool, + /// Ask for per-segment timing. + pub timestamps: bool, + /// Whisper: decode the whole buffer as one segment (live dictation). + pub single_segment: bool, + /// Whisper: cap tokens per utterance; 0 = the model's default. + pub max_tokens: usize, + /// Whisper: no-speech probability above which a chunk is treated as + /// silence. `None` = the engine default. + pub silence_threshold: Option, + pub wake: Option, +} + +impl Default for SttConfig { + fn default() -> Self { + Self { + engine: SttEngine::Auto, + reach: SpeechReach::Lan, + language: "en".to_string(), + partial_results: true, + prefer_offline: true, + timestamps: true, + single_segment: false, + max_tokens: 0, + silence_threshold: None, + wake: None, + } + } +} + +impl SttConfig { + /// The settings the Window voice input has always used for short, + /// VAD-gated utterances: one segment, few tokens, a stricter silence gate. + pub fn live_dictation() -> Self { + Self { + timestamps: false, + single_segment: true, + max_tokens: 48, + silence_threshold: Some(0.65), + ..Self::default() + } + } +} + +#[derive(Clone)] +pub struct TtsConfig { + pub engine: TtsEngine, + pub reach: SpeechReach, + /// A [`Voice::id`] from `Ready`'s voice list; `None` = the engine's + /// default for `language` (Kokoro: `MAKEPAD_TTS_VOICE` or `bm_daniel`). + pub voice: Option, + pub language: String, + /// 1.0 = normal speaking rate. + pub rate: f32, + /// 1.0 = normal pitch; engines without pitch control ignore it. + pub pitch: f32, + pub wake: Option, +} + +impl Default for TtsConfig { + fn default() -> Self { + Self { + engine: TtsEngine::Auto, + reach: SpeechReach::Lan, + voice: None, + language: "en".to_string(), + rate: 1.0, + pitch: 1.0, + wake: None, + } + } +} + +/// Which recognizer a session ended up with. +#[derive(Clone, Debug, PartialEq)] +pub struct SttEngineInfo { + /// `stt.whisper` or `stt.system`. + pub pipe: PipeId, + /// A human-readable engine name: `"whisper (ggml-large-v3-turbo.bin)"`, + /// `"apple-speechanalyzer"`, … + pub engine: String, + /// The node serving it when it is not this process. + pub remote: Option, + pub capabilities: SttCapabilities, +} + +/// Which voice a session ended up with. +#[derive(Clone, Debug, PartialEq)] +pub struct TtsEngineInfo { + /// `tts.kokoro` or `tts.system`. + pub pipe: PipeId, + pub engine: String, + pub remote: Option, + /// Sample rate the engine renders at. + pub sample_rate: u32, + /// The voices this engine offers; ids go into [`TtsConfig::voice`]. + pub voices: Vec, +} + +#[derive(Clone, Debug, PartialEq)] +pub enum SttEvent { + /// Engine selection / weight load progress. + Loading { phase: String, fraction: f64 }, + /// The engine is chosen and ready. Exactly once, before any result. + Ready(SttEngineInfo), + /// No engine could be had. Nothing else will ever arrive. + Failed(String), + /// `listen` mode: input level 0..1, when the engine reports one. + Level(f32), + /// `listen` mode: running hypothesis, replacing the previous one. + Partial(String), + /// A finished utterance: the id [`SttSession::transcribe`] returned, or + /// 0 for utterances the engine's own microphone session produced. + Final { utterance: u64, transcript: Transcript, secs: f64 }, + /// One utterance failed; the session goes on. + Error { utterance: Option, message: String }, + /// The engine's microphone session ended (stopped, or the engine decided + /// the utterance was over). `listen` again to start another. + ListenEnded, +} + +#[derive(Clone, Debug, PartialEq)] +pub enum TtsEvent { + Loading { phase: String, fraction: f64 }, + Ready(TtsEngineInfo), + Failed(String), + /// The rendered speech for one `say`. Mono PCM at the engine's rate. + Audio { utterance: u64, audio: SpeechAudio, secs: f64 }, + Error { utterance: u64, message: String }, +} + +pub(crate) enum SttMsg { + Transcribe { utterance: u64, generation: u64, samples: Vec }, + Listen, + StopListening, +} + +pub(crate) enum TtsMsg { + Say { utterance: u64, generation: u64, text: String }, +} + +/// A running speech-to-text session. Dropping it ends the worker. +/// +/// One thread polls it; a consumer that wants to submit from one thread and +/// drain events on another takes it apart with [`SttSession::split`]. +pub struct SttSession { + handle: SttHandle, + events: SttEvents, +} + +/// The submitting half of a session: `Send + Sync`, clone-free by design (one +/// owner decides what the recognizer hears). +pub struct SttHandle { + to_worker: Sender, + next_utterance: AtomicU64, + generation: Arc, +} + +/// The receiving half: the worker's events, in order. +pub struct SttEvents { + from_worker: Receiver, +} + +impl SttSession { + /// Pick an engine and get it ready, on a worker. Nothing blocks; progress + /// and the outcome arrive through [`SttSession::poll`]. + pub fn start(config: SttConfig) -> Self { + let (event_tx, from_worker) = channel(); + let (to_worker, msg_rx) = channel(); + let generation = Arc::new(AtomicU64::new(0)); + let worker_generation = generation.clone(); + thread::Builder::new() + .name("ai-hub-stt".into()) + .spawn(move || stt_worker::run(config, msg_rx, event_tx, worker_generation)) + .expect("spawn stt worker"); + Self { + handle: SttHandle { to_worker, next_utterance: AtomicU64::new(1), generation }, + events: SttEvents { from_worker }, + } + } + + /// Take the session apart: submit from one thread, drain on another. + pub fn split(self) -> (SttHandle, SttEvents) { + (self.handle, self.events) + } + + /// See [`SttHandle::transcribe`]. + pub fn transcribe(&self, samples_16k: Vec) -> u64 { + self.handle.transcribe(samples_16k) + } + + /// See [`SttHandle::listen`]. + pub fn listen(&self) { + self.handle.listen() + } + + pub fn stop_listening(&self) { + self.handle.stop_listening() + } + + /// See [`SttHandle::cancel`]. + pub fn cancel(&self) { + self.handle.cancel() + } + + pub fn poll(&self) -> Vec { + self.events.poll() + } + + pub fn recv(&self) -> Option { + self.events.recv() + } + + pub fn recv_timeout(&self, timeout: std::time::Duration) -> Option { + self.events.recv_timeout(timeout) + } +} + +impl SttHandle { + /// Queue caller-recorded PCM (mono f32 at [`STT_SAMPLE_RATE`]) for + /// recognition. Returns the utterance id its `Final`/`Error` will carry. + pub fn transcribe(&self, samples_16k: Vec) -> u64 { + let utterance = self.next_utterance.fetch_add(1, Ordering::Relaxed); + let _ = self.to_worker.send(SttMsg::Transcribe { + utterance, + generation: self.generation.load(Ordering::Relaxed), + samples: samples_16k, + }); + utterance + } + + /// Let the engine listen on the microphone itself (engines whose + /// capabilities say `engine_mic`). Results arrive as `Partial`/`Final` + /// with utterance id 0, then `ListenEnded`. + pub fn listen(&self) { + let _ = self.to_worker.send(SttMsg::Listen); + } + + pub fn stop_listening(&self) { + let _ = self.to_worker.send(SttMsg::StopListening); + } + + /// Drop every queued utterance; one already being recognized is + /// discarded when it finishes instead of being reported. + pub fn cancel(&self) { + self.generation.fetch_add(1, Ordering::Relaxed); + } +} + +impl SttEvents { + pub fn poll(&self) -> Vec { + self.from_worker.try_iter().collect() + } + + /// Block until the next event, or `None` once the worker is gone. For + /// headless consumers with a thread to spare; UIs use `poll` + `wake`. + pub fn recv(&self) -> Option { + self.from_worker.recv().ok() + } + + pub fn recv_timeout(&self, timeout: std::time::Duration) -> Option { + self.from_worker.recv_timeout(timeout).ok() + } +} + +/// A running text-to-speech session. Dropping it ends the worker. Take it +/// apart with [`TtsSession::split`] to speak from one thread and play from +/// another. +pub struct TtsSession { + handle: TtsHandle, + events: TtsEvents, +} + +/// The speaking half of a session (`Send + Sync`). +pub struct TtsHandle { + to_worker: Sender, + next_utterance: AtomicU64, + generation: Arc, +} + +/// The receiving half: rendered audio and everything else, in order. +pub struct TtsEvents { + from_worker: Receiver, +} + +impl TtsSession { + pub fn start(config: TtsConfig) -> Self { + let (event_tx, from_worker) = channel(); + let (to_worker, msg_rx) = channel(); + let generation = Arc::new(AtomicU64::new(0)); + let worker_generation = generation.clone(); + thread::Builder::new() + .name("ai-hub-tts".into()) + .spawn(move || tts_worker::run(config, msg_rx, event_tx, worker_generation)) + .expect("spawn tts worker"); + Self { + handle: TtsHandle { to_worker, next_utterance: AtomicU64::new(1), generation }, + events: TtsEvents { from_worker }, + } + } + + /// Take the session apart: speak from one thread, play from another. + pub fn split(self) -> (TtsHandle, TtsEvents) { + (self.handle, self.events) + } + + /// See [`TtsHandle::say`]. + pub fn say(&self, text: impl Into) -> u64 { + self.handle.say(text) + } + + /// See [`TtsHandle::cancel`]. + pub fn cancel(&self) { + self.handle.cancel() + } + + pub fn poll(&self) -> Vec { + self.events.poll() + } + + pub fn recv(&self) -> Option { + self.events.recv() + } + + pub fn recv_timeout(&self, timeout: std::time::Duration) -> Option { + self.events.recv_timeout(timeout) + } +} + +impl TtsHandle { + /// Queue text to render. Returns the utterance id its `Audio`/`Error` + /// will carry. Utterances render in order. + pub fn say(&self, text: impl Into) -> u64 { + let utterance = self.next_utterance.fetch_add(1, Ordering::Relaxed); + let _ = self.to_worker.send(TtsMsg::Say { + utterance, + generation: self.generation.load(Ordering::Relaxed), + text: text.into(), + }); + utterance + } + + /// Drop every queued utterance; one being rendered is discarded when it + /// finishes. Playback of audio already delivered is the app's to stop. + pub fn cancel(&self) { + self.generation.fetch_add(1, Ordering::Relaxed); + } +} + +impl TtsEvents { + pub fn poll(&self) -> Vec { + self.from_worker.try_iter().collect() + } + + /// Block until the next event, or `None` once the worker is gone. + pub fn recv(&self) -> Option { + self.from_worker.recv().ok() + } + + pub fn recv_timeout(&self, timeout: std::time::Duration) -> Option { + self.from_worker.recv_timeout(timeout).ok() + } +} + +/// True when this build and platform may load a heavy speech model into this +/// process for `Auto`. Phones and headsets keep 1.6 GB Whisper / 327 MB +/// Kokoro off-device (their OS engine or a LAN node serve them) unless the +/// `MAKEPAD` config asks for it by name (`MAKEPAD=whisper`, `MAKEPAD=kokoro`). +#[cfg(any(feature = "stt", feature = "tts"))] +pub(crate) fn in_process_allowed(engine: &str) -> bool { + if !cfg!(any(target_os = "ios", target_os = "android")) { + return true; + } + std::env::var("MAKEPAD").is_ok_and(|configs| { + configs.split(['+', ',']).any(|config| config.eq_ignore_ascii_case(engine)) + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn reach_is_ordered_inclusively() { + assert!(SpeechReach::Local < SpeechReach::Machine); + assert!(SpeechReach::Machine < SpeechReach::Lan); + assert_eq!(SpeechReach::default(), SpeechReach::Lan); + } + + #[test] + fn live_dictation_keeps_the_window_voice_defaults() { + let cfg = SttConfig::live_dictation(); + assert!(cfg.single_segment); + assert_eq!(cfg.max_tokens, 48); + assert_eq!(cfg.silence_threshold, Some(0.65)); + assert!(!cfg.timestamps); + } + + #[test] + fn utterance_ids_count_from_one_and_cancel_bumps_generation() { + // A session whose worker fails fast (no engines in a Local reach on + // a machine without weights) still hands out ids and generations. + let session = TtsSession::start(TtsConfig { + engine: TtsEngine::Kokoro, + reach: SpeechReach::Local, + ..TtsConfig::default() + }); + assert_eq!(session.say("a"), 1); + assert_eq!(session.say("b"), 2); + session.cancel(); + assert_eq!(session.handle.generation.load(Ordering::Relaxed), 1); + } +} diff --git a/libs/ai/hub/src/speech/remote.rs b/libs/ai/hub/src/speech/remote.rs new file mode 100644 index 000000000..c22c109ca --- /dev/null +++ b/libs/ai/hub/src/speech/remote.rs @@ -0,0 +1,189 @@ +//! A speech pipe on another node: the co-located machine node over loopback, +//! or a LAN node found through the beacon listener. Utterance-shaped in v1 +//! (one `/generate` job per utterance, polled fast); a streaming session +//! with word partials is the realtime-websocket shape and comes later. + +use super::SpeechReach; +use crate::client::{ContentProvider, LocalService}; +use crate::protocol::{ + GenerateRequestJson, TranscriptJson, JOB_STATE_CANCELLED, JOB_STATE_DONE, JOB_STATE_ERROR, + MODEL_STATE_DOWNLOADING, MODEL_STATE_LOADED, MODEL_STATE_READY, +}; +use crate::registry::Domain; +use crate::wav; +use makepad_micro_serde::DeJson; +use makepad_system_speech::{Segment, SpeechAudio, Transcript}; +use std::sync::OnceLock; +use std::time::{Duration, Instant}; + +/// Poll cadence for speech jobs: an utterance transcribes in well under a +/// second on a warm node, so the poll interval IS the latency floor. +const POLL: Duration = Duration::from_millis(40); +/// A job that has not finished in this long is lost (a node that fell over +/// mid-job keeps answering `running` until its lease janitor runs). +const JOB_TIMEOUT: Duration = Duration::from_secs(180); +/// First LAN lookup: beacons come every 2 s, so a fresh listener may need a +/// moment before it has heard anyone. +const FIRST_BEACON_WAIT: Duration = Duration::from_millis(2500); + +pub(crate) struct RemotePipe { + pub base_url: String, + pub model: String, + service: LocalService, +} + +impl RemotePipe { + /// The best node in reach serving `domain` with one of `backends`: + /// loopback nodes first (the machine node is the RAM holder), then the + /// LAN; a loaded model beats a ready one beats one still arriving. + pub(crate) fn find(reach: SpeechReach, domain: Domain, backends: &[&str]) -> Option { + let mut best: Option<(u8, RemotePipe)> = None; + for url in candidate_urls(reach) { + let Some((rank, pipe)) = Self::at(&url, domain, backends) else { continue }; + // Loopback wins ties: same rank, no network. + if best.as_ref().map_or(true, |(r, _)| rank > *r) { + best = Some((rank, pipe)); + } + } + best.map(|(_, pipe)| pipe) + } + + /// The pipe at one node, with its readiness rank, when it serves one. + pub(crate) fn at(base_url: &str, domain: Domain, backends: &[&str]) -> Option<(u8, RemotePipe)> { + let service = LocalService::new(base_url); + let models = service.list_models().ok()?; + let mut best: Option<(u8, String)> = None; + for model in models { + if !model.available || model.domain != domain.as_str() { + continue; + } + if !backends.iter().any(|b| *b == model.backend) { + continue; + } + let rank = match model.state.as_str() { + MODEL_STATE_LOADED => 3, + MODEL_STATE_READY => 2, + MODEL_STATE_DOWNLOADING => 1, + // "absent": the node could acquire it, but a first utterance + // would wait on a 1.6 GB download. Not a serving pipe today. + _ => continue, + }; + if best.as_ref().map_or(true, |(r, _)| rank > *r) { + best = Some((rank, model.id)); + } + } + let (rank, model) = best?; + Some((rank, RemotePipe { base_url: base_url.to_string(), model, service })) + } + + pub(crate) fn transcribe(&self, samples_16k: &[f32], language: &str, timestamps: bool) -> Result { + let wav = wav::encode_wav_pcm16_mono(samples_16k, super::STT_SAMPLE_RATE); + let request = GenerateRequestJson { + model: self.model.clone(), + input_b64: Some(base64(&wav)), + input_content_type: Some("audio/wav".to_string()), + language: Some(language.to_string()), + // The wire has no "timestamps" knob; the backend always times its + // segments and a caller that does not want them ignores them. + ..Default::default() + }; + let _ = timestamps; + let bytes = self.run_job(Domain::Stt, &request)?; + let text = std::str::from_utf8(&bytes).map_err(|_| "transcript is not utf-8".to_string())?; + let json = TranscriptJson::deserialize_json(text).map_err(|e| format!("transcript json: {e:?}"))?; + Ok(Transcript { + segments: json + .segments + .into_iter() + .map(|s| Segment { start_ms: s.start_ms, end_ms: s.end_ms, text: s.text }) + .collect(), + }) + } + + pub(crate) fn synthesize(&self, text: &str, voice: &str, speed: f32) -> Result { + let request = GenerateRequestJson { + model: self.model.clone(), + text: Some(text.to_string()), + voice: (!voice.is_empty()).then(|| voice.to_string()), + speed: Some(speed as f64), + ..Default::default() + }; + let bytes = self.run_job(Domain::Speech, &request)?; + let (samples, sample_rate) = wav::decode_wav_to_mono_f32(&bytes)?; + Ok(SpeechAudio { samples, sample_rate }) + } + + fn run_job(&self, domain: Domain, request: &GenerateRequestJson) -> Result, String> { + let job_id = self + .service + .request(domain, request) + .map_err(|e| format!("{}: {e}", self.base_url))?; + let deadline = Instant::now() + JOB_TIMEOUT; + loop { + let status = self + .service + .poll(&job_id) + .map_err(|e| format!("{}: {e}", self.base_url))?; + match status.state.as_str() { + JOB_STATE_DONE => { + let artifact = status + .artifacts + .first() + .ok_or_else(|| "job finished without an artifact".to_string())?; + return self + .service + .fetch_artifact(&artifact.id) + .map(|a| a.bytes) + .map_err(|e| format!("{}: {e}", self.base_url)); + } + JOB_STATE_ERROR => { + return Err(status.error.unwrap_or_else(|| "job failed".to_string())); + } + JOB_STATE_CANCELLED => return Err("job cancelled".to_string()), + _ => {} + } + if Instant::now() > deadline { + let _ = self.service.cancel(&job_id); + return Err(format!("{}: job {job_id} timed out", self.base_url)); + } + std::thread::sleep(POLL); + } + } +} + +/// Every node this reach allows, loopback first. +fn candidate_urls(reach: SpeechReach) -> Vec { + let mut urls = Vec::new(); + if reach >= SpeechReach::Machine { + for (_, entry) in crate::machine::read_node_entries() { + if entry.port > 0 { + urls.push(format!("http://127.0.0.1:{}", entry.port)); + } + } + } + if reach >= SpeechReach::Lan { + let discovered = crate::discovery::start_listener(); + // Give a brand-new listener one beacon interval to hear the fleet, + // once per process; afterwards the live set is whatever it is. + static WAITED: OnceLock<()> = OnceLock::new(); + if discovered.nodes().is_empty() && WAITED.get().is_none() { + let deadline = Instant::now() + FIRST_BEACON_WAIT; + while discovered.nodes().is_empty() && Instant::now() < deadline { + std::thread::sleep(Duration::from_millis(100)); + } + let _ = WAITED.set(()); + } + for node in discovered.nodes() { + let url = node.base_url.trim_end_matches('/').to_string(); + if !urls.contains(&url) { + urls.push(url); + } + } + } + urls +} + +fn base64(bytes: &[u8]) -> String { + String::from_utf8(makepad_base64::base64_encode(bytes, &makepad_base64::BASE64_STANDARD)) + .unwrap_or_default() +} diff --git a/libs/ai/hub/src/speech/stt_worker.rs b/libs/ai/hub/src/speech/stt_worker.rs new file mode 100644 index 000000000..451388b31 --- /dev/null +++ b/libs/ai/hub/src/speech/stt_worker.rs @@ -0,0 +1,364 @@ +//! The STT session worker: choose an engine once, then serve utterances. + +use super::remote::RemotePipe; +use super::{SpeechReach, SttConfig, SttEngine, SttEngineInfo, SttEvent, SttMsg, Transcript}; +use crate::pipe::PipeId; +use crate::registry::Domain; +use makepad_system_speech as sys; +use makepad_system_speech::{ListenHandle, SttCapabilities}; +use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::mpsc::{channel, Receiver, RecvTimeoutError, Sender}; +use std::sync::Arc; +use std::time::{Duration, Instant}; + +pub(crate) fn run( + config: SttConfig, + msg_rx: Receiver, + event_tx: Sender, + generation: Arc, +) { + let wake = config.wake.clone(); + let send = move |event: SttEvent| { + let _ = event_tx.send(event); + if let Some(wake) = &wake { + wake(); + } + }; + + let mut engine = match choose(&config, &send) { + Ok(engine) => engine, + Err(why) => return send(SttEvent::Failed(why)), + }; + send(SttEvent::Ready(engine.info())); + + let mut listening: Option = None; + loop { + if let Some(live) = listening.as_mut() { + let mut ended = false; + while let Ok(event) = live.events.try_recv() { + match event { + sys::SttEvent::Level(level) => send(SttEvent::Level(level)), + sys::SttEvent::Partial(text) => send(SttEvent::Partial(text)), + sys::SttEvent::Final(transcript) => { + send(SttEvent::Final { utterance: 0, transcript, secs: 0.0 }) + } + sys::SttEvent::Error(error) => { + send(SttEvent::Error { utterance: None, message: error.to_string() }) + } + sys::SttEvent::Ended => ended = true, + } + } + if ended { + listening = None; + send(SttEvent::ListenEnded); + } + } + + match msg_rx.recv_timeout(Duration::from_millis(20)) { + Ok(SttMsg::Transcribe { utterance, generation: mine, samples }) => { + if mine != generation.load(Ordering::Relaxed) { + continue; + } + let started = Instant::now(); + match engine.transcribe(&samples, &config) { + Ok(transcript) => { + // A cancel that landed mid-recognition means this + // result belongs to a turn nobody wants any more. + if mine == generation.load(Ordering::Relaxed) { + send(SttEvent::Final { + utterance, + transcript, + secs: started.elapsed().as_secs_f64(), + }); + } + } + Err(message) => send(SttEvent::Error { utterance: Some(utterance), message }), + } + } + Ok(SttMsg::Listen) => { + if listening.is_some() { + continue; + } + match engine.listen(&config) { + Ok(live) => listening = Some(live), + Err(message) => send(SttEvent::Error { utterance: None, message }), + } + } + Ok(SttMsg::StopListening) => { + // Keep draining events: the engine still delivers its final + // result and `Ended` after being told to stop. + if let Some(live) = listening.as_mut() { + if let Some(handle) = live.handle.take() { + handle.stop(); + } + } + } + Err(RecvTimeoutError::Timeout) => {} + Err(RecvTimeoutError::Disconnected) => break, + } + } +} + +/// An engine-owned microphone session in progress. +struct Listening { + handle: Option, + events: Receiver, +} + +trait Engine { + fn info(&self) -> SttEngineInfo; + fn transcribe(&mut self, samples_16k: &[f32], config: &SttConfig) -> Result; + fn listen(&mut self, config: &SttConfig) -> Result; +} + +// ----------------------------------------------------------------- choosing + +fn choose(config: &SttConfig, send: &dyn Fn(SttEvent)) -> Result, String> { + let want_whisper = matches!(config.engine, SttEngine::Auto | SttEngine::Whisper); + let want_system = matches!(config.engine, SttEngine::Auto | SttEngine::System); + let mut reasons: Vec = Vec::new(); + + if want_whisper { + #[cfg(feature = "stt")] + { + if !super::in_process_allowed("whisper") { + reasons.push("in-process whisper is off on this platform (MAKEPAD=whisper enables it)".into()); + } else if let Some(path) = super::weights::whisper_model_path() { + match whisper::elect_and_load(&path, config, send) { + Ok(engine) => return Ok(engine), + Err(why) => reasons.push(why), + } + } else { + reasons.push(format!("no whisper weights ({}) on this machine", super::weights::WHISPER_MODEL_FILE)); + } + } + #[cfg(not(feature = "stt"))] + reasons.push("whisper is not compiled into this build".into()); + + if config.reach >= SpeechReach::Machine { + send(SttEvent::Loading { phase: "looking for a whisper node".into(), fraction: 0.0 }); + match RemotePipe::find(config.reach, Domain::Stt, &["whisper"]) { + Some(pipe) => return Ok(Box::new(RemoteStt { pipe })), + None => reasons.push(format!("no node in reach ({:?}) serves stt.whisper", config.reach)), + } + } + } + + if want_system { + if sys::stt::available() { + let _ = sys::stt::prepare(&config.language); + return Ok(Box::new(SystemStt)); + } + reasons.push(format!("no system recognizer here ({})", sys::stt::engine_name())); + } + + Err(reasons.join("; ")) +} + +fn stt_options(config: &SttConfig) -> sys::SttOptions { + sys::SttOptions { + language: config.language.clone(), + partial_results: config.partial_results, + prefer_offline: config.prefer_offline, + timestamps: config.timestamps, + } +} + +// ------------------------------------------------------------- the OS engine + +struct SystemStt; + +impl Engine for SystemStt { + fn info(&self) -> SttEngineInfo { + SttEngineInfo { + pipe: PipeId::new("stt.system"), + engine: sys::stt::engine_name().to_string(), + remote: None, + capabilities: sys::stt::capabilities(), + } + } + + fn transcribe(&mut self, samples_16k: &[f32], config: &SttConfig) -> Result { + sys::stt::transcribe(samples_16k, &stt_options(config)).map_err(|e| e.to_string()) + } + + fn listen(&mut self, config: &SttConfig) -> Result { + let (tx, events) = channel(); + let handle = sys::stt::listen(&stt_options(config), tx).map_err(|e| e.to_string())?; + Ok(Listening { handle: Some(handle), events }) + } +} + +// ---------------------------------------------------------------- remote pipe + +struct RemoteStt { + pipe: RemotePipe, +} + +impl Engine for RemoteStt { + fn info(&self) -> SttEngineInfo { + SttEngineInfo { + pipe: PipeId::new("stt.whisper"), + engine: format!("whisper ({})", self.pipe.model), + remote: Some(self.pipe.base_url.clone()), + capabilities: SttCapabilities { pcm_input: true, engine_mic: false, partial_results: false, offline: true }, + } + } + + fn transcribe(&mut self, samples_16k: &[f32], config: &SttConfig) -> Result { + self.pipe.transcribe(samples_16k, &config.language, config.timestamps) + } + + fn listen(&mut self, _config: &SttConfig) -> Result { + Err("a remote whisper takes PCM; record and call transcribe".to_string()) + } +} + +// ------------------------------------------------------- in-process whisper + +#[cfg(feature = "stt")] +mod whisper { + use super::super::weights; + use super::*; + use crate::machine::{self, Claim, ResidencyState}; + use makepad_ai_speech::whisper::{WhisperModel, WhisperParams, WhisperState}; + use std::path::Path; + + /// How long to wait on another process's `Loading` before loading our + /// own copy. Whisper turbo streams 1.6 GB; a minute covers a cold disk. + const HOLDER_PATIENCE: Duration = Duration::from_secs(60); + const POLL: Duration = Duration::from_millis(150); + + pub(super) struct WhisperLocal { + model: WhisperModel, + state: WhisperState, + name: String, + /// The won machine election, held for the life of the engine. + _residency: Option, + } + + impl Engine for WhisperLocal { + fn info(&self) -> SttEngineInfo { + SttEngineInfo { + pipe: PipeId::new("stt.whisper"), + engine: format!("whisper ({}, {})", self.name, makepad_ai_speech::whisper::accel_backend_name()), + remote: None, + capabilities: SttCapabilities { pcm_input: true, engine_mic: false, partial_results: false, offline: true }, + } + } + + fn transcribe(&mut self, samples_16k: &[f32], config: &SttConfig) -> Result { + let params = whisper_params(config); + let segments = self.state.transcribe(&self.model, samples_16k, ¶ms); + Ok(Transcript { + segments: segments + .into_iter() + .map(|s| super::super::Segment { start_ms: s.start_ms, end_ms: s.end_ms, text: s.text }) + .collect(), + }) + } + + fn listen(&mut self, _config: &SttConfig) -> Result { + Err("whisper takes PCM; record and call transcribe".to_string()) + } + } + + fn whisper_params(config: &SttConfig) -> WhisperParams { + let mut params = WhisperParams::default(); + // Whisper wants the bare language code; a BCP-47 tag loses its region. + params.language = config + .language + .split(['-', '_']) + .next() + .unwrap_or("en") + .to_ascii_lowercase(); + params.no_timestamps = !config.timestamps; + params.single_segment = config.single_segment; + if config.max_tokens > 0 { + params.max_tokens = config.max_tokens; + } + if let Some(threshold) = config.silence_threshold { + params.no_speech_thold = threshold; + } + params + } + + /// The machine election around the load (aicore §3): route to a serving + /// holder, wait on a loading one, else claim and load here. + pub(super) fn elect_and_load( + path: &Path, + config: &SttConfig, + send: &dyn Fn(SttEvent), + ) -> Result, String> { + let key = weights::election_key(path); + let deadline = Instant::now() + HOLDER_PATIENCE; + loop { + match machine::read_holder(&key) { + Ok(Some(record)) => match record.state { + ResidencyState::Ready { port } if port > 0 && config.reach >= SpeechReach::Machine => { + let url = format!("http://127.0.0.1:{port}"); + if let Some((_, pipe)) = RemotePipe::at(&url, Domain::Stt, &["whisper"]) { + return Ok(Box::new(RemoteStt { pipe })); + } + // The holder serves something, but not this pipe. + break; + } + ResidencyState::Ready { .. } => { + eprintln!("[hub-stt] {key}: held by pid {} without a usable route — loading a duplicate copy", record.pid); + break; + } + ResidencyState::Loading { fraction } => { + send(SttEvent::Loading { phase: format!("waiting on pid {}", record.pid), fraction }); + if Instant::now() > deadline { + break; + } + std::thread::sleep(POLL * 4); + } + ResidencyState::Failed { .. } => break, + }, + _ => break, + } + } + + let mut guard = match machine::claim(&key) { + Ok(Claim::Won(mut guard)) => { + let _ = guard.publish(ResidencyState::Loading { fraction: 0.0 }); + Some(guard) + } + _ => None, + }; + + let name = path.file_name().map(|n| n.to_string_lossy().into_owned()).unwrap_or_default(); + send(SttEvent::Loading { phase: format!("loading {name}"), fraction: 0.0 }); + let started = Instant::now(); + let model = match WhisperModel::load_file(&path.to_string_lossy()) { + Ok(model) => model, + Err(error) => { + let reason = format!("could not load {}: {error:?}", path.display()); + if let Some(guard) = guard.as_mut() { + let retry_after_ms = unix_ms() + 30_000; + let _ = guard.publish(ResidencyState::Failed { reason: reason.clone(), retry_after_ms }); + } + return Err(reason); + } + }; + let state = WhisperState::new(&model); + if let Some(guard) = guard.as_mut() { + // Resident but not serving a port: co-located claimants see the + // election held and fall back per the documented soft failure. + let _ = guard.publish(ResidencyState::Ready { port: 0 }); + } + send(SttEvent::Loading { + phase: format!("loaded {name} in {:.1}s", started.elapsed().as_secs_f64()), + fraction: 1.0, + }); + Ok(Box::new(WhisperLocal { model, state, name, _residency: guard })) + } + + fn unix_ms() -> u64 { + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .map(|d| d.as_millis() as u64) + .unwrap_or(0) + } +} diff --git a/libs/ai/hub/src/speech/tts_worker.rs b/libs/ai/hub/src/speech/tts_worker.rs new file mode 100644 index 000000000..dcc9f603a --- /dev/null +++ b/libs/ai/hub/src/speech/tts_worker.rs @@ -0,0 +1,312 @@ +//! The TTS session worker: choose a voice engine once, then render utterances +//! in order. Audio goes back as PCM; the app plays it. + +use super::remote::RemotePipe; +use super::weights; +use super::{SpeechAudio, SpeechReach, TtsConfig, TtsEngine, TtsEngineInfo, TtsEvent, TtsMsg}; +use crate::pipe::PipeId; +use crate::registry::Domain; +use makepad_system_speech as sys; +use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::mpsc::{Receiver, Sender}; +use std::sync::Arc; +use std::time::Instant; + +pub(crate) fn run( + config: TtsConfig, + msg_rx: Receiver, + event_tx: Sender, + generation: Arc, +) { + let wake = config.wake.clone(); + let send = move |event: TtsEvent| { + let _ = event_tx.send(event); + if let Some(wake) = &wake { + wake(); + } + }; + + let mut engine = match choose(&config, &send) { + Ok(engine) => engine, + Err(why) => return send(TtsEvent::Failed(why)), + }; + send(TtsEvent::Ready(engine.info())); + + while let Ok(TtsMsg::Say { utterance, generation: mine, text }) = msg_rx.recv() { + if mine != generation.load(Ordering::Relaxed) { + continue; + } + let text = text.trim(); + if text.is_empty() { + continue; + } + let started = Instant::now(); + match engine.synthesize(text, &config) { + Ok(audio) if !audio.is_empty() => { + // Synthesis is slow enough that a cancel can land while it + // runs; a stale utterance must never be heard. + if mine == generation.load(Ordering::Relaxed) { + send(TtsEvent::Audio { utterance, audio, secs: started.elapsed().as_secs_f64() }); + } + } + Ok(_) => send(TtsEvent::Error { utterance, message: "engine produced no audio".into() }), + Err(message) => send(TtsEvent::Error { utterance, message }), + } + } +} + +trait Engine { + fn info(&self) -> TtsEngineInfo; + fn synthesize(&mut self, text: &str, config: &TtsConfig) -> Result; +} + +// ----------------------------------------------------------------- choosing + +fn choose(config: &TtsConfig, send: &dyn Fn(TtsEvent)) -> Result, String> { + let want_kokoro = matches!(config.engine, TtsEngine::Auto | TtsEngine::Kokoro); + let want_system = matches!(config.engine, TtsEngine::Auto | TtsEngine::System); + let mut reasons: Vec = Vec::new(); + + if want_kokoro { + #[cfg(feature = "tts")] + { + if !super::in_process_allowed("kokoro") { + reasons.push("in-process kokoro is off on this platform (MAKEPAD=kokoro enables it)".into()); + } else if let Some(path) = weights::kokoro_model_path() { + match kokoro::elect_and_load(&path, config, send) { + Ok(engine) => return Ok(engine), + Err(why) => reasons.push(why), + } + } else { + reasons.push(format!("no kokoro weights ({}) on this machine", weights::KOKORO_MODEL_FILE)); + } + } + #[cfg(not(feature = "tts"))] + reasons.push("kokoro is not compiled into this build".into()); + + if config.reach >= SpeechReach::Machine { + send(TtsEvent::Loading { phase: "looking for a kokoro node".into(), fraction: 0.0 }); + match RemotePipe::find(config.reach, Domain::Speech, &["kokoro"]) { + Some(pipe) => return Ok(Box::new(RemoteTts { pipe })), + None => reasons.push(format!("no node in reach ({:?}) serves tts.kokoro", config.reach)), + } + } + } + + if want_system { + if sys::tts::available() { + return Ok(Box::new(SystemTts)); + } + reasons.push(format!("no system voice here ({})", sys::tts::engine_name())); + } + + Err(reasons.join("; ")) +} + +/// The Kokoro voice a config asks for, as a bare pack name. +fn kokoro_voice_name(config: &TtsConfig) -> String { + config + .voice + .as_deref() + .map(|v| v.strip_suffix(".mkvoice").unwrap_or(v).to_string()) + .filter(|v| !v.is_empty()) + .unwrap_or_else(weights::kokoro_default_voice) +} + +// ------------------------------------------------------------- the OS engine + +struct SystemTts; + +impl Engine for SystemTts { + fn info(&self) -> TtsEngineInfo { + TtsEngineInfo { + pipe: PipeId::new("tts.system"), + engine: sys::tts::engine_name().to_string(), + remote: None, + // The OS decides per voice (Apple 22.05 kHz, Windows 16/22/24 kHz + // by voice); every `Audio` event carries its own rate. + sample_rate: 0, + voices: sys::tts::voices(), + } + } + + fn synthesize(&mut self, text: &str, config: &TtsConfig) -> Result { + let options = sys::TtsOptions { + voice: config.voice.clone(), + language: config.language.clone(), + rate: config.rate, + pitch: config.pitch, + }; + sys::tts::synthesize(text, &options).map_err(|e| e.to_string()) + } +} + +// ---------------------------------------------------------------- remote pipe + +struct RemoteTts { + pipe: RemotePipe, +} + +impl Engine for RemoteTts { + fn info(&self) -> TtsEngineInfo { + TtsEngineInfo { + pipe: PipeId::new("tts.kokoro"), + engine: format!("kokoro ({})", self.pipe.model), + remote: Some(self.pipe.base_url.clone()), + sample_rate: 24_000, + voices: weights::kokoro_voice_catalogue(), + } + } + + fn synthesize(&mut self, text: &str, config: &TtsConfig) -> Result { + self.pipe.synthesize(text, &kokoro_voice_name(config), config.rate) + } +} + +// -------------------------------------------------------- in-process kokoro + +#[cfg(feature = "tts")] +mod kokoro { + use super::super::Voice; + use super::*; + use crate::machine::{self, Claim, ResidencyState}; + use makepad_ai_speech::kokoro::KokoroSpeaker; + use std::path::{Path, PathBuf}; + use std::time::Duration; + + const HOLDER_PATIENCE: Duration = Duration::from_secs(30); + const POLL: Duration = Duration::from_millis(150); + + pub(super) struct KokoroLocal { + model_path: PathBuf, + speaker: KokoroSpeaker, + voice: String, + voices: Vec, + _residency: Option, + } + + impl Engine for KokoroLocal { + fn info(&self) -> TtsEngineInfo { + TtsEngineInfo { + pipe: PipeId::new("tts.kokoro"), + engine: format!("kokoro ({})", weights::KOKORO_MODEL_FILE), + remote: None, + sample_rate: makepad_ai_speech::kokoro::SAMPLE_RATE, + voices: self.voices.clone(), + } + } + + fn synthesize(&mut self, text: &str, config: &TtsConfig) -> Result { + let wanted = kokoro_voice_name(config); + if wanted != self.voice { + // A voice is a 510x256 style table; the speaker reloads with + // it. Rare (the config picks one voice), so the reload cost + // is acceptable. + let voice_path = weights::kokoro_voice_path(&wanted) + .ok_or_else(|| format!("kokoro voice pack {wanted}.mkvoice not found"))?; + self.speaker = KokoroSpeaker::load_with_voice( + &self.model_path.to_string_lossy(), + &voice_path.to_string_lossy(), + ) + .map_err(|e| format!("kokoro load voice {wanted}: {e:?}"))?; + self.voice = wanted; + } + let audio = self + .speaker + .synthesize_with_speed(text, config.rate) + .map_err(|e| format!("kokoro: {e:?}"))?; + Ok(SpeechAudio { samples: audio.samples, sample_rate: audio.sample_rate }) + } + } + + pub(super) fn elect_and_load( + path: &Path, + config: &TtsConfig, + send: &dyn Fn(TtsEvent), + ) -> Result, String> { + let key = weights::election_key(path); + let deadline = Instant::now() + HOLDER_PATIENCE; + loop { + match machine::read_holder(&key) { + Ok(Some(record)) => match record.state { + ResidencyState::Ready { port } if port > 0 && config.reach >= SpeechReach::Machine => { + let url = format!("http://127.0.0.1:{port}"); + if let Some((_, pipe)) = RemotePipe::at(&url, Domain::Speech, &["kokoro"]) { + return Ok(Box::new(RemoteTts { pipe })); + } + break; + } + ResidencyState::Ready { .. } => { + eprintln!("[hub-tts] {key}: held by pid {} without a usable route — loading a duplicate copy", record.pid); + break; + } + ResidencyState::Loading { fraction } => { + send(TtsEvent::Loading { phase: format!("waiting on pid {}", record.pid), fraction }); + if Instant::now() > deadline { + break; + } + std::thread::sleep(POLL * 4); + } + ResidencyState::Failed { .. } => break, + }, + _ => break, + } + } + + let mut guard = match machine::claim(&key) { + Ok(Claim::Won(mut guard)) => { + let _ = guard.publish(ResidencyState::Loading { fraction: 0.0 }); + Some(guard) + } + _ => None, + }; + + let voice = kokoro_voice_name(config); + let voice_path = match weights::kokoro_voice_path(&voice) { + Some(path) => path, + None => { + let reason = format!("kokoro voice pack {voice}.mkvoice not found"); + if let Some(guard) = guard.as_mut() { + let _ = guard.publish(ResidencyState::Failed { reason: reason.clone(), retry_after_ms: unix_ms() + 30_000 }); + } + return Err(reason); + } + }; + send(TtsEvent::Loading { phase: format!("loading {}", weights::KOKORO_MODEL_FILE), fraction: 0.0 }); + let started = Instant::now(); + let mut speaker = match KokoroSpeaker::load_with_voice(&path.to_string_lossy(), &voice_path.to_string_lossy()) { + Ok(speaker) => speaker, + Err(error) => { + let reason = format!("could not load {}: {error:?}", path.display()); + if let Some(guard) = guard.as_mut() { + let _ = guard.publish(ResidencyState::Failed { reason: reason.clone(), retry_after_ms: unix_ms() + 30_000 }); + } + return Err(reason); + } + }; + // Discarded warm-up: the first synthesis initializes the Metal + // context on this thread — better now than on the first sentence. + let _ = speaker.synthesize("Hi."); + if let Some(guard) = guard.as_mut() { + let _ = guard.publish(ResidencyState::Ready { port: 0 }); + } + send(TtsEvent::Loading { + phase: format!("loaded kokoro in {:.1}s", started.elapsed().as_secs_f64()), + fraction: 1.0, + }); + Ok(Box::new(KokoroLocal { + model_path: path.to_path_buf(), + speaker, + voice, + voices: weights::kokoro_voices(), + _residency: guard, + })) + } + + fn unix_ms() -> u64 { + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .map(|d| d.as_millis() as u64) + .unwrap_or(0) + } +} diff --git a/libs/ai/hub/src/speech/weights.rs b/libs/ai/hub/src/speech/weights.rs new file mode 100644 index 000000000..805f797ae --- /dev/null +++ b/libs/ai/hub/src/speech/weights.rs @@ -0,0 +1,182 @@ +//! Where the speech weights live, and what they are called. +//! +//! Resolution order for every file: an explicit env override, the working +//! directory, next to the executable (what a bundled app sees), then the +//! shared home `~/.makepad/weights//…` — the same cache paths the +//! registry's `cache_as` entries use, so a file the machine node downloaded +//! is found by every app on the machine without any coordination. + +use crate::home; +use makepad_system_speech::{Voice, VoiceGender}; +use std::path::{Path, PathBuf}; + +pub const WHISPER_MODEL_FILE: &str = "ggml-large-v3-turbo.bin"; +pub const WHISPER_MODEL_ENV: &str = "MAKEPAD_VOICE_MODEL"; +/// The registry id of the Whisper model the in-process engine loads and the +/// `stt.whisper` pipe serves. +pub const WHISPER_MODEL_ID: &str = "whisper-large-v3-turbo"; + +pub const KOKORO_MODEL_FILE: &str = "kokoro-v1_0.mktts"; +pub const KOKORO_MODEL_ENV: &str = "MAKEPAD_TTS_MODEL"; +pub const KOKORO_VOICE_ENV: &str = "MAKEPAD_TTS_VOICE"; +pub const KOKORO_DEFAULT_VOICE: &str = "bm_daniel"; +/// The registry id of the Kokoro model (`tts.kokoro`). +pub const KOKORO_MODEL_ID: &str = "kokoro"; + +/// Kokoro v1.0's English voice packs. Fixed for the model version, so a +/// remote `tts.kokoro` pipe can be listed without a voices endpoint. +pub const KOKORO_VOICE_NAMES: &[&str] = &[ + "af_alloy", "af_aoede", "af_bella", "af_heart", "af_jessica", "af_kore", "af_nicole", "af_nova", + "af_river", "af_sarah", "af_sky", "am_adam", "am_echo", "am_eric", "am_fenrir", "am_liam", + "am_michael", "am_onyx", "am_puck", "am_santa", "bf_alice", "bf_emma", "bf_isabella", "bf_lily", + "bm_daniel", "bm_fable", "bm_george", "bm_lewis", +]; + +fn candidates(env: &str, name: &str, sub: &str) -> Vec { + let mut out = Vec::new(); + if let Ok(path) = std::env::var(env) { + if !path.trim().is_empty() { + out.push(PathBuf::from(path)); + } + } + out.push(PathBuf::from(name)); + if let Some(dir) = std::env::current_exe().ok().and_then(|exe| exe.parent().map(Path::to_path_buf)) { + out.push(dir.join(name)); + } + out.push(home::weights_dir().join(sub).join(name)); + out +} + +fn first_file(paths: Vec) -> Option { + paths.into_iter().find(|p| p.is_file()) +} + +/// The Whisper weights, if this machine has them. +pub fn whisper_model_path() -> Option { + first_file(candidates(WHISPER_MODEL_ENV, WHISPER_MODEL_FILE, "stt")) +} + +/// The Kokoro weights, if this machine has them. +pub fn kokoro_model_path() -> Option { + first_file(candidates(KOKORO_MODEL_ENV, KOKORO_MODEL_FILE, "tts")) +} + +/// A Kokoro voice pack by name (`"bm_daniel"` or `"bm_daniel.mkvoice"`), +/// searched next to the model and along the usual chain. `MAKEPAD_TTS_VOICE` +/// pointing at a file wins outright, as it always has. +pub fn kokoro_voice_path(name: &str) -> Option { + if let Ok(path) = std::env::var(KOKORO_VOICE_ENV) { + let path = PathBuf::from(path); + if path.is_file() { + return Some(path); + } + } + let file = if name.ends_with(".mkvoice") { name.to_string() } else { format!("{name}.mkvoice") }; + let mut paths = Vec::new(); + if let Some(dir) = kokoro_model_path().and_then(|m| m.parent().map(Path::to_path_buf)) { + paths.push(dir.join(&file)); + } + paths.extend(candidates("", &file, "tts").into_iter().skip(0)); + first_file(paths) +} + +/// The voice the environment or the default asks for, as a bare pack name. +pub fn kokoro_default_voice() -> String { + if let Ok(path) = std::env::var(KOKORO_VOICE_ENV) { + if let Some(stem) = Path::new(&path).file_stem().and_then(|s| s.to_str()) { + return stem.to_string(); + } + } + KOKORO_DEFAULT_VOICE.to_string() +} + +/// A [`Voice`] for a Kokoro pack name: `bm_daniel` → "Daniel", en-GB, male. +pub fn kokoro_voice(name: &str) -> Voice { + let stem = name.strip_suffix(".mkvoice").unwrap_or(name); + let mut chars = stem.chars(); + let accent = chars.next(); + let gender = chars.next(); + let language = match accent { + Some('a') => "en-US", + Some('b') => "en-GB", + _ => "en", + }; + let gender = match gender { + Some('f') => VoiceGender::Female, + Some('m') => VoiceGender::Male, + _ => VoiceGender::Unknown, + }; + let bare = stem.split_once('_').map(|(_, rest)| rest).unwrap_or(stem); + let mut pretty = String::new(); + for (i, c) in bare.chars().enumerate() { + pretty.push(if i == 0 { c.to_ascii_uppercase() } else { c }); + } + Voice { id: stem.to_string(), name: pretty, language: language.to_string(), gender, offline: true } +} + +/// The Kokoro voices present on this machine: every `.mkvoice` next to the +/// model and along the resolution chain, deduplicated by name. +pub fn kokoro_voices() -> Vec { + let mut dirs: Vec = Vec::new(); + if let Some(dir) = kokoro_model_path().and_then(|m| m.parent().map(Path::to_path_buf)) { + dirs.push(dir); + } + dirs.push(PathBuf::from(".")); + if let Some(dir) = std::env::current_exe().ok().and_then(|exe| exe.parent().map(Path::to_path_buf)) { + dirs.push(dir); + } + dirs.push(home::weights_dir().join("tts")); + let mut names: Vec = Vec::new(); + for dir in dirs { + let Ok(entries) = std::fs::read_dir(&dir) else { continue }; + for entry in entries.flatten() { + let name = entry.file_name().to_string_lossy().into_owned(); + if let Some(stem) = name.strip_suffix(".mkvoice") { + if !names.iter().any(|n| n == stem) { + names.push(stem.to_string()); + } + } + } + } + names.sort(); + names.iter().map(|n| kokoro_voice(n)).collect() +} + +/// The full catalogue, for a remote Kokoro whose files we cannot see. +pub fn kokoro_voice_catalogue() -> Vec { + KOKORO_VOICE_NAMES.iter().map(|n| kokoro_voice(n)).collect() +} + +/// The machine-election key for a weights file: its lowercase file name, +/// exactly as `hub_chat` keys the LLM. +pub fn election_key(path: &Path) -> String { + path.file_name() + .map(|n| n.to_string_lossy().to_ascii_lowercase()) + .unwrap_or_else(|| "unknown-model".to_string()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn kokoro_voice_names_decode() { + let v = kokoro_voice("bm_daniel"); + assert_eq!(v.id, "bm_daniel"); + assert_eq!(v.name, "Daniel"); + assert_eq!(v.language, "en-GB"); + assert_eq!(v.gender, VoiceGender::Male); + let v = kokoro_voice("af_heart.mkvoice"); + assert_eq!((v.id.as_str(), v.language.as_str(), v.gender), ("af_heart", "en-US", VoiceGender::Female)); + } + + #[test] + fn catalogue_has_all_28_voices() { + assert_eq!(kokoro_voice_catalogue().len(), 28); + } + + #[test] + fn election_key_is_the_lowercase_file_name() { + assert_eq!(election_key(Path::new("/x/GGML-Large-v3-turbo.bin")), "ggml-large-v3-turbo.bin"); + } +} diff --git a/libs/ai/hub/src/whisper_backend.rs b/libs/ai/hub/src/whisper_backend.rs new file mode 100644 index 000000000..117476e4d --- /dev/null +++ b/libs/ai/hub/src/whisper_backend.rs @@ -0,0 +1,282 @@ +//! The `whisper` backend: speech-to-text (the `stt` domain) through the +//! in-repo Whisper port — the wire side of the `stt.whisper` pipe a machine +//! node or LAN box publishes. This file only wraps the engine. +//! +//! Request: `{model: "whisper-large-v3-turbo", input_b64: , +//! input_content_type: "audio/wav", language: "en"}` -> one +//! `application/json` artifact, a [`TranscriptJson`]: the segments with +//! millisecond timing and the joined text. Any WAV the in-repo decoder reads +//! is accepted; it is downmixed and resampled to 16 kHz here, so a client +//! never has to. + +use crate::backend::{ArtifactData, BackendCtx, CancelToken, ContentBackend, GenerateParams, ProgressSink}; +use crate::error::AssetAiError; +use crate::protocol::{TranscriptJson, TranscriptSegmentJson}; +use makepad_micro_serde::SerJson; + +const WHISPER_SAMPLE_RATE: u32 = 16_000; + +/// One utterance handed to the engine: 16 kHz mono PCM plus the language. +pub struct TranscribeJob<'a> { + pub samples_16k: &'a [f32], + pub language: String, +} + +/// Pluggable recognition: the real path calls the makepad-ai-speech whisper engine; tests plug in +/// a closure. +pub type TranscribeFn = + Box Result, AssetAiError> + Send>; + +enum Recognizer { + Stub(TranscribeFn), + #[cfg(feature = "stt")] + Whisper(whisper_engine::WhisperEngine), +} + +pub struct WhisperBackend { + model_id: String, + recognizer: Recognizer, +} + +impl WhisperBackend { + /// Test/CI constructor: recognition is the given closure, no weights. + pub fn with_stub(model_id: &str, recognize: TranscribeFn) -> Self { + Self { model_id: model_id.to_string(), recognizer: Recognizer::Stub(recognize) } + } + + #[cfg(feature = "stt")] + pub fn new_whisper(model_id: &str) -> Self { + Self { model_id: model_id.to_string(), recognizer: Recognizer::Whisper(whisper_engine::WhisperEngine::new()) } + } +} + +/// Decode the request's audio to 16 kHz mono. +fn decode_input(params: &GenerateParams) -> Result, AssetAiError> { + if params.input_bytes.is_empty() { + return Err(AssetAiError::Params("speech recognition needs `input_b64` audio (audio/wav)".into())); + } + let content_type = params.input_content_type.to_ascii_lowercase(); + if !(content_type.contains("wav") || content_type.contains("wave") || content_type == "application/octet-stream") { + return Err(AssetAiError::Params(format!( + "input_content_type {:?}: whisper takes audio/wav", + params.input_content_type + ))); + } + let (samples, rate) = crate::wav::decode_wav_to_mono_f32(¶ms.input_bytes) + .map_err(|e| AssetAiError::Params(format!("input wav: {e}")))?; + Ok(if rate == WHISPER_SAMPLE_RATE { + samples + } else { + crate::resample::resample_channel(&samples, rate, WHISPER_SAMPLE_RATE) + }) +} + +impl ContentBackend for WhisperBackend { + fn model_id(&self) -> &str { + &self.model_id + } + + fn ensure_loaded(&mut self, _ctx: &mut BackendCtx) -> Result<(), AssetAiError> { + match &mut self.recognizer { + Recognizer::Stub(_) => Ok(()), + #[cfg(feature = "stt")] + Recognizer::Whisper(engine) => engine.ensure_loaded(_ctx), + } + } + + fn is_resident(&self) -> bool { + match &self.recognizer { + Recognizer::Stub(_) => false, + #[cfg(feature = "stt")] + Recognizer::Whisper(engine) => engine.is_resident(), + } + } + + fn unload(&mut self) -> Result<(), AssetAiError> { + match &mut self.recognizer { + Recognizer::Stub(_) => {} + #[cfg(feature = "stt")] + Recognizer::Whisper(engine) => engine.unload(), + } + Ok(()) + } + + fn generate( + &mut self, + params: &GenerateParams, + progress: ProgressSink, + cancel: &CancelToken, + ) -> Result, AssetAiError> { + progress("decode", 0.05); + let samples = decode_input(params)?; + cancel.check()?; + let language = if params.language.trim().is_empty() { + "en".to_string() + } else { + // Whisper wants the bare code; a BCP-47 tag loses its region. + params.language.split(['-', '_']).next().unwrap_or("en").to_ascii_lowercase() + }; + let job = TranscribeJob { samples_16k: &samples, language }; + progress("transcribe", 0.1); + let segments = match &mut self.recognizer { + Recognizer::Stub(recognize) => recognize(&job)?, + #[cfg(feature = "stt")] + Recognizer::Whisper(engine) => engine.transcribe(&job)?, + }; + cancel.check()?; + let text = segments + .iter() + .map(|s| s.text.trim()) + .filter(|t| !t.is_empty()) + .collect::>() + .join(" "); + let json = TranscriptJson { text, segments }.serialize_json(); + progress("done", 1.0); + Ok(vec![ArtifactData { content_type: "application/json", ext: "json", bytes: json.into_bytes() }]) + } +} + +#[cfg(feature = "stt")] +mod whisper_engine { + use super::{TranscribeJob, TranscriptSegmentJson}; + use crate::backend::BackendCtx; + use crate::error::AssetAiError; + use makepad_ai_speech::whisper::{WhisperModel, WhisperParams, WhisperState}; + use std::path::PathBuf; + + pub struct WhisperEngine { + model_path: Option, + loaded: Option<(WhisperModel, WhisperState)>, + } + + impl WhisperEngine { + pub fn new() -> Self { + Self { model_path: None, loaded: None } + } + + /// The registry file (downloaded on demand into the cache) or, as the + /// dev fallback, the same chain the in-process session uses. + pub fn ensure_loaded(&mut self, ctx: &mut BackendCtx) -> Result<(), AssetAiError> { + let path = match ctx.ensure_files() { + Ok(files) => files + .into_iter() + .find(|f| f.extension().is_some_and(|e| e == "bin")) + .or_else(crate::speech::weights::whisper_model_path), + Err(_) => crate::speech::weights::whisper_model_path(), + } + .ok_or_else(|| { + AssetAiError::Backend(format!( + "whisper weights not found (expected {} in the cache stt/ dir or MAKEPAD_VOICE_MODEL)", + crate::speech::weights::WHISPER_MODEL_FILE + )) + })?; + if self.model_path.as_ref() != Some(&path) { + self.model_path = Some(path.clone()); + self.loaded = None; + } + if self.loaded.is_none() { + let model = WhisperModel::load_file(&path.to_string_lossy()) + .map_err(|e| AssetAiError::Backend(format!("whisper load {}: {e:?}", path.display())))?; + let state = WhisperState::new(&model); + self.loaded = Some((model, state)); + } + Ok(()) + } + + pub fn is_resident(&self) -> bool { + self.loaded.is_some() + } + + pub fn unload(&mut self) { + self.loaded = None; + } + + pub fn transcribe(&mut self, job: &TranscribeJob) -> Result, AssetAiError> { + let (model, state) = self + .loaded + .as_mut() + .ok_or_else(|| AssetAiError::Backend("whisper used before ensure_loaded".into()))?; + let mut params = WhisperParams::default(); + params.language = job.language.clone(); + params.no_timestamps = false; + params.single_segment = false; + params.temperature = 0.0; + params.suppress_blank = true; + Ok(state + .transcribe(model, job.samples_16k, ¶ms) + .into_iter() + .map(|s| TranscriptSegmentJson { start_ms: s.start_ms, end_ms: s.end_ms, text: s.text }) + .collect()) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::backend::GenerateParams; + use crate::protocol::GenerateRequestJson; + use makepad_micro_serde::DeJson; + + fn params_with_wav(samples: &[f32], rate: u32, language: &str) -> GenerateParams { + let wav = crate::wav::encode_wav_pcm16_mono(samples, rate); + let request = GenerateRequestJson { + model: "whisper-large-v3-turbo".into(), + input_b64: Some( + String::from_utf8(makepad_base64::base64_encode(&wav, &makepad_base64::BASE64_STANDARD)).unwrap(), + ), + input_content_type: Some("audio/wav".into()), + language: Some(language.into()), + ..Default::default() + }; + GenerateParams::from_request(&request).unwrap() + } + + #[test] + fn transcribes_wav_input_to_a_json_transcript() { + let mut seen_len = 0usize; + let mut seen_lang = String::new(); + let mut backend = WhisperBackend::with_stub( + "whisper-large-v3-turbo", + Box::new(|job| { + Ok(vec![TranscriptSegmentJson { start_ms: 0, end_ms: 500, text: format!("heard {} samples", job.samples_16k.len()) }]) + }), + ); + let params = params_with_wav(&vec![0.1; 16_000], 16_000, "en-GB"); + let out = backend + .generate(¶ms, &mut |_, _| {}, &CancelToken::new()) + .unwrap(); + assert_eq!(out.len(), 1); + assert_eq!(out[0].content_type, "application/json"); + let json = TranscriptJson::deserialize_json(std::str::from_utf8(&out[0].bytes).unwrap()).unwrap(); + assert_eq!(json.text, "heard 16000 samples"); + assert_eq!(json.segments[0].end_ms, 500); + let _ = (&mut seen_len, &mut seen_lang); + } + + #[test] + fn resamples_non_16k_input_and_bares_the_language() { + let mut backend = WhisperBackend::with_stub( + "whisper-large-v3-turbo", + Box::new(|job| { + Ok(vec![TranscriptSegmentJson { start_ms: 0, end_ms: 0, text: format!("{} {}", job.samples_16k.len(), job.language) }]) + }), + ); + // One second at 48 kHz must arrive as one second at 16 kHz. + let params = params_with_wav(&vec![0.0; 48_000], 48_000, "pt-BR"); + let out = backend.generate(¶ms, &mut |_, _| {}, &CancelToken::new()).unwrap(); + let json = TranscriptJson::deserialize_json(std::str::from_utf8(&out[0].bytes).unwrap()).unwrap(); + let (len, lang) = json.text.split_once(' ').unwrap(); + let len: usize = len.parse().unwrap(); + assert!((15_900..=16_100).contains(&len), "{len}"); + assert_eq!(lang, "pt"); + } + + #[test] + fn refuses_a_request_without_audio() { + let mut backend = WhisperBackend::with_stub("whisper-large-v3-turbo", Box::new(|_| Ok(Vec::new()))); + let request = GenerateRequestJson { model: "whisper-large-v3-turbo".into(), ..Default::default() }; + let params = GenerateParams::from_request(&request).unwrap(); + assert!(backend.generate(¶ms, &mut |_, _| {}, &CancelToken::new()).is_err()); + } +} diff --git a/libs/ai/models/speech/Cargo.toml b/libs/ai/models/speech/Cargo.toml index 3a8a0fa6f..fd373d469 100644 --- a/libs/ai/models/speech/Cargo.toml +++ b/libs/ai/models/speech/Cargo.toml @@ -2,33 +2,82 @@ name = "makepad-ai-speech" version = "0.1.0" edition = "2021" -description = "Speech family: IndexTTS-2.5 + Kokoro (aiarch.md §1)." +description = "Speech family: IndexTTS-2.5 + Kokoro speech synthesis engines (text in, PCM out). No platform code: OS voices are makepad-system-speech, engine choice is makepad-ai-hub." license = "MIT" +[features] +default = ["whisper", "vad", "kokoro", "indextts"] +# Whisper speech-to-text (CPU SIMD / Metal / CUDA). +whisper = [] +# Silero voice-activity detection. +vad = [] +# Kokoro-82M text-to-speech (+ its G2P). +kokoro = [] +# IndexTTS-2.5 character-voice text-to-speech. +indextts = [] +# Precompile the Whisper ggml Metal library at build time (else runtime source compile). +metal-precompile = [] + [dependencies] +# THE CUDA store (Whisper's CUDA backend). Must NOT be target-specific: cargo +# drops target-cfg deps when this crate is a path dep of another standalone +# `[workspace]`, and the `links = "makepad_ai_cuda"` handshake +# (DEP_MAKEPAD_AI_CUDA_KERNELS, read in build.rs) only arrives for an +# unconditional dependency. On macOS/iOS the crate compiles to empty stubs. +makepad-ai-cuda = { path = "../../cuda" } makepad-ai-common = { path = "../common" } makepad-ai-loader = { path = "../../loader" } makepad-ai-sfx = { path = "../sfx" } -[dev-dependencies] -makepad-voice = { path = "../../../voice" } - [[bin]] name = "g2p_test" path = "src/bin/g2p_test.rs" +required-features = ["kokoro"] [[bin]] name = "har_bisect" path = "src/bin/har_bisect.rs" +required-features = ["kokoro"] [[bin]] name = "kokoro_probe" path = "src/bin/kokoro_probe.rs" +required-features = ["kokoro"] [[bin]] name = "parity" path = "src/bin/parity.rs" +required-features = ["kokoro"] [[bin]] name = "tts_test" path = "src/bin/tts_test.rs" +required-features = ["kokoro"] + +[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies] +makepad-objc-sys = { path = "../../../objc-sys", version = "1.0.0" } + +[[bin]] +name = "whisper-test" +path = "src/bin/whisper_test.rs" +required-features = ["whisper"] + +[[bin]] +name = "whisper-parity" +path = "src/bin/whisper_parity.rs" +required-features = ["whisper"] + +[[bin]] +name = "vad-test" +path = "src/bin/vad_test.rs" +required-features = ["vad"] + +[[bin]] +name = "metal-strip-unused" +path = "src/bin/metal_strip_unused.rs" +required-features = ["whisper"] + +[[test]] +name = "silero_vad" +path = "tests/silero_vad.rs" +required-features = ["vad"] diff --git a/libs/ai/models/speech/build.rs b/libs/ai/models/speech/build.rs index b3379c92e..711141c1c 100644 --- a/libs/ai/models/speech/build.rs +++ b/libs/ai/models/speech/build.rs @@ -2,121 +2,109 @@ use std::env; use std::fs; use std::process::Command; -const IOS_DEPLOYMENT_TARGET_DEFAULT: &str = "26.0"; - fn main() { - println!("cargo:rerun-if-changed=swift/tts_bridge.swift"); - println!("cargo:rustc-check-cfg=cfg(no_apple_tts)"); - let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default(); - let is_apple_host = env::var("HOST").unwrap_or_default().contains("apple"); - let is_apple_target = target_os == "macos" || target_os == "ios"; + // `makepad-ai-cuda` sets `links = "makepad_ai_cuda"` and emits + // `cargo:kernels=1` only when nvcc actually built and archived its .cu + // objects. Cargo forwards that to us as DEP_MAKEPAD_AI_CUDA_KERNELS, which + // is the only honest signal that `src/cuda/backend.rs` can link against a + // CUDA runtime. Without it the CUDA backend compiles to stubs and + // `src/accel.rs` falls back to Metal (Apple) or the CPU. + println!("cargo:rustc-check-cfg=cfg(makepad_ai_cuda_kernels)"); + if env::var("DEP_MAKEPAD_AI_CUDA_KERNELS").as_deref() == Ok("1") { + println!("cargo:rustc-cfg=makepad_ai_cuda_kernels"); + } + println!("cargo:rerun-if-env-changed=MAKEPAD_VOICE_METAL_PRECOMPILE"); - // No Swift toolchain, or not an Apple target: the crate degrades to a no-op - // rather than failing the build. - if !(is_apple_host && is_apple_target) || !build_tts_bridge(&target_os) { - println!("cargo:rustc-cfg=no_apple_tts"); + if target_os == "macos" { + build_whisper_metallib(); } } -/// Compile `swift/tts_bridge.swift` into a static library and link it. -/// -/// Unlike the speech (STT) bridge, nothing here is `async`, so Swift Concurrency -/// is never linked and the `@rpath/libswift_Concurrency.dylib` install-name -/// workaround that `makepad-voice` needs does not apply. -fn build_tts_bridge(target_os: &str) -> bool { +fn build_whisper_metallib() { + let precompile_default = env::var_os("CARGO_FEATURE_METAL_PRECOMPILE").is_some(); + let precompile_enabled = env::var("MAKEPAD_VOICE_METAL_PRECOMPILE") + .ok() + .map(|v| { + let v = v.trim().to_ascii_lowercase(); + !(v.is_empty() || v == "0" || v == "false" || v == "no" || v == "off") + }) + .unwrap_or(precompile_default); + let out_dir = env::var("OUT_DIR").unwrap(); let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); - let swift_src = format!("{manifest_dir}/swift/tts_bridge.swift"); - let module_cache = format!("{out_dir}/swift_module_cache"); - let _ = fs::create_dir_all(&module_cache); - let mut args = vec![ - "-emit-library".to_string(), - "-static".to_string(), - "-parse-as-library".to_string(), - "-module-name".to_string(), - "tts_bridge".to_string(), - "-module-cache-path".to_string(), - module_cache, - "-O".to_string(), - ]; - if target_os == "ios" { - if let Some((target, sdk)) = ios_target_and_sdk() { - args.push("-target".to_string()); - args.push(target); - args.push("-sdk".to_string()); - args.push(sdk); - } - } - args.push("-o".to_string()); - args.push(format!("{out_dir}/libtts_bridge.a")); - args.push(swift_src); + let ggml_src_dir = format!("{}/src/whisper/metal/ggml", manifest_dir); + let ggml_metal_dir = format!("{}/src/whisper/metal/ggml", manifest_dir); - match Command::new("swiftc").args(&args).status() { - Ok(status) if status.success() => {} - Ok(_) => { - println!("cargo:warning=swiftc failed for tts bridge; speech is disabled"); - return false; - } - Err(err) => { - println!("cargo:warning=swiftc unavailable ({err}); speech is disabled"); - return false; - } + let metal_src = format!("{}/ggml-metal.metal", ggml_metal_dir); + let common_h = format!("{}/ggml-common.h", ggml_src_dir); + let impl_h = format!("{}/ggml-metal-impl.h", ggml_metal_dir); + + println!("cargo:rerun-if-changed={}", metal_src); + println!("cargo:rerun-if-changed={}", common_h); + println!("cargo:rerun-if-changed={}", impl_h); + + let _ = fs::create_dir_all(&out_dir); + let air_path = format!("{}/ggml-metal.air", out_dir); + let metallib_path = format!("{}/ggml-default.metallib", out_dir); + + if !precompile_enabled { + let _ = fs::write(&metallib_path, []); + println!( + "cargo:rustc-env=MAKEPAD_VOICE_GGML_METALLIB={}", + metallib_path + ); + return; } - println!("cargo:rustc-link-search=native={out_dir}"); - println!("cargo:rustc-link-lib=static=tts_bridge"); - println!("cargo:rustc-link-lib=framework=Foundation"); - println!("cargo:rustc-link-lib=framework=AVFoundation"); + let metal_status = Command::new("xcrun") + .args([ + "--sdk", + "macosx", + "metal", + "-O3", + "-c", + &metal_src, + "-I", + &ggml_src_dir, + "-I", + &ggml_metal_dir, + "-o", + &air_path, + ]) + .status(); - // Let the linker resolve the Swift runtime symbols the bridge pulls in. - if let Ok(output) = Command::new("swiftc").args(["-print-target-info"]).output() { - if output.status.success() { - let info = String::from_utf8_lossy(&output.stdout); - for line in info.lines() { - let path = line.trim().trim_matches('"').trim_end_matches(','); - if path.starts_with('/') && path.contains("lib/swift") { - println!("cargo:rustc-link-search=native={path}"); - } - } - } + let ok = metal_status.as_ref().is_ok_and(|s| s.success()); + if !ok { + println!("cargo:warning=failed to compile ggml-metal.metal to AIR; runtime source compile will be used"); + let _ = fs::write(&metallib_path, []); + println!( + "cargo:rustc-env=MAKEPAD_VOICE_GGML_METALLIB={}", + metallib_path + ); + return; } - true -} - -fn ios_target_and_sdk() -> Option<(String, String)> { - let arch = env::var("CARGO_CFG_TARGET_ARCH").ok()?; - let abi = env::var("CARGO_CFG_TARGET_ABI").unwrap_or_default(); - let is_simulator = abi == "sim" || arch == "x86_64"; - let swift_arch = match arch.as_str() { - "aarch64" => "arm64", - "x86_64" => "x86_64", - _ => return None, - }; - let deployment_key = if is_simulator { - "IPHONESIMULATOR_DEPLOYMENT_TARGET" - } else { - "IPHONEOS_DEPLOYMENT_TARGET" - }; - let deployment = - env::var(deployment_key).unwrap_or_else(|_| IOS_DEPLOYMENT_TARGET_DEFAULT.to_string()); - let swift_target = if is_simulator { - format!("{swift_arch}-apple-ios{deployment}-simulator") - } else { - format!("{swift_arch}-apple-ios{deployment}") - }; - let sdk_name = if is_simulator { - "iphonesimulator" - } else { - "iphoneos" - }; - let sdk_path = Command::new("xcrun") - .args(["--sdk", sdk_name, "--show-sdk-path"]) - .output() - .ok() - .filter(|out| out.status.success()) - .map(|out| String::from_utf8_lossy(&out.stdout).trim().to_string())?; - Some((swift_target, sdk_path)) + let metallib_status = Command::new("xcrun") + .args([ + "--sdk", + "macosx", + "metallib", + &air_path, + "-o", + &metallib_path, + ]) + .status(); + + let ok = metallib_status.as_ref().is_ok_and(|s| s.success()); + if !ok { + println!("cargo:warning=failed to build ggml default metallib; runtime source compile will be used"); + let _ = fs::write(&metallib_path, []); + } + + println!( + "cargo:rustc-env=MAKEPAD_VOICE_GGML_METALLIB={}", + metallib_path + ); } diff --git a/libs/ai/models/speech/examples/roundtrip.rs b/libs/ai/models/speech/examples/roundtrip.rs deleted file mode 100644 index c91ee344e..000000000 --- a/libs/ai/models/speech/examples/roundtrip.rs +++ /dev/null @@ -1,130 +0,0 @@ -//! Speak a sentence, transcribe it back with Whisper, and score the difference. -//! -//! "It made noise" is not a test. This closes the loop: if the synthesizer -//! mumbles, slurs a plural, or reads `ɡˈæmɛs` for "games", Whisper hears it and -//! the word error rate goes up. It is also the scoreboard for comparing -//! backends — run it once on the system voice, once on Kokoro. -//! -//! Run from the makepad root so the Whisper model resolves: -//! -//! cargo run --release --manifest-path libs/ai/models/speech/Cargo.toml --example roundtrip - -use makepad_ai_speech::{SpeechAudio, Speaker}; -use makepad_voice::{VoiceTranscribeParams, VoiceTranscriber}; - -const WHISPER_SAMPLE_RATE: u32 = 16_000; - -const SENTENCES: &[&str] = &[ - "Hi! I make games with you.", - "I made the player jump higher.", - "Escape the Gummer, a squishy purple blob.", - "You scored forty two points.", - "The little guy can run and jump on the platforms.", - "I gave the ghost bigger eyes and made it chase you faster.", -]; - -fn main() { - let mut speaker = Speaker::from_makepad_env(); - println!("tts backend : {:?}", speaker.kind()); - - let mut transcriber = VoiceTranscriber::from_makepad_env(); - println!("asr backend : {:?}", transcriber.kind()); - let params = VoiceTranscribeParams::default(); - if let Err(err) = transcriber.preload(¶ms) { - println!("asr preload failed: {err:?}"); - return; - } - println!(); - - let (mut total_words, mut total_errors) = (0usize, 0usize); - let started = std::time::Instant::now(); - - for sentence in SENTENCES { - let audio = match speaker.synthesize(sentence) { - Ok(audio) if !audio.is_empty() => audio, - other => { - println!("{sentence:?}\n synthesis produced nothing ({other:?})\n"); - continue; - } - }; - - let heard = transcribe(&mut transcriber, ¶ms, &audio); - let (errors, words) = word_error(sentence, &heard); - total_errors += errors; - total_words += words; - - let verdict = if errors == 0 { "exact" } else { "differs" }; - println!("said : {sentence}"); - println!("heard : {heard}"); - println!( - " {verdict}: {errors}/{words} words wrong ({:.0}% WER), {:.1}s audio", - 100.0 * errors as f32 / words.max(1) as f32, - audio.duration_secs() - ); - println!(); - } - - println!( - "overall WER: {:.1}% ({total_errors}/{total_words} words) in {:.1}s", - 100.0 * total_errors as f32 / total_words.max(1) as f32, - started.elapsed().as_secs_f32() - ); -} - -fn transcribe( - transcriber: &mut VoiceTranscriber, - params: &VoiceTranscribeParams, - audio: &SpeechAudio, -) -> String { - let samples = audio.resampled(WHISPER_SAMPLE_RATE); - match transcriber.transcribe(&samples, params) { - Ok(segments) => segments - .iter() - .map(|segment| segment.text.trim()) - .collect::>() - .join(" ") - .trim() - .to_string(), - Err(err) => format!(""), - } -} - -/// Lowercase, drop punctuation, split on whitespace, and spell out digits. -/// -/// Whisper writes "42" where the sentence said "forty two". Without this the -/// scoreboard would blame the synthesizer for the transcriber's formatting. -fn normalize(text: &str) -> Vec { - text.to_lowercase() - .split(|c: char| !c.is_alphanumeric() && c != '\'') - .filter(|word| !word.is_empty()) - .flat_map(|word| match word.parse::() { - Ok(number) => makepad_ai_speech::g2p::spell_number(number) - .split_whitespace() - .map(str::to_string) - .collect::>(), - Err(_) => vec![word.to_string()], - }) - .collect() -} - -/// Levenshtein distance over words: substitutions, insertions, deletions. -fn word_error(said: &str, heard: &str) -> (usize, usize) { - let reference = normalize(said); - let hypothesis = normalize(heard); - - let mut previous: Vec = (0..=hypothesis.len()).collect(); - let mut current = vec![0usize; hypothesis.len() + 1]; - - for (i, want) in reference.iter().enumerate() { - current[0] = i + 1; - for (j, got) in hypothesis.iter().enumerate() { - let substitution = previous[j] + usize::from(want != got); - let insertion = current[j] + 1; - let deletion = previous[j + 1] + 1; - current[j + 1] = substitution.min(insertion).min(deletion); - } - std::mem::swap(&mut previous, &mut current); - } - - (previous[hypothesis.len()], reference.len()) -} diff --git a/libs/ai/models/speech/examples/score_wav.rs b/libs/ai/models/speech/examples/score_wav.rs deleted file mode 100644 index acec8fa2f..000000000 --- a/libs/ai/models/speech/examples/score_wav.rs +++ /dev/null @@ -1,98 +0,0 @@ -//! Transcribe a WAV with Whisper and score it against the text it should say. -//! -//! The other half of the round-trip harness: `roundtrip.rs` synthesizes through -//! a `Speaker`, this scores audio that came from anywhere — the ONNX reference, -//! the Rust graph, a file on disk. -//! -//! cargo run --release --manifest-path libs/ai/models/speech/Cargo.toml \ -//! --example score_wav -- kokoro_ref_16k.wav "Escape the Gummer, a squishy purple blob." - -use makepad_voice::{VoiceTranscribeParams, VoiceTranscriber}; - -fn main() { - let mut args = std::env::args().skip(1); - let path = args.next().expect("usage: score_wav [expected text]"); - let expected: String = args.collect::>().join(" "); - - let (samples, rate) = read_wav(&path); - println!("wav : {path} ({} samples @ {rate} Hz)", samples.len()); - if rate != 16_000 { - println!("warning : Whisper expects 16 kHz"); - } - - let mut transcriber = VoiceTranscriber::from_makepad_env(); - let params = VoiceTranscribeParams::default(); - if let Err(err) = transcriber.preload(¶ms) { - println!("preload failed: {err:?}"); - return; - } - - let heard = match transcriber.transcribe(&samples, ¶ms) { - Ok(segments) => segments - .iter() - .map(|s| s.text.trim()) - .collect::>() - .join(" "), - Err(err) => { - println!("transcribe failed: {err:?}"); - return; - } - }; - println!("heard : {}", heard.trim()); - - if !expected.is_empty() { - println!("expected : {expected}"); - let (errors, words) = word_error(&expected, &heard); - println!( - "WER : {:.1}% ({errors}/{words} words)", - 100.0 * errors as f32 / words.max(1) as f32 - ); - } -} - -/// 16-bit mono PCM WAV. -fn read_wav(path: &str) -> (Vec, u32) { - let bytes = std::fs::read(path).expect("cannot read wav"); - let rate = u32::from_le_bytes(bytes[24..28].try_into().unwrap()); - let at = bytes - .windows(4) - .position(|w| w == b"data") - .expect("no data chunk") - + 8; - let samples = bytes[at..] - .chunks_exact(2) - .map(|pair| i16::from_le_bytes([pair[0], pair[1]]) as f32 / 32768.0) - .collect(); - (samples, rate) -} - -fn normalize(text: &str) -> Vec { - text.to_lowercase() - .split(|c: char| !c.is_alphanumeric() && c != '\'') - .filter(|w| !w.is_empty()) - .flat_map(|w| match w.parse::() { - Ok(n) => makepad_ai_speech::g2p::spell_number(n) - .split_whitespace() - .map(str::to_string) - .collect::>(), - Err(_) => vec![w.to_string()], - }) - .collect() -} - -fn word_error(said: &str, heard: &str) -> (usize, usize) { - let reference = normalize(said); - let hypothesis = normalize(heard); - let mut previous: Vec = (0..=hypothesis.len()).collect(); - let mut current = vec![0usize; hypothesis.len() + 1]; - for (i, want) in reference.iter().enumerate() { - current[0] = i + 1; - for (j, got) in hypothesis.iter().enumerate() { - current[j + 1] = (previous[j] + usize::from(want != got)) - .min(current[j] + 1) - .min(previous[j + 1] + 1); - } - std::mem::swap(&mut previous, &mut current); - } - (previous[hypothesis.len()], reference.len()) -} diff --git a/libs/ai/models/speech/src/apple.rs b/libs/ai/models/speech/src/apple.rs deleted file mode 100644 index 1ef275c1b..000000000 --- a/libs/ai/models/speech/src/apple.rs +++ /dev/null @@ -1,48 +0,0 @@ -//! `AVSpeechSynthesizer` rendered to a buffer, via `swift/tts_bridge.swift`. - -use std::ffi::CString; -use std::os::raw::{c_char, c_float, c_int}; - -use crate::SpeechAudio; - -extern "C" { - fn apple_tts_synthesize( - text: *const c_char, - voice: *const c_char, - rate: c_float, - out_len: *mut c_int, - out_rate: *mut c_float, - ) -> *mut c_float; - - fn apple_tts_free(ptr: *mut c_float); -} - -/// Render `text` to mono PCM. `rate` follows `AVSpeechUtterance.rate` -/// (0.5 is the system default); pass `0.0` to leave it alone. -pub fn synthesize(text: &str, voice: Option<&str>, rate: f32) -> Option { - let text = CString::new(text).ok()?; - let voice = voice.and_then(|id| CString::new(id).ok()); - let voice_ptr = voice - .as_ref() - .map_or(std::ptr::null(), |id| id.as_ptr()); - - let mut len: c_int = 0; - let mut sample_rate: c_float = 0.0; - - // Safety: the bridge either returns null or a buffer of `len` floats that it - // allocated and we free below. `text`/`voice` outlive the call. - let samples = unsafe { - let ptr = apple_tts_synthesize(text.as_ptr(), voice_ptr, rate, &mut len, &mut sample_rate); - if ptr.is_null() || len <= 0 { - return None; - } - let samples = std::slice::from_raw_parts(ptr, len as usize).to_vec(); - apple_tts_free(ptr); - samples - }; - - Some(SpeechAudio { - samples, - sample_rate: sample_rate as u32, - }) -} diff --git a/libs/voice/src/bin/metal_strip_unused.rs b/libs/ai/models/speech/src/bin/metal_strip_unused.rs similarity index 100% rename from libs/voice/src/bin/metal_strip_unused.rs rename to libs/ai/models/speech/src/bin/metal_strip_unused.rs diff --git a/libs/ai/models/speech/src/bin/tts_test.rs b/libs/ai/models/speech/src/bin/tts_test.rs index 39f4bd0c0..a39667236 100644 --- a/libs/ai/models/speech/src/bin/tts_test.rs +++ b/libs/ai/models/speech/src/bin/tts_test.rs @@ -1,71 +1,74 @@ -//! Synthesize a sentence and write `tts_test.wav`. +//! Speak a sentence with the Kokoro engine and write it to a WAV. //! -//! cargo run --bin tts_test -- "Hi! I make games with you." +//! cargo run --release --manifest-path libs/ai/models/speech/Cargo.toml --bin tts_test -- "Hello there" [voice.mkvoice] [out.wav] +//! +//! Weights resolve through `MAKEPAD_TTS_MODEL` / the working directory / +//! next to the executable (`kokoro-v1_0.mktts`, `bm_daniel.mkvoice`). -use std::io::Write; - -use makepad_ai_speech::{SpeechAudio, Speaker}; +use makepad_ai_speech::kokoro::{self, KokoroSpeaker}; +use makepad_ai_speech::SpeechAudio; fn main() { let args: Vec = std::env::args().skip(1).collect(); - let text = if args.is_empty() { - "Hi! I make games with you.".to_string() - } else { - args.join(" ") - }; + let text = args.get(0).cloned().unwrap_or_else(|| "Hello from Kokoro.".to_string()); + let out = args.get(2).cloned().unwrap_or_else(|| "tts_test.wav".to_string()); - let mut speaker = Speaker::from_makepad_env(); - println!("backend : {:?}", speaker.kind()); - println!("text : {text:?}"); + let Some(model) = kokoro::model_path_if_present() else { + eprintln!("kokoro weights not found (set MAKEPAD_TTS_MODEL or put {} in the cwd)", kokoro::DEFAULT_MODEL_PATH); + std::process::exit(1); + }; + let voice = match args.get(1) { + Some(name) => kokoro::named_voice_path_if_present(name), + None => kokoro::voice_path_if_present(), + }; + let Some(voice) = voice else { + eprintln!("voice pack not found"); + std::process::exit(1); + }; + let started = std::time::Instant::now(); + let mut speaker = match KokoroSpeaker::load_with_voice(&model, &voice) { + Ok(speaker) => speaker, + Err(err) => { + eprintln!("load failed: {err:?}"); + std::process::exit(1); + } + }; + eprintln!("loaded {model} + {voice} in {:.2}s", started.elapsed().as_secs_f64()); let started = std::time::Instant::now(); - match speaker.synthesize(&text) { - Ok(audio) => { - let elapsed = started.elapsed().as_secs_f32(); - let peak = audio.samples.iter().fold(0.0f32, |m, s| m.max(s.abs())); - println!( - "samples : {} @ {} Hz ({:.2}s audio)", - audio.samples.len(), - audio.sample_rate, - audio.duration_secs() - ); - println!("peak : {peak:.4}"); - println!( - "synth : {:.0} ms ({:.1}x realtime)", - elapsed * 1000.0, - audio.duration_secs() / elapsed.max(1e-6) - ); - match write_wav("tts_test.wav", &audio) { - Ok(()) => println!("wrote : tts_test.wav"), - Err(err) => println!("wav err : {err}"), - } + let audio = match speaker.synthesize(&text) { + Ok(audio) => audio, + Err(err) => { + eprintln!("synthesis failed: {err:?}"); + std::process::exit(1); } - Err(err) => println!("error : {err:?}"), - } + }; + eprintln!( + "rendered {:.2}s of audio in {:.2}s", + audio.duration_secs(), + started.elapsed().as_secs_f64() + ); + std::fs::write(&out, wav_pcm16(&audio)).expect("write wav"); + println!("wrote {out}"); } -/// Minimal 16-bit mono WAV writer. -fn write_wav(path: &str, audio: &SpeechAudio) -> std::io::Result<()> { - let mut file = std::fs::File::create(path)?; +fn wav_pcm16(audio: &SpeechAudio) -> Vec { let data_len = (audio.samples.len() * 2) as u32; - let rate = audio.sample_rate; - - file.write_all(b"RIFF")?; - file.write_all(&(36 + data_len).to_le_bytes())?; - file.write_all(b"WAVEfmt ")?; - file.write_all(&16u32.to_le_bytes())?; // fmt chunk size - file.write_all(&1u16.to_le_bytes())?; // PCM - file.write_all(&1u16.to_le_bytes())?; // mono - file.write_all(&rate.to_le_bytes())?; - file.write_all(&(rate * 2).to_le_bytes())?; // byte rate - file.write_all(&2u16.to_le_bytes())?; // block align - file.write_all(&16u16.to_le_bytes())?; // bits per sample - file.write_all(b"data")?; - file.write_all(&data_len.to_le_bytes())?; - - for sample in &audio.samples { - let clamped = (sample.clamp(-1.0, 1.0) * 32767.0) as i16; - file.write_all(&clamped.to_le_bytes())?; + let mut out = Vec::with_capacity(44 + data_len as usize); + out.extend_from_slice(b"RIFF"); + out.extend_from_slice(&(36 + data_len).to_le_bytes()); + out.extend_from_slice(b"WAVEfmt "); + out.extend_from_slice(&16u32.to_le_bytes()); + out.extend_from_slice(&1u16.to_le_bytes()); + out.extend_from_slice(&1u16.to_le_bytes()); + out.extend_from_slice(&audio.sample_rate.to_le_bytes()); + out.extend_from_slice(&(audio.sample_rate * 2).to_le_bytes()); + out.extend_from_slice(&2u16.to_le_bytes()); + out.extend_from_slice(&16u16.to_le_bytes()); + out.extend_from_slice(b"data"); + out.extend_from_slice(&data_len.to_le_bytes()); + for &s in &audio.samples { + out.extend_from_slice(&((s.clamp(-1.0, 1.0) * 32767.0) as i16).to_le_bytes()); } - Ok(()) + out } diff --git a/libs/voice/src/bin/vad_test.rs b/libs/ai/models/speech/src/bin/vad_test.rs similarity index 98% rename from libs/voice/src/bin/vad_test.rs rename to libs/ai/models/speech/src/bin/vad_test.rs index bb86ab0d3..e76c4c4ee 100644 --- a/libs/voice/src/bin/vad_test.rs +++ b/libs/ai/models/speech/src/bin/vad_test.rs @@ -3,7 +3,7 @@ //! Usage: vad-test [--probs] //! The model resolves via MAKEPAD_VAD_MODEL or ./silero_vad.onnx. -use makepad_voice::{SileroVad, VAD_CHUNK_SAMPLES, VAD_SAMPLE_RATE}; +use makepad_ai_speech::vad::{SileroVad, VAD_CHUNK_SAMPLES, VAD_SAMPLE_RATE}; use std::io::{Read, Seek, SeekFrom}; fn read_wav_pcm_f32(path: &str) -> Vec { diff --git a/libs/voice/src/bin/whisper_parity.rs b/libs/ai/models/speech/src/bin/whisper_parity.rs similarity index 94% rename from libs/voice/src/bin/whisper_parity.rs rename to libs/ai/models/speech/src/bin/whisper_parity.rs index 06b61e930..867310d9c 100644 --- a/libs/voice/src/bin/whisper_parity.rs +++ b/libs/ai/models/speech/src/bin/whisper_parity.rs @@ -1,4 +1,4 @@ -//! GPU-vs-CPU parity harness for `makepad-voice`. +//! GPU-vs-CPU parity harness for the Whisper engine (`makepad_ai_speech::whisper`). //! //! Transcribes one clip twice in a single process — once with the accelerator //! (CUDA on Linux/Windows, Metal on Apple) and once with it forced off — and @@ -20,7 +20,7 @@ //! the run proved nothing). Set `MAKEPAD_VOICE_CUDA_ELEMENTWISE=1` to also put //! the elementwise ops on the device for the accelerated pass. -use makepad_voice::{Segment, WhisperModel, WhisperParams, WhisperState}; +use makepad_ai_speech::whisper::{Segment, WhisperModel, WhisperParams, WhisperState}; use std::io::{Read, Seek, SeekFrom}; fn read_wav_pcm_f32(path: &str) -> Vec { @@ -97,10 +97,10 @@ fn run_once( samples: &[f32], params: &WhisperParams, ) -> Run { - makepad_voice::set_accel_enabled(accel); - let backend = makepad_voice::accel_backend_name(); + makepad_ai_speech::whisper::set_accel_enabled(accel); + let backend = makepad_ai_speech::whisper::accel_backend_name(); // Drop anything a previous pass left behind. - let _ = makepad_voice::take_token_trace(); + let _ = makepad_ai_speech::whisper::take_token_trace(); let mut state = WhisperState::new(model); let t0 = std::time::Instant::now(); @@ -111,7 +111,7 @@ fn run_once( label, backend, seconds, - tokens: makepad_voice::take_token_trace(), + tokens: makepad_ai_speech::whisper::take_token_trace(), segments, } } diff --git a/libs/voice/src/bin/whisper_test.rs b/libs/ai/models/speech/src/bin/whisper_test.rs similarity index 96% rename from libs/voice/src/bin/whisper_test.rs rename to libs/ai/models/speech/src/bin/whisper_test.rs index 96473f0e3..78b6da4f3 100644 --- a/libs/voice/src/bin/whisper_test.rs +++ b/libs/ai/models/speech/src/bin/whisper_test.rs @@ -1,4 +1,4 @@ -use makepad_voice::{WhisperModel, WhisperParams, WhisperState}; +use makepad_ai_speech::whisper::{WhisperModel, WhisperParams, WhisperState}; use std::io::{Read, Seek, SeekFrom}; fn read_wav_pcm_f32(path: &str) -> Vec { @@ -136,7 +136,7 @@ fn main() { for run in 0..bench_repeat { let mut state = WhisperState::new(&model); eprintln!("transcribing run {}/{}...", run + 1, bench_repeat); - makepad_voice::reset_profiling(); + makepad_ai_speech::whisper::reset_profiling(); let t0 = std::time::Instant::now(); let segments = state.transcribe(&model, &samples, ¶ms); let total = t0.elapsed().as_secs_f64(); @@ -146,7 +146,7 @@ fn main() { bench_repeat, total ); - makepad_voice::print_profiling(); + makepad_ai_speech::whisper::print_profiling(); if run + 1 == bench_repeat { for seg in &segments { diff --git a/libs/ai/models/speech/src/convert.rs b/libs/ai/models/speech/src/convert.rs index 6fa7d0011..f52f52cdd 100644 --- a/libs/ai/models/speech/src/convert.rs +++ b/libs/ai/models/speech/src/convert.rs @@ -829,7 +829,9 @@ fn walk( // no torch, network, or checked-in binary is involved. // --------------------------------------------------------------------------- -#[cfg(test)] +// The round trip reads the result back through Kokoro's loader, so these +// tests need that engine compiled in. +#[cfg(all(test, feature = "kokoro"))] mod tests { use super::*; use crate::kokoro::weights::Weights; diff --git a/libs/ai/models/speech/src/lib.rs b/libs/ai/models/speech/src/lib.rs index 946cd0d12..34da21fc2 100644 --- a/libs/ai/models/speech/src/lib.rs +++ b/libs/ai/models/speech/src/lib.rs @@ -1,4 +1,7 @@ -//! Speech family: IndexTTS-2.5 + Kokoro. +//! Speech family: Whisper (speech-to-text), Silero VAD, Kokoro and IndexTTS-2.5 +//! (text-to-speech) — pure engines, audio in / text out and text in / PCM out. +//! No platform code and no device: the OS voices live in +//! makepad-system-speech and the choice between them is makepad-ai-hub's. //! Re-exports the shared exec surface so existing `crate::backend` / //! `crate::emit_progress` / `crate::error` paths inside moved modules //! keep compiling unchanged. @@ -12,21 +15,37 @@ pub use makepad_ai_common::{ BoxedProgressHook, DiffusionError, ProgressHook, Result, BYTE_PROGRESS_STEP, }; -#[cfg(all(any(target_os = "macos", target_os = "ios"), not(no_apple_tts)))] -mod apple; pub mod convert; +#[cfg(feature = "kokoro")] pub mod g2p; +#[cfg(feature = "indextts")] pub mod indextts; +#[cfg(feature = "indextts")] pub mod indextts_bigvgan; +#[cfg(feature = "indextts")] pub mod indextts_campplus; +#[cfg(feature = "indextts")] pub mod indextts_codec; +#[cfg(feature = "indextts")] pub mod indextts_gpt; +#[cfg(feature = "indextts")] pub mod indextts_mel; +#[cfg(feature = "indextts")] pub mod indextts_pipeline; +#[cfg(feature = "indextts")] pub mod indextts_s2mel; +#[cfg(feature = "indextts")] pub mod indextts_tokenizer; +#[cfg(feature = "indextts")] pub mod indextts_w2v; +#[cfg(feature = "kokoro")] pub mod kokoro; pub mod tts; +/// Silero VAD: the 16 kHz speech gate (pure Rust port). +#[cfg(feature = "vad")] +pub mod vad; +/// Whisper speech-to-text (CPU SIMD / Metal / CUDA), formerly `makepad-voice`. +#[cfg(feature = "whisper")] +pub mod whisper; -pub use tts::{Speaker, SpeechAudio, TtsBackend, TtsError}; +pub use tts::{SpeechAudio, TtsError}; diff --git a/libs/ai/models/speech/src/tts.rs b/libs/ai/models/speech/src/tts.rs index b9aaa4441..c089ff33a 100644 --- a/libs/ai/models/speech/src/tts.rs +++ b/libs/ai/models/speech/src/tts.rs @@ -1,7 +1,5 @@ -//! Kokoro / system-voice synthesis engine. Text in, PCM out — the caller -//! owns the audio device. Moved here from `libs/tts` (aiarch.md §1). - -use crate::kokoro; +//! The engine output types: mono PCM plus the synthesis error. Text in, PCM +//! out — the caller owns the audio device. /// Mono PCM produced by a backend. #[derive(Clone, Debug)] @@ -55,108 +53,9 @@ impl SpeechAudio { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum TtsBackend { - /// Kokoro-82M on the Metal/CPU path. - Kokoro, - /// The operating system's own synthesizer. - NativeApple, - /// No synthesizer on this platform; synthesis yields no samples. - Silent, -} - #[derive(Debug)] pub enum TtsError { /// The backend produced nothing for this text. Empty, Backend(String), } - -pub enum Speaker { - Kokoro(kokoro::KokoroSpeaker), - NativeApple, - Silent, -} - -impl Speaker { - /// Prefer Kokoro when its weights are present, else the system voice. - /// - /// Set `MAKEPAD_TTS_MODEL` to point at the weights, or drop them next to the - /// working directory as `kokoro-v1_0.mktts`. - pub fn from_makepad_env() -> Self { - if let Some(path) = kokoro::model_path_if_present() { - match kokoro::KokoroSpeaker::load(&path) { - Ok(speaker) => return Self::Kokoro(speaker), - Err(err) => { - eprintln!("[tts] kokoro weights at '{path}' unusable ({err:?}); falling back"); - } - } - } - Self::default_for_platform() - } - - /// [`Speaker::from_makepad_env`], but preferring a specific voice pack - /// (e.g. `"bm_fable.mkvoice"`). Falls back to the default voice if the - /// named pack is missing; `MAKEPAD_TTS_VOICE` still wins as an override. - pub fn from_makepad_env_with_voice(voice: &str) -> Self { - if let Some(path) = kokoro::model_path_if_present() { - let loaded = match kokoro::named_voice_path_if_present(voice) { - Some(voice_path) => kokoro::KokoroSpeaker::load_with_voice(&path, &voice_path), - None => { - eprintln!("[tts] voice pack '{voice}' not found; using default voice"); - kokoro::KokoroSpeaker::load(&path) - } - }; - match loaded { - Ok(speaker) => return Self::Kokoro(speaker), - Err(err) => { - eprintln!("[tts] kokoro weights at '{path}' unusable ({err:?}); falling back"); - } - } - } - Self::default_for_platform() - } - - pub fn default_for_platform() -> Self { - #[cfg(all(any(target_os = "macos", target_os = "ios"), not(no_apple_tts)))] - { - Self::NativeApple - } - #[cfg(not(all(any(target_os = "macos", target_os = "ios"), not(no_apple_tts))))] - { - Self::Silent - } - } - - pub fn kind(&self) -> TtsBackend { - match self { - Self::Kokoro(_) => TtsBackend::Kokoro, - Self::NativeApple => TtsBackend::NativeApple, - Self::Silent => TtsBackend::Silent, - } - } - - /// Blocking. Returns mono PCM at the backend's native sample rate. - pub fn synthesize(&mut self, text: &str) -> std::result::Result { - if text.trim().is_empty() { - return Err(TtsError::Empty); - } - match self { - Self::Kokoro(speaker) => speaker.synthesize(text), - - #[cfg(all(any(target_os = "macos", target_os = "ios"), not(no_apple_tts)))] - Self::NativeApple => crate::apple::synthesize(text, None, 0.0).ok_or(TtsError::Empty), - - #[cfg(not(all(any(target_os = "macos", target_os = "ios"), not(no_apple_tts))))] - Self::NativeApple => Ok(SpeechAudio::silent()), - - Self::Silent => Ok(SpeechAudio::silent()), - } - } -} - -impl Default for Speaker { - fn default() -> Self { - Self::from_makepad_env() - } -} diff --git a/libs/voice/src/vad.rs b/libs/ai/models/speech/src/vad.rs similarity index 100% rename from libs/voice/src/vad.rs rename to libs/ai/models/speech/src/vad.rs diff --git a/libs/voice/src/accel.rs b/libs/ai/models/speech/src/whisper/accel.rs similarity index 95% rename from libs/voice/src/accel.rs rename to libs/ai/models/speech/src/whisper/accel.rs index 55062440b..37da04f16 100644 --- a/libs/voice/src/accel.rs +++ b/libs/ai/models/speech/src/whisper/accel.rs @@ -28,7 +28,7 @@ //! used by `src/bin/whisper_parity.rs` to run the same audio twice in one //! process. -use crate::model::{DecoderLayer, EncoderLayer}; +use crate::whisper::model::{DecoderLayer, EncoderLayer}; use std::sync::atomic::{AtomicBool, Ordering}; static ENABLED: AtomicBool = AtomicBool::new(true); @@ -51,10 +51,10 @@ pub fn backend_name() -> &'static str { if !on() { return "cpu"; } - if crate::metal_backend::is_requested() { + if crate::whisper::metal_backend::is_requested() { return "metal"; } - if crate::cuda_backend::is_available() { + if crate::whisper::cuda_backend::is_available() { return "cuda"; } "cpu" @@ -64,7 +64,7 @@ pub fn backend_name() -> &'static str { /// between shapes of the same computation (see `src/cpu/decoder.rs`), so it /// must not claim more than [`backend_name`] does. pub(crate) fn is_requested() -> bool { - on() && (crate::metal_backend::is_requested() || crate::cuda_backend::is_available()) + on() && (crate::whisper::metal_backend::is_requested() || crate::whisper::cuda_backend::is_available()) } /// Try Metal, then CUDA. Exactly one of the two is ever non-stub in a given @@ -74,10 +74,10 @@ macro_rules! dispatch { if !on() { return None; } - if let Some(out) = crate::metal_backend::$name($($arg),*) { + if let Some(out) = crate::whisper::metal_backend::$name($($arg),*) { return Some(out); } - crate::cuda_backend::$name($($arg),*) + crate::whisper::cuda_backend::$name($($arg),*) }}; } @@ -181,8 +181,8 @@ pub(crate) fn try_flash_attn_f32_packed( /// harmful, and skipping it while acceleration is off would leave a cache from /// a previous chunk alive for the next one that re-enables it. pub(crate) fn clear_decoder_kv_cache() { - crate::metal_backend::clear_decoder_kv_cache(); - crate::cuda_backend::clear_decoder_kv_cache(); + crate::whisper::metal_backend::clear_decoder_kv_cache(); + crate::whisper::cuda_backend::clear_decoder_kv_cache(); } #[allow(clippy::too_many_arguments)] diff --git a/libs/voice/src/cpu/align.rs b/libs/ai/models/speech/src/whisper/cpu/align.rs similarity index 99% rename from libs/voice/src/cpu/align.rs rename to libs/ai/models/speech/src/whisper/cpu/align.rs index ef054277b..8a30291ee 100644 --- a/libs/voice/src/cpu/align.rs +++ b/libs/ai/models/speech/src/whisper/cpu/align.rs @@ -17,7 +17,7 @@ //! rows are copied out. Everything else — the encoder, the mel front end, //! decoder self-attention — keeps whatever accelerator it had. -use crate::model::WhisperHparams; +use crate::whisper::model::WhisperHparams; /// One encoder position is two 10 ms mel frames. pub const AUDIO_FRAME_MS: i64 = 20; @@ -155,7 +155,7 @@ impl AlignCapture { base_row: usize, n_audio_ctx: usize, ) -> Option { - let ptr = crate::tensor::SendPtr::new(self.rows_ptr()); + let ptr = crate::whisper::tensor::SendPtr::new(self.rows_ptr()); let slots = self.layer_slots(layer)?.to_vec(); Some(CaptureWrite { ptr, @@ -170,7 +170,7 @@ impl AlignCapture { /// See [`AlignCapture::writer`]. pub(crate) struct CaptureWrite { - ptr: crate::tensor::SendPtr, + ptr: crate::whisper::tensor::SendPtr, slots: Vec, n_slots: usize, stride: usize, diff --git a/libs/voice/src/cpu/decode_loop.rs b/libs/ai/models/speech/src/whisper/cpu/decode_loop.rs similarity index 94% rename from libs/voice/src/cpu/decode_loop.rs rename to libs/ai/models/speech/src/whisper/cpu/decode_loop.rs index 359755638..dfdf64126 100644 --- a/libs/voice/src/cpu/decode_loop.rs +++ b/libs/ai/models/speech/src/whisper/cpu/decode_loop.rs @@ -1,7 +1,7 @@ -use crate::decoder::{self, KvCache}; -use crate::encoder; -use crate::mel; -use crate::model::WhisperModel; +use crate::whisper::decoder::{self, KvCache}; +use crate::whisper::encoder; +use crate::whisper::mel; +use crate::whisper::model::WhisperModel; /// A transcribed text segment with timestamps. #[derive(Debug, Clone)] @@ -21,7 +21,7 @@ pub struct AlignedSegment { pub start_ms: i64, pub end_ms: i64, pub text: String, - pub words: Vec, + pub words: Vec, /// The segment's TEXT token ids, in order — what [`WhisperState::force_align`] /// needs to re-align this text against a different (usually narrower) /// window without re-transcribing, and therefore without transcription @@ -115,14 +115,14 @@ impl WhisperState { let _t = std::time::Instant::now(); let (mel_data, _n_mel, n_mel_len, n_mel_len_org) = mel::log_mel_spectrogram(samples, &model.filters, 1); - crate::PROF_MEL.fetch_add( + crate::whisper::PROF_MEL.fetch_add( _t.elapsed().as_nanos() as u64, std::sync::atomic::Ordering::Relaxed, ); let mut segments: Vec = Vec::new(); let mut seek = 0usize; // in mel frames - let heads = align.then(|| crate::align::AlignmentHeads::for_model(&model.hparams)); + let heads = align.then(|| crate::whisper::align::AlignmentHeads::for_model(&model.hparams)); // Use the original (non-30s-padded) mel length as the decode endpoint. let mel_end = n_mel_len_org.min(n_mel_len); @@ -145,7 +145,7 @@ impl WhisperState { // 3. Encode let _t = std::time::Instant::now(); let encoder_out = encoder::encode(model, &mel_chunk, n_ctx); - crate::PROF_ENCODER.fetch_add( + crate::whisper::PROF_ENCODER.fetch_add( _t.elapsed().as_nanos() as u64, std::sync::atomic::Ordering::Relaxed, ); @@ -153,7 +153,7 @@ impl WhisperState { // 4. Pre-compute cross-attention KV let _t = std::time::Instant::now(); let cross_kv = encoder::compute_cross_kv(model, &encoder_out); - crate::PROF_CROSS_KV.fetch_add( + crate::whisper::PROF_CROSS_KV.fetch_add( _t.elapsed().as_nanos() as u64, std::sync::atomic::Ordering::Relaxed, ); @@ -164,7 +164,7 @@ impl WhisperState { // One capture per chunk: rows are appended in decode order, so // row (n_prompt + i) is generated token i. let mut capture = heads.as_ref().map(|heads| { - crate::align::AlignCapture::new( + crate::whisper::align::AlignCapture::new( heads, model.hparams.n_text_layer as usize, model.hparams.n_text_head as usize, @@ -206,11 +206,11 @@ impl WhisperState { &cross_kv, capture.as_mut(), ); - crate::PROF_DECODER.fetch_add( + crate::whisper::PROF_DECODER.fetch_add( _t.elapsed().as_nanos() as u64, std::sync::atomic::Ordering::Relaxed, ); - crate::PROF_DECODER_CALLS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + crate::whisper::PROF_DECODER_CALLS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); decoder::advance_kv_cache(&mut self.kv_cache, n_prompt); // Check no-speech probability @@ -268,11 +268,11 @@ impl WhisperState { &cross_kv, capture.as_mut(), ); - crate::PROF_DECODER.fetch_add( + crate::whisper::PROF_DECODER.fetch_add( _t.elapsed().as_nanos() as u64, std::sync::atomic::Ordering::Relaxed, ); - crate::PROF_DECODER_CALLS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + crate::whisper::PROF_DECODER_CALLS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); decoder::advance_kv_cache(&mut self.kv_cache, 1); let cur_logits = &logits.data[0..n_vocab]; @@ -325,7 +325,7 @@ impl WhisperState { .len() .min(capture.n_rows.saturating_sub(n_prompt_rows)); let n_frames = (mel_end - seek).min(2 * n_ctx).div_ceil(2); - crate::align::align_rows( + crate::whisper::align::align_rows( capture, n_prompt_rows, n_prompt_rows + n_generated, @@ -335,10 +335,10 @@ impl WhisperState { // 8. Convert tokens to segments let chunk_start_ms = (seek as f64 * 10.0) as i64; // mel frames to ms (each frame = 10ms) - let words_for = |tokens: &[(usize, &str)]| -> Vec { + let words_for = |tokens: &[(usize, &str)]| -> Vec { match &alignment { Some(alignment) => { - crate::align::words_from_tokens(tokens, alignment, chunk_start_ms) + crate::whisper::align::words_from_tokens(tokens, alignment, chunk_start_ms) } None => Vec::new(), } @@ -441,7 +441,7 @@ impl WhisperState { samples: &[f32], tokens: &[i32], language: &str, - ) -> Option> { + ) -> Option> { if tokens.is_empty() || samples.is_empty() { return None; } @@ -477,8 +477,8 @@ impl WhisperState { } let positions: Vec = (0..sequence.len() as i32).collect(); - let mut capture = crate::align::AlignCapture::new( - &crate::align::AlignmentHeads::for_model(&model.hparams), + let mut capture = crate::whisper::align::AlignCapture::new( + &crate::whisper::align::AlignmentHeads::for_model(&model.hparams), model.hparams.n_text_layer as usize, model.hparams.n_text_head as usize, n_ctx, @@ -496,7 +496,7 @@ impl WhisperState { let n_frames = n_mel_len_org.min(n_mel_len).min(chunk_len).div_ceil(2); // Rows: [not] + text tokens + [eot]; text rows are offset by one. - let alignment = crate::align::align_rows( + let alignment = crate::whisper::align::align_rows( &capture, n_prompt - 1, n_prompt + tokens.len() + 1, @@ -507,7 +507,7 @@ impl WhisperState { .enumerate() .map(|(index, id)| (index + 1, vocab.token_to_str(*id))) .collect(); - Some(crate::align::words_from_tokens(&texts, &alignment, 0)) + Some(crate::whisper::align::words_from_tokens(&texts, &alignment, 0)) } } @@ -518,7 +518,7 @@ struct TokenData { fn sample_greedy( logits: &[f32], - vocab: &crate::model::Vocab, + vocab: &crate::whisper::model::Vocab, params: &WhisperParams, prev_tokens: &[TokenData], has_ts: bool, @@ -593,7 +593,7 @@ fn sample_greedy( } } - crate::record_token(best_id as i32); + crate::whisper::record_token(best_id as i32); TokenData { id: best_id as i32 } } diff --git a/libs/voice/src/cpu/decoder.rs b/libs/ai/models/speech/src/whisper/cpu/decoder.rs similarity index 95% rename from libs/voice/src/cpu/decoder.rs rename to libs/ai/models/speech/src/whisper/cpu/decoder.rs index 9f36e053d..0d433d1c3 100644 --- a/libs/voice/src/cpu/decoder.rs +++ b/libs/ai/models/speech/src/whisper/cpu/decoder.rs @@ -1,5 +1,5 @@ -use crate::model::WhisperModel; -use crate::tensor::{parallel_for, SendPtr, Tensor}; +use crate::whisper::model::WhisperModel; +use crate::whisper::tensor::{parallel_for, SendPtr, Tensor}; const EPS: f32 = 1e-5; @@ -42,7 +42,7 @@ impl KvCache { v.clear(); } self.n_past = 0; - crate::accel::clear_decoder_kv_cache(); + crate::whisper::accel::clear_decoder_kv_cache(); } /// Append K, V rows for a layer @@ -76,7 +76,7 @@ pub fn decode( positions: &[i32], kv_cache: &mut KvCache, cross_kv: &[(Tensor, Tensor)], - mut capture: Option<&mut crate::align::AlignCapture>, + mut capture: Option<&mut crate::whisper::align::AlignCapture>, ) -> Tensor { let n_tokens = tokens.len(); let n_state = model.hparams.n_text_state as usize; @@ -98,9 +98,9 @@ pub fn decode( let residual = cur.clone(); // Q, K, V projections. - let (q, k_new, v_new) = if crate::accel::is_requested() && n_tokens == 1 { + let (q, k_new, v_new) = if crate::whisper::accel::is_requested() && n_tokens == 1 { if let Some((q_data, k_data, v_data)) = - crate::accel::try_decoder_self_qkv_step_f32( + crate::whisper::accel::try_decoder_self_qkv_step_f32( &cur.data, n_state, &layer.attn_ln_0_w.data, @@ -157,15 +157,15 @@ pub fn decode( let (ref k_cross, ref v_cross) = cross_kv[il]; let n_audio_ctx = k_cross.shape[0]; - let n_audio_ctx_flash = if crate::accel::is_requested() && n_tokens == 1 { + let n_audio_ctx_flash = if crate::whisper::accel::is_requested() && n_tokens == 1 { pad_to(n_audio_ctx, 256) } else { n_audio_ctx }; let scale = 1.0 / (n_state_head as f32).sqrt(); - if crate::accel::is_requested() && n_tokens == 1 && !capturing { - if let Some(out) = crate::accel::try_decoder_self_cross_ffn_step_f32( + if crate::whisper::accel::is_requested() && n_tokens == 1 && !capturing { + if let Some(out) = crate::whisper::accel::try_decoder_self_cross_ffn_step_f32( il, &residual.data, &q.data, @@ -187,8 +187,8 @@ pub fn decode( } } - let attn_out = if crate::accel::is_requested() && n_tokens == 1 { - crate::accel::try_flash_attn_f32_self_kv_cache( + let attn_out = if crate::whisper::accel::is_requested() && n_tokens == 1 { + crate::whisper::accel::try_flash_attn_f32_self_kv_cache( il, &q.data, k_all, @@ -199,7 +199,7 @@ pub fn decode( scale, ) .or_else(|| { - crate::accel::try_flash_attn_f32_packed( + crate::whisper::accel::try_flash_attn_f32_packed( &q.data, k_all, v_all, @@ -373,8 +373,8 @@ pub fn decode( let projected = Tensor::linear_raw(&attn_result, &layer.attn_ln_1_w, &layer.attn_ln_1_b); cur = Tensor::add(&projected, &residual); - if crate::accel::is_requested() && n_tokens == 1 && !capturing { - if let Some(out) = crate::accel::try_decoder_cross_ffn_step_f32( + if crate::whisper::accel::is_requested() && n_tokens == 1 && !capturing { + if let Some(out) = crate::whisper::accel::try_decoder_cross_ffn_step_f32( il, &cur.data, n_state, @@ -406,8 +406,8 @@ pub fn decode( let scale = 1.0 / (n_state_head as f32).sqrt(); - let attn_out = if crate::accel::is_requested() && n_tokens == 1 && !capturing { - crate::accel::try_flash_attn_f32_cross_kv_cache( + let attn_out = if crate::whisper::accel::is_requested() && n_tokens == 1 && !capturing { + crate::whisper::accel::try_flash_attn_f32_cross_kv_cache( il, &q.data, &k_cross.data, @@ -419,7 +419,7 @@ pub fn decode( scale, ) .or_else(|| { - crate::accel::try_flash_attn_f32_packed( + crate::whisper::accel::try_flash_attn_f32_packed( &q.data, &k_cross.data, &v_cross.data, diff --git a/libs/voice/src/cpu/encoder.rs b/libs/ai/models/speech/src/whisper/cpu/encoder.rs similarity index 89% rename from libs/voice/src/cpu/encoder.rs rename to libs/ai/models/speech/src/whisper/cpu/encoder.rs index 998bb9dc0..4e86505ef 100644 --- a/libs/voice/src/cpu/encoder.rs +++ b/libs/ai/models/speech/src/whisper/cpu/encoder.rs @@ -1,5 +1,5 @@ -use crate::model::WhisperModel; -use crate::tensor::{parallel_for, RawTensor, Tensor}; +use crate::whisper::model::WhisperModel; +use crate::whisper::tensor::{parallel_for, RawTensor, Tensor}; const EPS: f32 = 1e-5; @@ -33,8 +33,8 @@ fn multi_head_attention( let k = Tensor::matmul_raw_with_prequant(x, k_w, xq.as_deref()); let v = Tensor::linear_raw_with_prequant(x, v_w, xq.as_deref(), v_b); - if crate::accel::is_requested() { - if let Some(out) = crate::accel::try_flash_attn_f32_packed( + if crate::whisper::accel::is_requested() { + if let Some(out) = crate::whisper::accel::try_flash_attn_f32_packed( &q.data, &k.data, &v.data, @@ -54,7 +54,7 @@ fn multi_head_attention( } let mut out = vec![0.0f32; seq_len * n_state]; - let out_ptr = crate::tensor::SendPtr::new(out.as_mut_ptr()); + let out_ptr = crate::whisper::tensor::SendPtr::new(out.as_mut_ptr()); let q_data = &q.data; let k_data = &k.data; let v_data = &v.data; @@ -147,7 +147,7 @@ pub fn encode(model: &WhisperModel, mel_data: &[f32], n_ctx: usize) -> Tensor { // Conv2 + GELU: [n_state, 2*n_ctx] -> [n_state, n_ctx] (stride 2) cur = Tensor::conv1d_raw(&cur, &model.e_conv_2_w, &model.e_conv_2_b, 2); cur = Tensor::gelu(&cur); - crate::PROF_ENC_CONV.fetch_add( + crate::whisper::PROF_ENC_CONV.fetch_add( _tc.elapsed().as_nanos() as u64, std::sync::atomic::Ordering::Relaxed, ); @@ -164,9 +164,9 @@ pub fn encode(model: &WhisperModel, mel_data: &[f32], n_ctx: usize) -> Tensor { }; cur = Tensor::add(&cur, &pe); - if crate::accel::is_requested() { + if crate::whisper::accel::is_requested() { let t_stack = std::time::Instant::now(); - if let Some(out) = crate::accel::try_encoder_stack_f32( + if let Some(out) = crate::whisper::accel::try_encoder_stack_f32( &cur.data, cur.shape[0], cur.shape[1], @@ -176,8 +176,8 @@ pub fn encode(model: &WhisperModel, mel_data: &[f32], n_ctx: usize) -> Tensor { &model.e_ln_b.data, ) { let dt = t_stack.elapsed().as_nanos() as u64; - crate::PROF_ENC_ATTN.fetch_add(dt / 2, std::sync::atomic::Ordering::Relaxed); - crate::PROF_ENC_ELEM.fetch_add(dt - dt / 2, std::sync::atomic::Ordering::Relaxed); + crate::whisper::PROF_ENC_ATTN.fetch_add(dt / 2, std::sync::atomic::Ordering::Relaxed); + crate::whisper::PROF_ENC_ELEM.fetch_add(dt - dt / 2, std::sync::atomic::Ordering::Relaxed); return Tensor { data: out, shape: cur.shape.clone(), @@ -187,9 +187,9 @@ pub fn encode(model: &WhisperModel, mel_data: &[f32], n_ctx: usize) -> Tensor { // Transformer encoder blocks for layer in &model.encoder_layers { - if crate::accel::is_requested() { + if crate::whisper::accel::is_requested() { let t_layer = std::time::Instant::now(); - if let Some(out) = crate::accel::try_encoder_layer_f32( + if let Some(out) = crate::whisper::accel::try_encoder_layer_f32( &cur.data, cur.shape[0], cur.shape[1], @@ -221,8 +221,8 @@ pub fn encode(model: &WhisperModel, mel_data: &[f32], n_ctx: usize) -> Tensor { shape: cur.shape.clone(), }; let dt = t_layer.elapsed().as_nanos() as u64; - crate::PROF_ENC_ATTN.fetch_add(dt / 2, std::sync::atomic::Ordering::Relaxed); - crate::PROF_ENC_ELEM.fetch_add(dt - dt / 2, std::sync::atomic::Ordering::Relaxed); + crate::whisper::PROF_ENC_ATTN.fetch_add(dt / 2, std::sync::atomic::Ordering::Relaxed); + crate::whisper::PROF_ENC_ELEM.fetch_add(dt - dt / 2, std::sync::atomic::Ordering::Relaxed); continue; } } @@ -230,8 +230,8 @@ pub fn encode(model: &WhisperModel, mel_data: &[f32], n_ctx: usize) -> Tensor { // Self-attention block let t_attn = std::time::Instant::now(); let mut attn_done = false; - if crate::accel::is_requested() { - if let Some(out) = crate::accel::try_encoder_attn_block_f32( + if crate::whisper::accel::is_requested() { + if let Some(out) = crate::whisper::accel::try_encoder_attn_block_f32( &cur.data, cur.shape[0], cur.shape[1], @@ -279,7 +279,7 @@ pub fn encode(model: &WhisperModel, mel_data: &[f32], n_ctx: usize) -> Tensor { cur = Tensor::add(&attn_out, &residual); } - crate::PROF_ENC_ATTN.fetch_add( + crate::whisper::PROF_ENC_ATTN.fetch_add( t_attn.elapsed().as_nanos() as u64, std::sync::atomic::Ordering::Relaxed, ); @@ -287,8 +287,8 @@ pub fn encode(model: &WhisperModel, mel_data: &[f32], n_ctx: usize) -> Tensor { // Feed-forward block let t_elem = std::time::Instant::now(); let mut ffn_done = false; - if crate::accel::is_requested() { - if let Some(out) = crate::accel::try_encoder_ffn_block_f32( + if crate::whisper::accel::is_requested() { + if let Some(out) = crate::whisper::accel::try_encoder_ffn_block_f32( &cur.data, cur.shape[0], cur.shape[1], @@ -320,7 +320,7 @@ pub fn encode(model: &WhisperModel, mel_data: &[f32], n_ctx: usize) -> Tensor { cur = Tensor::add(&ff, &residual); } - crate::PROF_ENC_ELEM.fetch_add( + crate::whisper::PROF_ENC_ELEM.fetch_add( t_elem.elapsed().as_nanos() as u64, std::sync::atomic::Ordering::Relaxed, ); diff --git a/libs/voice/src/cpu/mel.rs b/libs/ai/models/speech/src/whisper/cpu/mel.rs similarity index 99% rename from libs/voice/src/cpu/mel.rs rename to libs/ai/models/speech/src/whisper/cpu/mel.rs index aad42f228..ca06a21de 100644 --- a/libs/voice/src/cpu/mel.rs +++ b/libs/ai/models/speech/src/whisper/cpu/mel.rs @@ -1,4 +1,4 @@ -use crate::model::MelFilters; +use crate::whisper::model::MelFilters; pub const WHISPER_SAMPLE_RATE: usize = 16000; pub const WHISPER_N_FFT: usize = 400; diff --git a/libs/voice/src/cpu/model.rs b/libs/ai/models/speech/src/whisper/cpu/model.rs similarity index 99% rename from libs/voice/src/cpu/model.rs rename to libs/ai/models/speech/src/whisper/cpu/model.rs index fe8b1f83c..1b41dd628 100644 --- a/libs/voice/src/cpu/model.rs +++ b/libs/ai/models/speech/src/whisper/cpu/model.rs @@ -1,12 +1,12 @@ -use crate::quant::*; -use crate::tensor::{RawTensor, Tensor}; +use crate::whisper::quant::*; +use crate::whisper::tensor::{RawTensor, Tensor}; use std::collections::HashMap; use std::io::{self, Read, Seek}; const GGML_FILE_MAGIC: u32 = 0x67676d6c; fn should_preserve_raw_weight_type() -> bool { - crate::settings::PRESERVE_RAW_WEIGHT_TYPE + crate::whisper::settings::PRESERVE_RAW_WEIGHT_TYPE } #[derive(Debug, Clone)] diff --git a/libs/voice/src/cpu/quant.rs b/libs/ai/models/speech/src/whisper/cpu/quant.rs similarity index 100% rename from libs/voice/src/cpu/quant.rs rename to libs/ai/models/speech/src/whisper/cpu/quant.rs diff --git a/libs/voice/src/cpu/tensor.rs b/libs/ai/models/speech/src/whisper/cpu/tensor.rs similarity index 96% rename from libs/voice/src/cpu/tensor.rs rename to libs/ai/models/speech/src/whisper/cpu/tensor.rs index 90ce414ae..f35bce5a4 100644 --- a/libs/voice/src/cpu/tensor.rs +++ b/libs/ai/models/speech/src/whisper/cpu/tensor.rs @@ -1,4 +1,4 @@ -use crate::quant::*; +use crate::whisper::quant::*; use std::cell::RefCell; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Condvar, Mutex}; @@ -8,7 +8,7 @@ thread_local! { } fn quant_gpu_enabled() -> bool { - crate::settings::ENABLE_METAL_QUANT + crate::whisper::settings::ENABLE_METAL_QUANT } /// Wrapper to pass raw *mut f32 across thread boundaries. @@ -172,7 +172,7 @@ fn get_pool() -> &'static ThreadPool { #[inline] fn use_act_q8() -> bool { - crate::settings::ENABLE_ACT_Q8 + crate::whisper::settings::ENABLE_ACT_Q8 } /// Run `n_jobs` tasks in parallel, each receiving its job index. @@ -644,7 +644,7 @@ impl Tensor { /// out = a + b (broadcasting b if it's smaller) pub fn add(a: &Tensor, b: &Tensor) -> Tensor { - if let Some(out) = crate::accel::try_add_f32(&a.data, &a.shape, &b.data, &b.shape) { + if let Some(out) = crate::whisper::accel::try_add_f32(&a.data, &a.shape, &b.data, &b.shape) { return Tensor { data: out, shape: a.shape.clone(), @@ -682,7 +682,7 @@ impl Tensor { /// out = a * b element-wise (broadcasting b) pub fn mul(a: &Tensor, b: &Tensor) -> Tensor { - if let Some(out) = crate::accel::try_mul_f32(&a.data, &a.shape, &b.data, &b.shape) { + if let Some(out) = crate::whisper::accel::try_mul_f32(&a.data, &a.shape, &b.data, &b.shape) { return Tensor { data: out, shape: a.shape.clone(), @@ -726,7 +726,7 @@ impl Tensor { /// GELU activation: x * 0.5 * (1 + tanh(sqrt(2/pi) * (x + 0.044715 * x^3))) pub fn gelu(a: &Tensor) -> Tensor { - if let Some(out) = crate::accel::try_gelu_f32(&a.data, &a.shape) { + if let Some(out) = crate::whisper::accel::try_gelu_f32(&a.data, &a.shape) { return Tensor { data: out, shape: a.shape.clone(), @@ -751,7 +751,7 @@ impl Tensor { /// Layer normalization along the last dimension. /// out[i] = (x[i] - mean) / sqrt(var + eps) pub fn layer_norm(x: &Tensor, eps: f32) -> Tensor { - if let Some(out) = crate::accel::try_layer_norm_f32(&x.data, &x.shape, eps) { + if let Some(out) = crate::whisper::accel::try_layer_norm_f32(&x.data, &x.shape, eps) { return Tensor { data: out, shape: x.shape.clone(), @@ -784,7 +784,7 @@ impl Tensor { /// Layer normalization followed by affine transform. /// out = layer_norm(x, eps) * mul + add pub fn layer_norm_mul_add(x: &Tensor, mul: &Tensor, add: &Tensor, eps: f32) -> Tensor { - if let Some(out) = crate::accel::try_layer_norm_mul_add_f32( + if let Some(out) = crate::whisper::accel::try_layer_norm_mul_add_f32( &x.data, &x.shape, &mul.data, &mul.shape, &add.data, &add.shape, eps, ) { return Tensor { @@ -928,7 +928,7 @@ impl Tensor { assert_eq!(b.shape[0], k); let n = b.shape[1]; - if let Some(out) = crate::accel::try_matmul_nn_f32(&a.data, &b.data, m, k, n) { + if let Some(out) = crate::whisper::accel::try_matmul_nn_f32(&a.data, &b.data, m, k, n) { return Tensor { data: out, shape: vec![m, n], @@ -968,18 +968,18 @@ impl Tensor { let batch = x.numel() / in_features; assert_eq!(x.numel(), batch * in_features, "matmul_t: x size mismatch"); - if let Some(out) = crate::accel::try_matmul_nt_f32( + if let Some(out) = crate::whisper::accel::try_matmul_nt_f32( &x.data, &w.data, batch, in_features, out_features, ) { - crate::PROF_MATMUL_T.fetch_add( + crate::whisper::PROF_MATMUL_T.fetch_add( _t.elapsed().as_nanos() as u64, std::sync::atomic::Ordering::Relaxed, ); - crate::PROF_MATMUL_T_CALLS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + crate::whisper::PROF_MATMUL_T_CALLS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); return Tensor { data: out, shape: vec![batch, out_features], @@ -1000,11 +1000,11 @@ impl Tensor { } }); - crate::PROF_MATMUL_T.fetch_add( + crate::whisper::PROF_MATMUL_T.fetch_add( _t.elapsed().as_nanos() as u64, std::sync::atomic::Ordering::Relaxed, ); - crate::PROF_MATMUL_T_CALLS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + crate::whisper::PROF_MATMUL_T_CALLS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); Tensor { data: out, shape: vec![batch, out_features], @@ -1071,7 +1071,7 @@ impl Tensor { ); if bias.numel() == out_features { - if let Some(out) = crate::accel::try_matmul_nt_ggml_bytes_add_bias( + if let Some(out) = crate::whisper::accel::try_matmul_nt_ggml_bytes_add_bias( &x.data, &weight.data, weight.ggml_type, @@ -1107,7 +1107,7 @@ impl Tensor { ); if bias.numel() == out_features { - if let Some(out) = crate::accel::try_matmul_nt_ggml_bytes_add_bias( + if let Some(out) = crate::whisper::accel::try_matmul_nt_ggml_bytes_add_bias( &x.data, &weight.data, weight.ggml_type, @@ -1144,36 +1144,36 @@ impl Tensor { ); if weight.ggml_type == GGML_TYPE_F32 { - if let Some(out) = crate::accel::try_matmul_nt_f32_bytes( + if let Some(out) = crate::whisper::accel::try_matmul_nt_f32_bytes( &x.data, &weight.data, batch, in_features, out_features, ) { - crate::PROF_MATMUL_RAW.fetch_add( + crate::whisper::PROF_MATMUL_RAW.fetch_add( _t.elapsed().as_nanos() as u64, std::sync::atomic::Ordering::Relaxed, ); - crate::PROF_MATMUL_RAW_CALLS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + crate::whisper::PROF_MATMUL_RAW_CALLS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); return Tensor { data: out, shape: vec![batch, out_features], }; } } else if weight.ggml_type == GGML_TYPE_F16 { - if let Some(out) = crate::accel::try_matmul_nt_f16_bytes( + if let Some(out) = crate::whisper::accel::try_matmul_nt_f16_bytes( &x.data, &weight.data, batch, in_features, out_features, ) { - crate::PROF_MATMUL_RAW.fetch_add( + crate::whisper::PROF_MATMUL_RAW.fetch_add( _t.elapsed().as_nanos() as u64, std::sync::atomic::Ordering::Relaxed, ); - crate::PROF_MATMUL_RAW_CALLS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + crate::whisper::PROF_MATMUL_RAW_CALLS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); return Tensor { data: out, shape: vec![batch, out_features], @@ -1183,7 +1183,7 @@ impl Tensor { match weight.ggml_type { GGML_TYPE_Q4_0 | GGML_TYPE_Q4_1 | GGML_TYPE_Q5_0 | GGML_TYPE_Q5_1 | GGML_TYPE_Q8_0 => { - if let Some(out) = crate::accel::try_matmul_nt_ggml_bytes( + if let Some(out) = crate::whisper::accel::try_matmul_nt_ggml_bytes( &x.data, &weight.data, weight.ggml_type, @@ -1191,11 +1191,11 @@ impl Tensor { in_features, out_features, ) { - crate::PROF_MATMUL_RAW.fetch_add( + crate::whisper::PROF_MATMUL_RAW.fetch_add( _t.elapsed().as_nanos() as u64, std::sync::atomic::Ordering::Relaxed, ); - crate::PROF_MATMUL_RAW_CALLS + crate::whisper::PROF_MATMUL_RAW_CALLS .fetch_add(1, std::sync::atomic::Ordering::Relaxed); return Tensor { data: out, @@ -1608,11 +1608,11 @@ impl Tensor { } } - crate::PROF_MATMUL_RAW.fetch_add( + crate::whisper::PROF_MATMUL_RAW.fetch_add( _t.elapsed().as_nanos() as u64, std::sync::atomic::Ordering::Relaxed, ); - crate::PROF_MATMUL_RAW_CALLS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + crate::whisper::PROF_MATMUL_RAW_CALLS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); Tensor { data: out, shape: vec![batch, out_features], @@ -1633,11 +1633,11 @@ impl Tensor { let out_len = (in_len + 2 * pad - ksize) / stride + 1; if let Some(im2col) = - crate::accel::try_im2col_1d_f32(&input.data, ch_in, in_len, ksize, stride, pad) + crate::whisper::accel::try_im2col_1d_f32(&input.data, ch_in, in_len, ksize, stride, pad) { let k = ch_in * ksize; if let Some(mm_out) = - crate::accel::try_matmul_nt_f32(&im2col, &weight.data, out_len, k, ch_out) + crate::whisper::accel::try_matmul_nt_f32(&im2col, &weight.data, out_len, k, ch_out) { let mut out = vec![0.0f32; ch_out * out_len]; let out_ptr = SendPtr::new(out.as_mut_ptr()); @@ -1702,7 +1702,7 @@ impl Tensor { let pad = ksize / 2; let out_len = (in_len + 2 * pad - ksize) / stride + 1; - if let Some(im2col) = crate::accel::try_im2col_1d_f32( + if let Some(im2col) = crate::whisper::accel::try_im2col_1d_f32( &input.data, ch_in, in_len, @@ -1712,14 +1712,14 @@ impl Tensor { ) { let k = ch_in * ksize; let mm_out = match weight.ggml_type { - GGML_TYPE_F32 => crate::accel::try_matmul_nt_f32_bytes( + GGML_TYPE_F32 => crate::whisper::accel::try_matmul_nt_f32_bytes( &im2col, &weight.data, out_len, k, ch_out, ), - GGML_TYPE_F16 => crate::accel::try_matmul_nt_f16_bytes( + GGML_TYPE_F16 => crate::whisper::accel::try_matmul_nt_f16_bytes( &im2col, &weight.data, out_len, @@ -1730,7 +1730,7 @@ impl Tensor { | GGML_TYPE_Q8_0 if quant_gpu_enabled() => { - crate::accel::try_matmul_nt_ggml_bytes( + crate::whisper::accel::try_matmul_nt_ggml_bytes( &im2col, &weight.data, weight.ggml_type, diff --git a/libs/voice/src/cuda/backend.rs b/libs/ai/models/speech/src/whisper/cuda/backend.rs similarity index 98% rename from libs/voice/src/cuda/backend.rs rename to libs/ai/models/speech/src/whisper/cuda/backend.rs index bf8f6319f..88c4bea32 100644 --- a/libs/voice/src/cuda/backend.rs +++ b/libs/ai/models/speech/src/whisper/cuda/backend.rs @@ -46,7 +46,7 @@ //! Resident f32 weights cost 4 bytes/parameter: ~300 MB for `base`, ~1 GB for //! `small`, ~3.2 GB for `large-v3-turbo`, ~6.2 GB for `large-v3`. -use crate::model::{DecoderLayer, EncoderLayer}; +use crate::whisper::model::{DecoderLayer, EncoderLayer}; /// `MAKEPAD_VOICE_CUDA=0|false|no|off` forces this backend off entirely. fn env_off(name: &str) -> bool { @@ -217,7 +217,7 @@ fn fingerprint_f32(values: &[f32]) -> u64 { /// types the CPU path does not produce either. #[allow(dead_code)] fn dequant_to_f32(bytes: &[u8], ggml_type: u32, n_elements: usize) -> Option> { - use crate::quant::*; + use crate::whisper::quant::*; let mut out = vec![0.0f32; n_elements]; match ggml_type { GGML_TYPE_F32 => { @@ -356,7 +356,7 @@ pub(crate) fn try_matmul_nt_f32_bytes( k: usize, n: usize, ) -> Option> { - matmul_nt_bytes(a, bt_bytes, crate::quant::GGML_TYPE_F32, m, k, n, None) + matmul_nt_bytes(a, bt_bytes, crate::whisper::quant::GGML_TYPE_F32, m, k, n, None) } pub(crate) fn try_matmul_nt_f16_bytes( @@ -366,7 +366,7 @@ pub(crate) fn try_matmul_nt_f16_bytes( k: usize, n: usize, ) -> Option> { - matmul_nt_bytes(a, bt_f16_bytes, crate::quant::GGML_TYPE_F16, m, k, n, None) + matmul_nt_bytes(a, bt_f16_bytes, crate::whisper::quant::GGML_TYPE_F16, m, k, n, None) } pub(crate) fn try_matmul_nt_ggml_bytes( @@ -1079,7 +1079,7 @@ mod imp { #[cfg(test)] mod tests { use super::*; - use crate::tensor::Tensor; + use crate::whisper::tensor::Tensor; /// `im2col_1d` + a plain NT matmul must reproduce `Tensor::conv1d` exactly. /// This is the contract the CUDA conv path relies on, and it is checkable @@ -1132,7 +1132,7 @@ mod tests { #[test] fn dequant_f32_and_f16_roundtrip() { - use crate::quant::{f32_to_f16, GGML_TYPE_F16, GGML_TYPE_F32}; + use crate::whisper::quant::{f32_to_f16, GGML_TYPE_F16, GGML_TYPE_F32}; let values: Vec = (0..64).map(|i| (i as f32) * 0.25 - 8.0).collect(); let mut f32_bytes = Vec::new(); @@ -1156,8 +1156,8 @@ mod tests { /// because the CPU fallback and the device path must see the same weights. #[test] fn dequant_matches_raw_tensor_to_f32() { - use crate::quant::{quantize_f32_to_q8_0, GGML_TYPE_Q8_0}; - use crate::tensor::RawTensor; + use crate::whisper::quant::{quantize_f32_to_q8_0, GGML_TYPE_Q8_0}; + use crate::whisper::tensor::RawTensor; let values: Vec = (0..256).map(|i| ((i * 37 % 91) as f32) * 0.13 - 5.0).collect(); let q8 = quantize_f32_to_q8_0(&values); diff --git a/libs/voice/src/metal/backend.rs b/libs/ai/models/speech/src/whisper/metal/backend.rs similarity index 99% rename from libs/voice/src/metal/backend.rs rename to libs/ai/models/speech/src/whisper/metal/backend.rs index ce19e4122..e0aae1e52 100644 --- a/libs/voice/src/metal/backend.rs +++ b/libs/ai/models/speech/src/whisper/metal/backend.rs @@ -7,11 +7,11 @@ fn log_metal_trace() -> bool { #[allow(dead_code)] fn log_mul_mat_requested() -> bool { - crate::settings::LOG_METAL_MUL_MAT || log_metal_trace() + crate::whisper::settings::LOG_METAL_MUL_MAT || log_metal_trace() } fn metal_requested() -> bool { - crate::settings::USE_METAL_BACKEND + crate::whisper::settings::USE_METAL_BACKEND } pub(crate) fn try_matmul_nn_f32( @@ -361,7 +361,7 @@ pub(crate) fn try_encoder_stack_f32( seq_len: usize, n_state: usize, n_head: usize, - layers: &[crate::model::EncoderLayer], + layers: &[crate::whisper::model::EncoderLayer], final_ln_w: &[f32], final_ln_b: &[f32], ) -> Option> { @@ -414,7 +414,7 @@ pub(crate) fn try_decoder_cross_ffn_step_f32( k_cross: &[f32], v_cross: &[f32], n_audio_ctx: usize, - layer: &crate::model::DecoderLayer, + layer: &crate::whisper::model::DecoderLayer, ) -> Option> { if !metal_requested() { return None; @@ -444,7 +444,7 @@ pub(crate) fn try_decoder_self_cross_ffn_step_f32( k_cross: &[f32], v_cross: &[f32], n_audio_ctx: usize, - layer: &crate::model::DecoderLayer, + layer: &crate::whisper::model::DecoderLayer, ) -> Option> { if !metal_requested() { return None; @@ -703,7 +703,7 @@ mod imp { _seq_len: usize, _n_state: usize, _n_head: usize, - _layers: &[crate::model::EncoderLayer], + _layers: &[crate::whisper::model::EncoderLayer], _final_ln_w: &[f32], _final_ln_b: &[f32], ) -> Option> { @@ -737,7 +737,7 @@ mod imp { _k_cross: &[f32], _v_cross: &[f32], _n_audio_ctx: usize, - _layer: &crate::model::DecoderLayer, + _layer: &crate::whisper::model::DecoderLayer, ) -> Option> { None } @@ -755,7 +755,7 @@ mod imp { _k_cross: &[f32], _v_cross: &[f32], _n_audio_ctx: usize, - _layer: &crate::model::DecoderLayer, + _layer: &crate::whisper::model::DecoderLayer, ) -> Option> { None } @@ -763,8 +763,8 @@ mod imp { #[cfg(target_os = "macos")] mod imp { - use crate::model::{DecoderLayer, EncoderLayer}; - use crate::quant::{ + use crate::whisper::model::{DecoderLayer, EncoderLayer}; + use crate::whisper::quant::{ block_size, f32_to_f16, GGML_TYPE_F16, GGML_TYPE_F32, GGML_TYPE_Q4_0, GGML_TYPE_Q4_1, GGML_TYPE_Q5_0, GGML_TYPE_Q5_1, GGML_TYPE_Q8_0, }; @@ -1277,16 +1277,16 @@ mod imp { fn metal_compile_feature_macros(device: ObjcId) -> (bool, bool) { let mut has_bfloat = device_supports_family(device, MTL_GPU_FAMILY_METAL3) || device_supports_family(device, MTL_GPU_FAMILY_APPLE6); - if crate::settings::DISABLE_GGML_METAL_BF16 { + if crate::whisper::settings::DISABLE_GGML_METAL_BF16 { has_bfloat = false; } let mut has_tensor = device_supports_family(device, MTL_GPU_FAMILY_METAL4); - if crate::settings::DISABLE_GGML_METAL_TENSOR { + if crate::whisper::settings::DISABLE_GGML_METAL_TENSOR { has_tensor = false; } - if !crate::settings::FORCE_ENABLE_GGML_METAL_TENSOR && has_tensor { + if !crate::whisper::settings::FORCE_ENABLE_GGML_METAL_TENSOR && has_tensor { let dev_name_obj: ObjcId = unsafe { msg_send![device, name] }; let dev_name = nsstring_to_string(dev_name_obj); let tensor_whitelisted = dev_name.contains("M5") @@ -2458,7 +2458,7 @@ mod imp { nsg: i32, ) -> Result<(ObjcId, usize, i32, i32, i32), String> { if !self.pipeline_cache.contains_key(&cache_name) { - if crate::settings::LOG_METAL_PIPELINES { + if crate::whisper::settings::LOG_METAL_PIPELINES { eprintln!("[voice][metal] compile_pipeline base={}", base_name); } let compiled = self.compile_pipeline(base_name, constants)?; diff --git a/libs/voice/src/metal/ggml/LICENSE b/libs/ai/models/speech/src/whisper/metal/ggml/LICENSE similarity index 100% rename from libs/voice/src/metal/ggml/LICENSE rename to libs/ai/models/speech/src/whisper/metal/ggml/LICENSE diff --git a/libs/voice/src/metal/ggml/ggml-common.h b/libs/ai/models/speech/src/whisper/metal/ggml/ggml-common.h similarity index 100% rename from libs/voice/src/metal/ggml/ggml-common.h rename to libs/ai/models/speech/src/whisper/metal/ggml/ggml-common.h diff --git a/libs/voice/src/metal/ggml/ggml-metal-impl.h b/libs/ai/models/speech/src/whisper/metal/ggml/ggml-metal-impl.h similarity index 100% rename from libs/voice/src/metal/ggml/ggml-metal-impl.h rename to libs/ai/models/speech/src/whisper/metal/ggml/ggml-metal-impl.h diff --git a/libs/voice/src/metal/ggml/ggml-metal.metal b/libs/ai/models/speech/src/whisper/metal/ggml/ggml-metal.metal similarity index 100% rename from libs/voice/src/metal/ggml/ggml-metal.metal rename to libs/ai/models/speech/src/whisper/metal/ggml/ggml-metal.metal diff --git a/libs/voice/src/lib.rs b/libs/ai/models/speech/src/whisper/mod.rs similarity index 90% rename from libs/voice/src/lib.rs rename to libs/ai/models/speech/src/whisper/mod.rs index cbd3b03be..076bb2160 100644 --- a/libs/voice/src/lib.rs +++ b/libs/ai/models/speech/src/whisper/mod.rs @@ -20,25 +20,11 @@ mod quant; mod settings; #[path = "cpu/tensor.rs"] mod tensor; -mod transcriber; -mod vad; - -#[cfg(all(any(target_os = "macos", target_os = "ios"), not(force_whisper)))] -#[path = "apple/speech.rs"] -pub mod apple_speech; pub use accel::{backend_name as accel_backend_name, set_enabled as set_accel_enabled}; pub use align::{AlignmentHeads, WordSpan, AUDIO_FRAME_MS}; pub use decode_loop::{AlignedSegment, Segment, WhisperParams, WhisperState}; pub use model::WhisperModel; -pub use transcriber::{ - NativeAppleTranscriber, VoiceBackendKind, VoiceTranscribeError, VoiceTranscribeParams, - VoiceTranscriber, WhisperTranscriber, -}; -pub use vad::{ - vad_model_path_if_present, SileroVad, VadError, VadStream, VAD_CHUNK_SAMPLES, - VAD_SAMPLE_RATE, -}; use std::sync::atomic::{AtomicU64, Ordering}; diff --git a/libs/voice/src/settings.rs b/libs/ai/models/speech/src/whisper/settings.rs similarity index 100% rename from libs/voice/src/settings.rs rename to libs/ai/models/speech/src/whisper/settings.rs diff --git a/libs/ai/models/speech/swift/tts_bridge.swift b/libs/ai/models/speech/swift/tts_bridge.swift deleted file mode 100644 index f3be07a27..000000000 --- a/libs/ai/models/speech/swift/tts_bridge.swift +++ /dev/null @@ -1,98 +0,0 @@ -import AVFoundation -import Foundation - -/// Accumulates the PCM the synthesizer hands back, buffer by buffer. -private final class Rendered { - var samples: [Float] = [] - var sampleRate: Double = 0 -} - -/// Render `text` to mono float PCM and return an owned buffer. -/// -/// Returns null on failure. The caller must release the result with -/// `apple_tts_free`. Unlike `AVSpeechSynthesizer.speak`, this never touches an -/// output device — the samples go back to Rust so Makepad's audio output owns -/// playback. -@_cdecl("apple_tts_synthesize") -public func apple_tts_synthesize( - _ text: UnsafePointer, - _ voice: UnsafePointer?, - _ rate: Float, - _ outLen: UnsafeMutablePointer, - _ outRate: UnsafeMutablePointer -) -> UnsafeMutablePointer? { - outLen.pointee = 0 - outRate.pointee = 0 - - let string = String(cString: text) - if string.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { - return nil - } - - let utterance = AVSpeechUtterance(string: string) - if let voice, let selected = AVSpeechSynthesisVoice(identifier: String(cString: voice)) { - utterance.voice = selected - } else { - utterance.voice = AVSpeechSynthesisVoice(language: "en-US") - } - if rate > 0 { - utterance.rate = rate - } - - let synthesizer = AVSpeechSynthesizer() - let rendered = Rendered() - let finished = DispatchSemaphore(value: 0) - var signalled = false - - // Buffers arrive on an internal queue; a zero-length buffer terminates the run. - synthesizer.write(utterance) { buffer in - guard let pcm = buffer as? AVAudioPCMBuffer else { return } - let frames = Int(pcm.frameLength) - if frames == 0 { - if !signalled { - signalled = true - finished.signal() - } - return - } - rendered.sampleRate = pcm.format.sampleRate - if let channels = pcm.floatChannelData { - rendered.samples.append(contentsOf: UnsafeBufferPointer(start: channels[0], count: frames)) - } else if let channels = pcm.int16ChannelData { - let source = UnsafeBufferPointer(start: channels[0], count: frames) - rendered.samples.append(contentsOf: source.map { Float($0) / 32768.0 }) - } - } - - // `write` delivers its buffers through the main run loop. Blocking the main - // thread on the semaphore therefore deadlocks and yields zero buffers — so - // pump the run loop when we are on it, and only block when we are not. - if Thread.isMainThread { - let deadline = Date().addingTimeInterval(30) - while !signalled, Date() < deadline { - RunLoop.current.run(mode: .default, before: Date().addingTimeInterval(0.02)) - } - } else { - _ = finished.wait(timeout: .now() + 30) - } - // The synthesizer must outlive its callbacks. - withExtendedLifetime(synthesizer) {} - - if rendered.samples.isEmpty || rendered.sampleRate <= 0 { - return nil - } - - let count = rendered.samples.count - let out = UnsafeMutablePointer.allocate(capacity: count) - rendered.samples.withUnsafeBufferPointer { source in - out.initialize(from: source.baseAddress!, count: count) - } - outLen.pointee = Int32(count) - outRate.pointee = Float(rendered.sampleRate) - return out -} - -@_cdecl("apple_tts_free") -public func apple_tts_free(_ ptr: UnsafeMutablePointer?) { - ptr?.deallocate() -} diff --git a/libs/voice/tests/fixtures/silero_ref_speech.txt b/libs/ai/models/speech/tests/fixtures/silero_ref_speech.txt similarity index 100% rename from libs/voice/tests/fixtures/silero_ref_speech.txt rename to libs/ai/models/speech/tests/fixtures/silero_ref_speech.txt diff --git a/libs/voice/tests/fixtures/silero_ref_synth.txt b/libs/ai/models/speech/tests/fixtures/silero_ref_synth.txt similarity index 100% rename from libs/voice/tests/fixtures/silero_ref_synth.txt rename to libs/ai/models/speech/tests/fixtures/silero_ref_synth.txt diff --git a/libs/voice/tests/silero_vad.rs b/libs/ai/models/speech/tests/silero_vad.rs similarity index 98% rename from libs/voice/tests/silero_vad.rs rename to libs/ai/models/speech/tests/silero_vad.rs index 70237e25d..d57e4a3a7 100644 --- a/libs/voice/tests/silero_vad.rs +++ b/libs/ai/models/speech/tests/silero_vad.rs @@ -6,7 +6,7 @@ //! from `MAKEPAD_VAD_MODEL` or the repo root; they skip quietly if it is //! missing so the suite still passes on machines without the weights. -use makepad_voice::{SileroVad, VAD_CHUNK_SAMPLES}; +use makepad_ai_speech::vad::{SileroVad, VAD_CHUNK_SAMPLES}; use std::path::{Path, PathBuf}; fn repo_root_file(name: &str) -> Option { diff --git a/libs/audio_lyrics/Cargo.toml b/libs/audio_lyrics/Cargo.toml index 8e02ae97a..04f19bcf6 100644 --- a/libs/audio_lyrics/Cargo.toml +++ b/libs/audio_lyrics/Cargo.toml @@ -7,6 +7,6 @@ description = "Word-aligned lyrics: the karaoke alignment core and the lyrics JS license = "MIT OR Apache-2.0" [dependencies] -makepad-voice = { path = "../voice" } +makepad-ai-speech = { path = "../ai/models/speech", default-features = false, features = ["whisper"] } makepad-asset-client = { path = "../asset/client" } makepad-asset-data = { path = "../asset/data" } diff --git a/libs/audio_lyrics/src/align.rs b/libs/audio_lyrics/src/align.rs index def5238e3..473894c30 100644 --- a/libs/audio_lyrics/src/align.rs +++ b/libs/audio_lyrics/src/align.rs @@ -8,7 +8,7 @@ //! rises. This module replaces the guessing with measurement, in three //! stages, each of which the audit harness can score separately: //! -//! 1. **Cross-attention DTW** (`makepad_voice::transcribe_aligned`): the +//! 1. **Cross-attention DTW** (`makepad_ai_speech::whisper::transcribe_aligned`): the //! decoder's alignment heads attend to the audio being sung as each token //! is written; a DTW path through that attention IS the word timing, on a //! 20 ms grid. This is what `word_timestamps=True` does inside OpenAI's @@ -29,10 +29,10 @@ //! times out of the cache and the display sweeps smoothly instead of hopping //! wrongly — confidently wrong is worse than a smooth line. //! -//! Everything here is track-time SECONDS and self-contained (makepad_voice + +//! Everything here is track-time SECONDS and self-contained (makepad_ai_speech::whisper + //! std only), so the audit harness can drive the exact code the apps ship. -use makepad_voice::{AlignedSegment, WhisperModel, WhisperState}; +use makepad_ai_speech::whisper::{AlignedSegment, WhisperModel, WhisperState}; /// Whisper's input rate. pub const WHISPER_RATE: f64 = 16_000.0; diff --git a/libs/audio_lyrics/src/bake.rs b/libs/audio_lyrics/src/bake.rs index 25704a29d..f7ebcd318 100644 --- a/libs/audio_lyrics/src/bake.rs +++ b/libs/audio_lyrics/src/bake.rs @@ -13,8 +13,8 @@ use std::path::Path; /// A loaded whisper model plus its decode state, reusable across tracks. pub struct LyricsBaker { - model: Box, - state: makepad_voice::WhisperState, + model: Box, + state: makepad_ai_speech::whisper::WhisperState, model_name: String, } @@ -22,9 +22,9 @@ impl LyricsBaker { /// Load the checkpoint at `path` (a ggml whisper file). pub fn open(path: &Path) -> Result { let text = path.to_string_lossy().to_string(); - let model = makepad_voice::WhisperModel::load_file(&text) + let model = makepad_ai_speech::whisper::WhisperModel::load_file(&text) .map_err(|error| format!("whisper model: {error}"))?; - let state = makepad_voice::WhisperState::new(&model); + let state = makepad_ai_speech::whisper::WhisperState::new(&model); let model_name = path .file_name() .map(|n| n.to_string_lossy().to_string()) @@ -44,7 +44,7 @@ impl LyricsBaker { ) -> Option { let samples_16k = align::resample(vocals_mono, rate, align::WHISPER_RATE); let analysis = align::analyze_vocals(vocals_mono, rate, OnsetPreset::Snapping); - let mut params = makepad_voice::WhisperParams::default(); + let mut params = makepad_ai_speech::whisper::WhisperParams::default(); params.language = language.to_string(); params.no_timestamps = false; params.single_segment = false; diff --git a/libs/converse/Cargo.toml b/libs/converse/Cargo.toml index 282655dae..cd0518187 100644 --- a/libs/converse/Cargo.toml +++ b/libs/converse/Cargo.toml @@ -6,19 +6,22 @@ description = "Conversational voice pipeline for Makepad apps: streamed agent re license = "MIT OR Apache-2.0" [features] -# Speech synthesis (Kokoro). Default ON so existing consumers are unchanged, +# Speech synthesis through the ai-hub (Kokoro or the OS voice). Default ON so existing consumers are unchanged, # but separable: the model plus its embedded pronunciation lexicon is ~10 MB of # binary and ~327 MB resident, which a build that can never speak should not # carry. With it off, SpeechOutput still exists and every non-audio path # behaves identically — the worker just drains its queue in silence. default = ["tts"] -tts = ["dep:makepad-ai-speech"] +tts = ["dep:makepad-ai-hub"] # The local filtering LLM (QwenFilter) on makepad-ai-llm; heavy, so opt-in. local-llm = ["dep:makepad-ai-llm"] [dependencies] makepad-widgets = { path = "../../widgets" } -makepad-ai-speech = { path = "../ai/models/speech", optional = true } +# The hub picks the voice: Kokoro in-process / on the machine node / on a LAN +# node, else the OS synthesizer (makepad-system-speech). No default features: +# the image/video/mesh backends are not this crate's business. +makepad-ai-hub = { path = "../ai/hub", default-features = false, features = ["tts", "speech"], optional = true } makepad-ai-llm = { path = "../ai/llm", optional = true } [[bin]] diff --git a/libs/converse/src/speech.rs b/libs/converse/src/speech.rs index 954258d93..4db5fd021 100644 --- a/libs/converse/src/speech.rs +++ b/libs/converse/src/speech.rs @@ -1,23 +1,24 @@ -//! Speech output: a synthesis worker plus the playback buffer it fills. +//! Speech output: a hub TTS session plus the playback buffer it fills. //! -//! `makepad-ai-speech` returns PCM rather than owning a device, so playback goes +//! The hub hands back PCM rather than owning a device, so playback goes //! through `cx.audio_output` like any other audio in Makepad. Muting is then //! just "stop feeding the buffer", which also makes it instant. //! //! Streamed reply text goes in through [`SpeechOutput::feed`]; each finished -//! sentence is synthesized and spoken while the rest of the reply is still -//! being generated. Lifted out of the gamemaker example so any app can bolt a -//! voice onto an agent. +//! sentence is queued on the session and spoken while the rest of the reply +//! is still being generated. Which voice speaks — Kokoro in this process, on +//! the machine node, on a LAN box, or the OS voice — is the hub's decision +//! ([`makepad_ai_hub::speech`]); this file only plays what comes back. #[cfg(feature = "tts")] -use makepad_ai_speech::Speaker; +use makepad_ai_hub::speech::{TtsConfig, TtsEvent, TtsHandle, TtsSession}; use makepad_widgets::makepad_draw::audio::AudioBuffer; #[cfg(feature = "tts")] use makepad_widgets::log; -use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; -use std::sync::{mpsc, Arc, Mutex}; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{Arc, Mutex, OnceLock}; -/// The buffer the audio callback plays from. Written by the synthesis worker, +/// The buffer the audio callback plays from. Written by the pump thread, /// read by the audio thread. #[derive(Default)] pub struct Playback { @@ -59,19 +60,27 @@ impl Playback { self.cursor -= consumed as f64; } } + + fn clear(&mut self) { + self.samples.clear(); + self.cursor = 0.0; + } } /// Don't speak a fragment shorter than this — one-word clips sound like hiccups. const MIN_SPOKEN_CHARS: usize = 16; -/// Speech output: a synthesis worker plus the buffer it fills. +/// Speech output: a hub TTS session plus the buffer it fills. pub struct SpeechOutput { - say: mpsc::Sender<(u64, String)>, + /// Kokoro voice pack name (or any [`makepad_ai_hub::speech::Voice`] id). + voice: String, + /// Started on the FIRST utterance, not at construction: Kokoro is ~327 MB + /// resident and an app that never speaks (text tier, muted, a session + /// where nobody triggers a reply) must not pay for it. + #[cfg(feature = "tts")] + session: OnceLock, playback: Arc>, muted: Arc, - /// Bumped on stop. Requests from an older generation are dropped, so a - /// sentence that was already being synthesized never plays after a cancel. - generation: Arc, /// Streamed reply text not yet spoken. pending: String, /// "Shh" latch: swallow the rest of the current reply (see `hush`). @@ -79,86 +88,15 @@ pub struct SpeechOutput { } impl SpeechOutput { - /// Start the synthesis worker with a named voice pack - /// (e.g. `"bm_fable.mkvoice"`). Falls back like [`Speaker`] does when the - /// pack or model is missing. + /// Create the output with a named voice (e.g. `"bm_fable"`; a trailing + /// `.mkvoice` is tolerated). Nothing loads until something is said. pub fn new(voice: &str) -> Self { - let playback = Arc::new(Mutex::new(Playback::default())); - let muted = Arc::new(AtomicBool::new(false)); - let generation = Arc::new(AtomicU64::new(0)); - let (say, requests) = mpsc::channel::<(u64, String)>(); - - let worker_playback = playback.clone(); - let worker_generation = generation.clone(); - let voice = voice.to_string(); - std::thread::spawn(move || { - // Built without `tts`: the synthesis stack (Kokoro plus its - // embedded pronunciation lexicon) is ~10 MB of binary, so a build - // that can never speak does not link it. Drain the queue so senders - // never block — every other path (text, muting, generation - // cancellation) behaves exactly as it does with speech on. - #[cfg(not(feature = "tts"))] - { - let _ = (&voice, &worker_playback); - while let Ok((generation, _text)) = requests.recv() { - let _ = generation.min(worker_generation.load(Ordering::Relaxed)); - } - return; - } - // Off the main thread on purpose: synthesis blocks until the whole - // utterance is rendered. - // - // The speaker is built on the FIRST request, not here: the Kokoro - // model is ~327 MB resident, and an app that never speaks (text - // tier, muted, or a session where nobody triggers a reply) should - // not pay for it. Construction is still off the main thread, so - // the load cost lands on the worker either way. - #[cfg(feature = "tts")] - let mut speaker: Option = None; - #[cfg(feature = "tts")] - while let Ok((generation, text)) = requests.recv() { - if generation != worker_generation.load(Ordering::Relaxed) { - continue; - } - let speaker = match speaker { - Some(ref mut speaker) => speaker, - ref mut none => { - let mut fresh = Speaker::from_makepad_env_with_voice(&voice); - log!("tts: backend {:?}", fresh.kind()); - // Discarded warm-up: Kokoro's first synthesis - // initializes the Metal context on this thread. - let _ = fresh.synthesize("Hi."); - none.insert(fresh) - } - }; - match speaker.synthesize(&text) { - Ok(audio) if !audio.is_empty() => { - // Re-check: synthesis is slow enough that a cancel can - // land while it runs. - if generation != worker_generation.load(Ordering::Relaxed) { - continue; - } - let mut playback = worker_playback.lock().unwrap(); - if playback.source_rate != audio.sample_rate as f64 { - playback.samples.clear(); - playback.cursor = 0.0; - playback.source_rate = audio.sample_rate as f64; - } - // Append, don't replace: sentences queue up behind - // each other. - playback.samples.extend_from_slice(&audio.samples); - } - Ok(_) => {} - Err(err) => log!("tts: {err:?}"), - } - } - }); - Self { - say, - playback, - muted, - generation, + voice: voice.strip_suffix(".mkvoice").unwrap_or(voice).to_string(), + #[cfg(feature = "tts")] + session: OnceLock::new(), + playback: Arc::new(Mutex::new(Playback::default())), + muted: Arc::new(AtomicBool::new(false)), pending: String::new(), hushed: false, } @@ -175,6 +113,12 @@ impl SpeechOutput { self.muted.clone() } + /// True while synthesized audio is still queued or playing — apps use it + /// to drop mic transcripts of the assistant's own voice. + pub fn is_speaking(&self) -> bool { + self.playback.lock().map(|p| !p.samples.is_empty()).unwrap_or(false) + } + /// Convenience for apps with no other audio: install an audio-output /// callback that plays speech and nothing else. pub fn install_audio_output(&self, cx: &mut makepad_widgets::Cx, index: usize) { @@ -238,18 +182,74 @@ impl SpeechOutput { if text.is_empty() { return; } - let _ = self - .say - .send((self.generation.load(Ordering::Relaxed), text)); + #[cfg(feature = "tts")] + { + let session = self + .session + .get_or_init(|| Self::start_session(&self.voice, self.playback.clone())); + session.say(text); + } + // Built without `tts`: the synthesis stack is ~10 MB of binary, so a + // build that can never speak does not link it. Every other path (text, + // muting, cancellation) behaves exactly as it does with speech on. + #[cfg(not(feature = "tts"))] + let _ = text; + } + + /// Start the hub session and the pump thread that moves its audio into + /// the playback buffer. The pump blocks on the session's events, so it + /// costs nothing while nobody speaks. + #[cfg(feature = "tts")] + fn start_session(voice: &str, playback: Arc>) -> TtsHandle { + let (handle, events) = TtsSession::start(TtsConfig { + voice: Some(voice.to_string()), + ..TtsConfig::default() + }) + .split(); + std::thread::Builder::new() + .name("converse-speech-pump".into()) + .spawn(move || { + while let Some(event) = events.recv() { + match event { + TtsEvent::Loading { .. } => {} + TtsEvent::Ready(info) => { + log!("tts: {} via {}{}", info.engine, info.pipe, match &info.remote { + Some(node) => format!(" on {node}"), + None => String::new(), + }); + } + TtsEvent::Failed(why) => { + log!("tts: no voice available: {why}"); + return; + } + TtsEvent::Audio { audio, .. } => { + let mut playback = playback.lock().unwrap(); + if playback.source_rate != audio.sample_rate as f64 { + playback.clear(); + playback.source_rate = audio.sample_rate as f64; + } + // Append, don't replace: sentences queue up behind + // each other. + playback.samples.extend_from_slice(&audio.samples); + } + TtsEvent::Error { message, .. } => log!("tts: {message}"), + } + } + }) + .expect("spawn speech pump"); + handle } /// Cancel queued and playing speech immediately. pub fn stop(&mut self) { - self.generation.fetch_add(1, Ordering::Relaxed); + #[cfg(feature = "tts")] + if let Some(session) = self.session.get() { + session.cancel(); + } self.pending.clear(); - let mut playback = self.playback.lock().unwrap(); - playback.samples.clear(); - playback.cursor = 0.0; + if let Ok(mut playback) = self.playback.lock() { + playback.clear(); + } } /// "Shh": stop speaking AND stay quiet for the rest of the current reply. @@ -291,7 +291,7 @@ pub fn spoken_text(markdown: &str) -> String { } let cleaned: String = line .chars() - .filter(|c| !matches!(c, '*' | '_' | '`' | '#' | '>' | '|')) + .filter(|c| !matches!(c, '*' | '_' | '`' | '#' | '>' | '|' | '→' | '⚙' | '·')) .collect(); let cleaned = cleaned.trim(); if !cleaned.is_empty() { @@ -306,48 +306,43 @@ pub fn spoken_text(markdown: &str) -> String { mod tests { use super::*; - /// Constructing the output must NOT load the synthesis model: Kokoro is - /// ~327 MB resident, and an app that never speaks should not pay for it. - /// Model load happens on the first enqueued utterance instead. - /// - /// Proxy for "did not load": construction returns promptly. A real load - /// reads hundreds of MB off disk and warms a Metal context, which cannot - /// happen in this budget on any machine we build on. + /// Constructing the output must NOT start a session or load a model: + /// Kokoro is ~327 MB resident, and an app that never speaks should not + /// pay for it. The session starts on the first enqueued utterance. #[test] - fn constructing_speech_output_does_not_load_the_model() { + fn constructing_speech_output_does_not_start_a_session() { let start = std::time::Instant::now(); let speech = SpeechOutput::new("bm_fable.mkvoice"); - let elapsed = start.elapsed(); - assert!( - speech.playback().lock().unwrap().samples.is_empty(), - "nothing should be synthesized before anything is said" - ); - assert!( - elapsed < std::time::Duration::from_millis(250), - "construction took {elapsed:?} — the model is being loaded eagerly again" - ); + #[cfg(feature = "tts")] + assert!(speech.session.get().is_none()); + assert!(speech.playback().lock().unwrap().samples.is_empty()); + assert!(!speech.is_speaking()); + assert!(start.elapsed() < std::time::Duration::from_millis(250)); + } + + #[test] + fn spoken_text_drops_code_and_markup() { + let text = "Here **you** go:\n```rust\nfn x() {}\n```\nDone → ok."; + // The arrow is dropped, not replaced, so its two surrounding spaces remain. + assert_eq!(spoken_text(text), "Here you go: Done ok."); } /// The lazy path must still speak. Ignored by default: it loads the real - /// ~327 MB model and takes seconds. - /// - /// Model paths resolve relative to the CWD, which under `cargo test` is - /// the crate dir, not the repo root — so point them at the real files or - /// this silently falls back to a different backend and proves nothing: + /// ~327 MB model (or falls back to the OS voice) and takes seconds. /// /// ```text /// MAKEPAD_TTS_MODEL=$REPO/kokoro-v1_0.mktts \ /// MAKEPAD_TTS_VOICE=$REPO/bm_fable.mkvoice \ - /// cargo test -p makepad-converse --release lazily_loaded -- --ignored + /// cargo test -p makepad-converse --release lazily -- --ignored /// ``` #[test] - #[ignore = "loads the real Kokoro model (~327 MB); needs MAKEPAD_TTS_* paths"] - fn lazily_loaded_speaker_still_produces_audio() { - let speech = SpeechOutput::new("bm_fable.mkvoice"); + #[ignore = "starts a real hub TTS session; needs weights or an OS voice"] + fn lazily_started_session_still_produces_audio() { + let mut speech = SpeechOutput::new("bm_fable.mkvoice"); speech.enqueue("Testing the lazy speech path."); let deadline = std::time::Instant::now() + std::time::Duration::from_secs(120); while std::time::Instant::now() < deadline { - if !speech.playback().lock().unwrap().samples.is_empty() { + if speech.is_speaking() { return; } std::thread::sleep(std::time::Duration::from_millis(200)); diff --git a/libs/system_speech/Cargo.toml b/libs/system_speech/Cargo.toml new file mode 100644 index 000000000..545366f22 --- /dev/null +++ b/libs/system_speech/Cargo.toml @@ -0,0 +1,46 @@ +[package] +name = "makepad-system-speech" +version = "0.1.0" +edition = "2021" +description = "The operating system's own speech services as plain blocking functions: speech-to-text and text-to-speech through Apple Speech / AVSpeechSynthesizer, Windows.Media.SpeechRecognition / SpeechSynthesis, Android SpeechRecognizer / TextToSpeech, and espeak-ng on Linux. No models, no network, no hub — makepad-ai-hub publishes these as the `stt.system` / `tts.system` pipes." +license = "MIT" + +[dependencies] + +[target.'cfg(target_os = "android")'.dependencies] +## Same rule as makepad-platform: crates.io versions, not path deps, so exactly +## one copy of the JNI / activity state exists in the app binary. +makepad-jni-sys = { version = "0.4.0" } +makepad-android-state = { version = "0.1.0" } + +[target.'cfg(windows)'.dependencies.windows-core] +path = "../windows/windows-core" +version = "0.62.2" + +## `IAsyncOperation` / `IAsyncAction` are named directly by the blocking waits +## in `platform/windows.rs`; the `windows` crate returns them but re-exports +## neither. +[target.'cfg(windows)'.dependencies.windows-future] +path = "../windows/windows-future" +version = "0.3.2" +default-features = false + +[target.'cfg(windows)'.dependencies.windows] +path = "../windows/windows-rs" +version = "0.62.2" +features = [ + "Foundation", + "Foundation_Collections", + "Globalization", + ## `SpeechSynthesisStream` is gated on Media_Core: it is an IMediaSource. + "Media_Core", + "Media_SpeechSynthesis", + "Media_SpeechRecognition", + "Storage_Streams", + "Win32_Foundation", + "Win32_System_WinRT", +] + +[[bin]] +name = "system-speech-test" +path = "src/bin/system_speech_test.rs" diff --git a/libs/system_speech/build.rs b/libs/system_speech/build.rs new file mode 100644 index 000000000..23ee48210 --- /dev/null +++ b/libs/system_speech/build.rs @@ -0,0 +1,198 @@ +//! Builds the Apple bridge (`swift/stt_bridge.swift` + `swift/tts_bridge.swift`) +//! into one static library on Apple hosts targeting macOS/iOS. Without a Swift +//! toolchain, or off Apple, the crate compiles without the `apple_speech` cfg +//! and both engines report themselves unavailable. + +use std::env; +use std::fs; +use std::process::Command; + +/// SpeechAnalyzer (the STT half of the bridge) is iOS 26+. +const IOS_DEPLOYMENT_TARGET_DEFAULT: &str = "26.0"; + +fn main() { + println!("cargo:rustc-check-cfg=cfg(apple_speech)"); + println!("cargo:rerun-if-changed=swift/stt_bridge.swift"); + println!("cargo:rerun-if-changed=swift/tts_bridge.swift"); + println!("cargo:rerun-if-env-changed=MAKEPAD_SYSTEM_SPEECH_NO_APPLE_BRIDGE"); + println!("cargo:rerun-if-env-changed=IPHONEOS_DEPLOYMENT_TARGET"); + println!("cargo:rerun-if-env-changed=IPHONESIMULATOR_DEPLOYMENT_TARGET"); + + let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default(); + let is_apple_host = env::var("HOST").unwrap_or_default().contains("apple-darwin"); + let is_apple_target = target_os == "macos" || target_os == "ios"; + let disabled = env::var_os("MAKEPAD_SYSTEM_SPEECH_NO_APPLE_BRIDGE").is_some(); + + if is_apple_host && is_apple_target && !disabled && build_apple_bridge(&target_os) { + println!("cargo:rustc-cfg=apple_speech"); + } else if is_apple_target && !disabled { + println!("cargo:warning=makepad-system-speech: Apple bridge not built; system STT/TTS unavailable"); + } +} + +fn build_apple_bridge(target_os: &str) -> bool { + let out_dir = env::var("OUT_DIR").unwrap(); + let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + let module_cache = format!("{out_dir}/swift_module_cache"); + let _ = fs::create_dir_all(&module_cache); + + let mut args = vec![ + "-emit-library".to_string(), + "-static".to_string(), + "-parse-as-library".to_string(), + "-module-name".to_string(), + "makepad_system_speech".to_string(), + "-module-cache-path".to_string(), + module_cache, + "-O".to_string(), + ]; + if target_os == "ios" { + if let Some((target, sdk)) = ios_target_and_sdk() { + args.push("-target".to_string()); + args.push(target); + args.push("-sdk".to_string()); + args.push(sdk); + } + } + args.push("-o".to_string()); + args.push(format!("{out_dir}/libmakepad_system_speech.a")); + args.push(format!("{manifest_dir}/swift/stt_bridge.swift")); + args.push(format!("{manifest_dir}/swift/tts_bridge.swift")); + + match Command::new("swiftc").args(&args).status() { + Ok(status) if status.success() => {} + Ok(_) => { + println!("cargo:warning=swiftc failed for the makepad-system-speech Apple bridge"); + return false; + } + Err(err) => { + println!("cargo:warning=swiftc unavailable ({err}) for the makepad-system-speech Apple bridge"); + return false; + } + } + + // Must come BEFORE any other link-search line so the patched .tbd files win. + if target_os == "macos" { + fix_swift_rpath_tbds(&out_dir); + } + + println!("cargo:rustc-link-search=native={out_dir}"); + println!("cargo:rustc-link-lib=static=makepad_system_speech"); + + // The Swift objects were built for this deployment target; the Rust link + // step must agree or the async runtime's symbols go missing. + if target_os == "ios" { + let deployment = ios_deployment_target(); + println!("cargo:rustc-link-arg=-miphoneos-version-min={deployment}"); + } + + println!("cargo:rustc-link-lib=framework=Speech"); + println!("cargo:rustc-link-lib=framework=Foundation"); + println!("cargo:rustc-link-lib=framework=AVFoundation"); + println!("cargo:rustc-link-lib=framework=CoreMedia"); + + // Swift runtime search paths so the linker resolves the bridge's symbols. + if let Ok(output) = Command::new("swiftc").args(["-print-target-info"]).output() { + if output.status.success() { + let info = String::from_utf8_lossy(&output.stdout); + for line in info.lines() { + let path = line.trim().trim_matches('"').trim_end_matches(','); + if path.starts_with('/') && path.contains("lib/swift") { + println!("cargo:rustc-link-search=native={path}"); + } + } + } + } + true +} + +fn ios_is_simulator() -> bool { + let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default(); + let abi = env::var("CARGO_CFG_TARGET_ABI").unwrap_or_default(); + abi == "sim" || arch == "x86_64" +} + +fn ios_deployment_target() -> String { + let key = if ios_is_simulator() { + "IPHONESIMULATOR_DEPLOYMENT_TARGET" + } else { + "IPHONEOS_DEPLOYMENT_TARGET" + }; + env::var(key).unwrap_or_else(|_| IOS_DEPLOYMENT_TARGET_DEFAULT.to_string()) +} + +fn ios_target_and_sdk() -> Option<(String, String)> { + let arch = env::var("CARGO_CFG_TARGET_ARCH").ok()?; + let swift_arch = match arch.as_str() { + "aarch64" => "arm64", + "x86_64" => "x86_64", + _ => return None, + }; + let deployment = ios_deployment_target(); + let (swift_target, sdk_name) = if ios_is_simulator() { + (format!("{swift_arch}-apple-ios{deployment}-simulator"), "iphonesimulator") + } else { + (format!("{swift_arch}-apple-ios{deployment}"), "iphoneos") + }; + let sdk_path = Command::new("xcrun") + .args(["--sdk", sdk_name, "--show-sdk-path"]) + .output() + .ok() + .filter(|out| out.status.success()) + .map(|out| String::from_utf8_lossy(&out.stdout).trim().to_string())?; + Some((swift_target, sdk_path)) +} + +/// The macOS SDK's Swift runtime `.tbd` files carry `$ld$previous` entries that +/// make the linker record `@rpath/libswift_Concurrency.dylib` as the install +/// name whenever MACOSX_DEPLOYMENT_TARGET < 15 — and Rust defaults to 11.0. The +/// binary then dies at launch with "Library not loaded: @rpath/...". Patched +/// copies without those entries, searched first, make the linker use the +/// absolute `/usr/lib/swift/...` names instead. +fn fix_swift_rpath_tbds(out_dir: &str) { + let Some(sdk_path) = Command::new("xcrun") + .args(["--show-sdk-path"]) + .output() + .ok() + .filter(|o| o.status.success()) + .map(|o| String::from_utf8_lossy(&o.stdout).trim().to_string()) + else { + return; + }; + let override_dir = format!("{out_dir}/swift_tbd_override"); + if fs::create_dir_all(&override_dir).is_err() { + return; + } + let swift_tbd_dir = format!("{sdk_path}/usr/lib/swift"); + for name in [ + "libswift_Concurrency.tbd", + "libswiftCore.tbd", + "libswiftFoundation.tbd", + "libswift_StringProcessing.tbd", + "libswift_RegexParser.tbd", + ] { + let Ok(content) = fs::read_to_string(format!("{swift_tbd_dir}/{name}")) else { + continue; + }; + if !content.contains("$ld$previous$@rpath/") { + continue; + } + let _ = fs::write(format!("{override_dir}/{name}"), strip_ld_previous_rpath(&content)); + } + println!("cargo:rustc-link-search=native={override_dir}"); +} + +fn strip_ld_previous_rpath(content: &str) -> String { + let mut result = content.to_string(); + while let Some(start) = result.find("'$ld$previous$@rpath/") { + let Some(end_quote_offset) = result[start + 1..].find('\'') else { + break; + }; + let end = start + 1 + end_quote_offset + 1; + let rest = &result[end..]; + let trimmed = rest.trim_start_matches(|c: char| matches!(c, ',' | ' ' | '\n' | '\r')); + let skip = rest.len() - trimmed.len(); + result = format!("{}{}", &result[..start], &result[end + skip..]); + } + result +} diff --git a/libs/system_speech/src/bin/system_speech_test.rs b/libs/system_speech/src/bin/system_speech_test.rs new file mode 100644 index 000000000..249e35e43 --- /dev/null +++ b/libs/system_speech/src/bin/system_speech_test.rs @@ -0,0 +1,133 @@ +//! Exercise the OS speech engines from the command line. +//! +//! ```text +//! system-speech-test info +//! system-speech-test voices +//! system-speech-test tts "Hello there" [--voice ID] [--lang en-GB] [--rate 1.2] [--pitch 1.0] [-o out.wav] +//! system-speech-test stt input.wav [--lang en] # PCM-input engines +//! system-speech-test listen [--lang en] [--seconds 8] # mic-owning engines +//! ``` + +use makepad_system_speech::{stt, tts, wav, SttEvent, SttOptions, TtsOptions, STT_SAMPLE_RATE}; +use std::sync::mpsc; +use std::time::{Duration, Instant}; + +fn arg_value(args: &[String], flag: &str) -> Option { + args.iter().position(|a| a == flag).and_then(|i| args.get(i + 1).cloned()) +} + +fn main() { + let args: Vec = std::env::args().skip(1).collect(); + match args.first().map(String::as_str) { + Some("info") | None => { + println!("stt engine : {} (available: {})", stt::engine_name(), stt::available()); + println!("stt caps : {:?}", stt::capabilities()); + println!("tts engine : {} (available: {})", tts::engine_name(), tts::available()); + println!("tts voices : {}", tts::voices().len()); + } + Some("voices") => { + for v in tts::voices() { + println!("{:<48} {:<8} {:?} {}", v.id, v.language, v.gender, v.name); + } + } + Some("tts") => { + let text = args.get(1).cloned().unwrap_or_else(|| "Hello from makepad system speech.".into()); + let mut options = TtsOptions::default(); + options.voice = arg_value(&args, "--voice"); + if let Some(lang) = arg_value(&args, "--lang") { + options.language = lang; + } + if let Some(rate) = arg_value(&args, "--rate").and_then(|v| v.parse().ok()) { + options.rate = rate; + } + if let Some(pitch) = arg_value(&args, "--pitch").and_then(|v| v.parse().ok()) { + options.pitch = pitch; + } + let t0 = Instant::now(); + match tts::synthesize(&text, &options) { + Ok(audio) => { + println!( + "rendered {:.2}s at {} Hz in {:.2}s", + audio.duration_secs(), + audio.sample_rate, + t0.elapsed().as_secs_f64() + ); + let out = arg_value(&args, "-o").unwrap_or_else(|| "system_speech_tts.wav".into()); + std::fs::write(&out, wav::encode_pcm16_mono(&audio)).expect("write wav"); + println!("wrote {out}"); + } + Err(err) => { + eprintln!("tts failed: {err}"); + std::process::exit(1); + } + } + } + Some("stt") => { + let path = args.get(1).expect("stt "); + let bytes = std::fs::read(path).expect("read wav"); + let audio = wav::decode(&bytes).expect("decode wav").resampled(STT_SAMPLE_RATE); + let mut options = SttOptions::default(); + if let Some(lang) = arg_value(&args, "--lang") { + options.language = lang; + } + if let Err(err) = stt::prepare(&options.language) { + eprintln!("prepare: {err} (continuing)"); + } + let t0 = Instant::now(); + match stt::transcribe(&audio.samples, &options) { + Ok(transcript) => { + println!("transcribed {:.2}s of audio in {:.2}s", audio.duration_secs(), t0.elapsed().as_secs_f64()); + for s in &transcript.segments { + println!("[{:>7.2} --> {:>7.2}] {}", s.start_ms as f64 / 1000.0, s.end_ms as f64 / 1000.0, s.text); + } + println!("text: {}", transcript.text()); + } + Err(err) => { + eprintln!("stt failed: {err}"); + std::process::exit(1); + } + } + } + Some("listen") => { + let mut options = SttOptions::default(); + if let Some(lang) = arg_value(&args, "--lang") { + options.language = lang; + } + let seconds: u64 = arg_value(&args, "--seconds").and_then(|v| v.parse().ok()).unwrap_or(8); + let (tx, rx) = mpsc::channel(); + let handle = match stt::listen(&options, tx) { + Ok(handle) => handle, + Err(err) => { + eprintln!("listen failed: {err}"); + std::process::exit(1); + } + }; + println!("listening for {seconds}s ..."); + let deadline = Instant::now() + Duration::from_secs(seconds); + let mut handle = Some(handle); + loop { + match rx.recv_timeout(Duration::from_millis(100)) { + Ok(SttEvent::Level(level)) => print!("\rlevel {level:.2} "), + Ok(SttEvent::Partial(text)) => println!("\npartial: {text}"), + Ok(SttEvent::Final(t)) => println!("\nfinal : {}", t.text()), + Ok(SttEvent::Error(err)) => println!("\nerror : {err}"), + Ok(SttEvent::Ended) => { + println!("\nended"); + break; + } + Err(mpsc::RecvTimeoutError::Timeout) => {} + Err(mpsc::RecvTimeoutError::Disconnected) => break, + } + if Instant::now() >= deadline { + if let Some(handle) = handle.take() { + handle.stop(); + } + } + } + } + Some(other) => { + eprintln!("unknown command {other}"); + std::process::exit(2); + } + } +} diff --git a/libs/system_speech/src/lib.rs b/libs/system_speech/src/lib.rs new file mode 100644 index 000000000..dc25f519a --- /dev/null +++ b/libs/system_speech/src/lib.rs @@ -0,0 +1,424 @@ +//! The operating system's own speech services, as plain blocking functions. +//! +//! This crate is deliberately the bottom of the stack: no models, no network, +//! no hub, no `Cx`. It answers exactly two questions per platform — "can this +//! OS turn speech into text / text into speech, and how?" — and hands back +//! plain data. `makepad-ai-hub` wraps it as the `stt.system` / `tts.system` +//! pipes, next to the in-repo Whisper and Kokoro engines, so an app never +//! calls this crate directly; it asks the hub. +//! +//! | platform | STT | TTS | +//! |----------|------------------------------------|----------------------------------| +//! | macOS/iOS| `SpeechAnalyzer` (PCM in) | `AVSpeechSynthesizer` → PCM | +//! | Windows | `Windows.Media.SpeechRecognition` | `Windows.Media.SpeechSynthesis` | +//! | Android | `android.speech.SpeechRecognizer` | `android.speech.tts.TextToSpeech`| +//! | Linux | none | `espeak-ng` when installed | +//! +//! **Two STT shapes, honestly modelled.** Apple's recognizer takes PCM the +//! caller recorded ([`stt::transcribe`]). Android (at API 26) and Windows +//! recognizers only listen to the microphone themselves ([`stt::listen`]). +//! [`stt::capabilities`] says which a platform offers; a caller adapts rather +//! than the crate pretending. +//! +//! **Threading.** Every function blocks until done and is meant to be called +//! from a worker thread, never the UI thread: the Android bridge parks the +//! calling thread on a latch while the platform does its work on the main +//! looper, and Apple's synthesizer delivers its audio through the process's +//! MAIN run loop. UI apps always pump one; a headless tool that calls TTS +//! from a worker must keep its main thread in `CFRunLoopRun` (the hub's +//! `speech-roundtrip` bin shows the pattern). + +pub mod wav; +mod platform; + +use std::sync::mpsc::Sender; + +// ------------------------------------------------------------------ common + +/// Mono PCM at the producing engine's native rate. +#[derive(Clone, Debug, Default, PartialEq)] +pub struct SpeechAudio { + pub samples: Vec, + pub sample_rate: u32, +} + +impl SpeechAudio { + pub fn is_empty(&self) -> bool { + self.samples.is_empty() + } + + pub fn duration_secs(&self) -> f32 { + if self.sample_rate == 0 { + return 0.0; + } + self.samples.len() as f32 / self.sample_rate as f32 + } + + /// Linear resample to `target` Hz. Good enough for STT input; playback + /// paths should use their own higher-quality resampler. + pub fn resampled(&self, target: u32) -> SpeechAudio { + if self.sample_rate == 0 || target == 0 || self.samples.is_empty() { + return SpeechAudio { samples: Vec::new(), sample_rate: target }; + } + if self.sample_rate == target { + return self.clone(); + } + let ratio = self.sample_rate as f64 / target as f64; + let out_len = ((self.samples.len() as f64) / ratio).floor() as usize; + let mut out = Vec::with_capacity(out_len); + for i in 0..out_len { + let pos = i as f64 * ratio; + let left = pos.floor() as usize; + let frac = (pos - left as f64) as f32; + let a = self.samples[left]; + let b = *self.samples.get(left + 1).unwrap_or(&a); + out.push(a + (b - a) * frac); + } + SpeechAudio { samples: out, sample_rate: target } + } +} + +#[derive(Clone, Debug, PartialEq)] +pub enum SpeechError { + /// Not on this platform, the bridge was not built, or the OS service is + /// missing (no recognition service installed, no `espeak-ng` binary, ...). + Unavailable(String), + /// The OS refused: microphone / speech-recognition permission not granted. + PermissionDenied, + /// The engine exists but lacks this capability (e.g. PCM input on Android). + Unsupported(&'static str), + /// The engine ran and produced nothing. + Empty, + Cancelled, + Timeout, + Backend(String), +} + +impl std::fmt::Display for SpeechError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SpeechError::Unavailable(why) => write!(f, "unavailable: {why}"), + SpeechError::PermissionDenied => f.write_str("permission denied"), + SpeechError::Unsupported(what) => write!(f, "unsupported: {what}"), + SpeechError::Empty => f.write_str("engine produced nothing"), + SpeechError::Cancelled => f.write_str("cancelled"), + SpeechError::Timeout => f.write_str("timed out"), + SpeechError::Backend(why) => write!(f, "backend: {why}"), + } + } +} + +impl std::error::Error for SpeechError {} + +// --------------------------------------------------------------------- STT + +/// The rate [`stt::transcribe`] expects its PCM at. +pub const STT_SAMPLE_RATE: u32 = 16_000; + +/// A transcribed span. Engines without timing report `0..0`. +#[derive(Clone, Debug, PartialEq)] +pub struct Segment { + pub start_ms: i64, + pub end_ms: i64, + pub text: String, +} + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct Transcript { + pub segments: Vec, +} + +impl Transcript { + pub fn from_text(text: impl Into) -> Self { + let text: String = text.into(); + if text.trim().is_empty() { + return Self::default(); + } + Self { segments: vec![Segment { start_ms: 0, end_ms: 0, text }] } + } + + pub fn is_empty(&self) -> bool { + self.segments.iter().all(|s| s.text.trim().is_empty()) + } + + /// All segment text joined with single spaces. + pub fn text(&self) -> String { + let mut out = String::new(); + for segment in &self.segments { + let trimmed = segment.text.trim(); + if trimmed.is_empty() { + continue; + } + if !out.is_empty() { + out.push(' '); + } + out.push_str(trimmed); + } + out + } +} + +#[derive(Clone, Debug, PartialEq)] +pub struct SttOptions { + /// ISO 639-1 (`"en"`) or a BCP-47 tag (`"en-US"`). Bare codes map to the + /// platform's default region. + pub language: String, + /// `listen` only: emit [`SttEvent::Partial`] while the utterance is still + /// being spoken, when the engine can. + pub partial_results: bool, + /// Prefer on-device recognition over a cloud-backed one when the engine + /// offers the choice (Android). Never forces: an engine without an + /// offline model still recognizes. + pub prefer_offline: bool, + /// `transcribe` only: ask for per-segment timing when the engine has it. + pub timestamps: bool, +} + +impl Default for SttOptions { + fn default() -> Self { + Self { + language: "en".to_string(), + partial_results: true, + prefer_offline: true, + timestamps: true, + } + } +} + +/// What this platform's recognizer can do. Both input shapes may be false +/// (no recognizer at all) or true (Apple: PCM today; a mic session is a +/// natural extension). +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] +pub struct SttCapabilities { + /// [`stt::transcribe`] works: caller-recorded 16 kHz mono PCM in. + pub pcm_input: bool, + /// [`stt::listen`] works: the engine owns the microphone. + pub engine_mic: bool, + /// `listen` can emit partial hypotheses. + pub partial_results: bool, + /// Recognition can run without network. + pub offline: bool, +} + +/// Events from a [`stt::listen`] session, in order. `Ended` is always last; +/// after it (or `Error`) nothing else arrives and the handle is spent. +#[derive(Clone, Debug, PartialEq)] +pub enum SttEvent { + /// Input level, 0..1, when the engine reports one (Android `onRmsChanged`). + Level(f32), + /// Running hypothesis for the utterance in progress; replaces the last. + Partial(String), + /// A finished utterance. + Final(Transcript), + Error(SpeechError), + Ended, +} + +/// A running microphone session. Dropping it stops listening. +pub struct ListenHandle { + stop: Option>, +} + +impl ListenHandle { + pub fn new(stop: impl FnOnce() + Send + 'static) -> Self { + Self { stop: Some(Box::new(stop)) } + } + + /// Stop listening. The engine still delivers any final result it has, + /// then `Ended`. + pub fn stop(mut self) { + if let Some(stop) = self.stop.take() { + stop(); + } + } +} + +impl Drop for ListenHandle { + fn drop(&mut self) { + if let Some(stop) = self.stop.take() { + stop(); + } + } +} + +pub mod stt { + //! Speech to text through the OS engine. + use super::*; + + /// A short stable name for logs and pipe adverts, e.g. `"apple-speechanalyzer"`. + pub fn engine_name() -> &'static str { + platform::STT_ENGINE + } + + /// True when at least one of the two input shapes works here. + pub fn available() -> bool { + platform::stt_available() + } + + pub fn capabilities() -> SttCapabilities { + platform::stt_capabilities() + } + + /// Get the engine ready for `language`: download an on-device model, + /// warm the recognizer, surface a permission problem early. Optional; + /// `transcribe`/`listen` do it lazily. + pub fn prepare(language: &str) -> Result<(), SpeechError> { + platform::stt_prepare(language) + } + + /// Recognize caller-recorded PCM: mono `f32` at [`STT_SAMPLE_RATE`]. + /// Blocks until the whole buffer is processed. + pub fn transcribe(samples_16k: &[f32], options: &SttOptions) -> Result { + if samples_16k.is_empty() { + return Ok(Transcript::default()); + } + platform::stt_transcribe(samples_16k, options) + } + + /// Let the engine listen on the microphone itself, streaming events into + /// `sink` until the utterance ends or the handle is stopped/dropped. The + /// caller must already hold microphone permission. + pub fn listen(options: &SttOptions, sink: Sender) -> Result { + platform::stt_listen(options, sink) + } +} + +// --------------------------------------------------------------------- TTS + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum VoiceGender { + Unknown, + Female, + Male, +} + +/// One installed voice. `id` is what [`TtsOptions::voice`] takes and is +/// stable per platform (Apple identifier, WinRT `VoiceInformation.Id`, +/// Android `Voice.getName()`, espeak voice name). +#[derive(Clone, Debug, PartialEq)] +pub struct Voice { + pub id: String, + pub name: String, + /// BCP-47, e.g. `"en-GB"`. + pub language: String, + pub gender: VoiceGender, + /// Renders without network. + pub offline: bool, +} + +#[derive(Clone, Debug, PartialEq)] +pub struct TtsOptions { + /// A [`Voice::id`]; `None` picks the platform default for `language`. + pub voice: Option, + /// BCP-47 or bare code, used when `voice` is `None`. + pub language: String, + /// 1.0 = the platform's normal speaking rate; 0.5 half, 2.0 double. + pub rate: f32, + /// 1.0 = normal pitch. Engines without pitch control ignore it. + pub pitch: f32, +} + +impl Default for TtsOptions { + fn default() -> Self { + Self { voice: None, language: "en".to_string(), rate: 1.0, pitch: 1.0 } + } +} + +pub mod tts { + //! Text to speech through the OS engine. Always PCM out: the caller owns + //! the audio device (Makepad plays through `cx.audio_output`), so muting, + //! mixing and cancellation stay in the app. + use super::*; + + /// A short stable name for logs and pipe adverts, e.g. `"apple-avspeech"`. + pub fn engine_name() -> &'static str { + platform::TTS_ENGINE + } + + pub fn available() -> bool { + platform::tts_available() + } + + /// Installed voices. Empty when unavailable. + pub fn voices() -> Vec { + platform::tts_voices() + } + + /// Render `text` to mono PCM at the engine's native rate. Blocks until the + /// whole utterance is rendered; long texts are the caller's to split. + pub fn synthesize(text: &str, options: &TtsOptions) -> Result { + if text.trim().is_empty() { + return Err(SpeechError::Empty); + } + platform::tts_synthesize(text, options) + } +} + +/// Split a bare ISO 639-1 code into the platform default region, or pass a +/// BCP-47 tag through. Shared by the platform modules. +pub(crate) fn bcp47(language: &str) -> String { + let language = language.trim(); + if language.contains('-') || language.contains('_') { + return language.replace('_', "-"); + } + let region = match language.to_ascii_lowercase().as_str() { + "en" => "en-US", + "fr" => "fr-FR", + "de" => "de-DE", + "es" => "es-ES", + "it" => "it-IT", + "pt" => "pt-BR", + "nl" => "nl-NL", + "zh" => "zh-CN", + "ja" => "ja-JP", + "ko" => "ko-KR", + "ru" => "ru-RU", + "yue" => "yue-CN", + _ => return language.to_string(), + }; + region.to_string() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn transcript_text_joins_trimmed_segments() { + let t = Transcript { + segments: vec![ + Segment { start_ms: 0, end_ms: 10, text: " hello ".into() }, + Segment { start_ms: 10, end_ms: 20, text: "".into() }, + Segment { start_ms: 20, end_ms: 30, text: "world".into() }, + ], + }; + assert_eq!(t.text(), "hello world"); + assert!(!t.is_empty()); + assert!(Transcript::from_text(" ").is_empty()); + } + + #[test] + fn bare_language_codes_get_a_region() { + assert_eq!(bcp47("en"), "en-US"); + assert_eq!(bcp47("en-GB"), "en-GB"); + assert_eq!(bcp47("pt_BR"), "pt-BR"); + assert_eq!(bcp47("xx"), "xx"); + } + + #[test] + fn resample_halves_length_at_half_rate() { + let audio = SpeechAudio { samples: vec![0.0; 1000], sample_rate: 32_000 }; + assert_eq!(audio.resampled(16_000).samples.len(), 500); + assert_eq!(audio.resampled(32_000).samples.len(), 1000); + } + + #[test] + fn the_platform_answers_without_panicking() { + // Availability probes must be safe to call anywhere, any platform. + let _ = stt::available(); + let _ = tts::available(); + let _ = stt::capabilities(); + let _ = stt::engine_name(); + let _ = tts::engine_name(); + } +} diff --git a/libs/system_speech/src/platform/android.rs b/libs/system_speech/src/platform/android.rs new file mode 100644 index 000000000..13f527f7e --- /dev/null +++ b/libs/system_speech/src/platform/android.rs @@ -0,0 +1,457 @@ +//! Android: `android.speech.SpeechRecognizer` for STT and +//! `android.speech.tts.TextToSpeech` for TTS, both reached through +//! `MakepadSpeech.java`, which hangs off `MakepadActivity`. +//! +//! Minimum API level is 26, so the recognizer is the mic-owning +//! `SpeechRecognizer` + `EXTRA_PREFER_OFFLINE` (API 23) rather than +//! `createOnDeviceSpeechRecognizer` (API 31), and TTS renders through +//! `synthesizeToFile(CharSequence, Bundle, File, String)` (API 21) rather than +//! the `ParcelFileDescriptor` overload (API 30). +//! +//! Every function here blocks and belongs on a worker thread: the Java side +//! does its work on the main looper (both engines require it) and parks the +//! caller on a latch, so calling from the main thread would deadlock. + +use crate::{ + bcp47, ListenHandle, SpeechAudio, SpeechError, SttCapabilities, SttEvent, SttOptions, + Transcript, TtsOptions, Voice, VoiceGender, +}; +use makepad_android_state::{get_activity, get_java_vm}; +use makepad_jni_sys as jni; +use std::collections::HashMap; +use std::ffi::{CStr, CString}; +use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::mpsc::Sender; +use std::sync::{Mutex, OnceLock}; + +pub(crate) const STT_ENGINE: &str = "android-speechrecognizer"; +pub(crate) const TTS_ENGINE: &str = "android-texttospeech"; + +// ------------------------------------------------------------------ JNI glue + +/// Attach this (worker) thread to the VM. Threads created by Rust are unknown +/// to the JVM until attached, and stay attached for the process' life. +unsafe fn attach_env() -> Option<*mut jni::JNIEnv> { + let vm = get_java_vm(); + if vm.is_null() { + return None; + } + let mut env: *mut jni::JNIEnv = std::ptr::null_mut(); + let attach = (**vm).AttachCurrentThread?; + if attach(vm, &mut env, std::ptr::null_mut()) != 0 || env.is_null() { + return None; + } + Some(env) +} + +/// A pending Java exception poisons every later JNI call on this thread, so it +/// is logged and cleared at each boundary rather than carried across. +unsafe fn clear_exception(env: *mut jni::JNIEnv) { + let (Some(check), Some(describe), Some(clear)) = + ((**env).ExceptionCheck, (**env).ExceptionDescribe, (**env).ExceptionClear) + else { + return; + }; + if check(env) != 0 { + describe(env); + clear(env); + } +} + +/// Resolve a method on the activity's *own* class. A natively attached thread +/// carries only the system class loader, so `FindClass("dev/makepad/...")` +/// cannot see app classes from here; `GetObjectClass(activity)` always can. +unsafe fn activity_method( + env: *mut jni::JNIEnv, + name: &str, + sig: &str, +) -> Option<(jni::jobject, jni::jmethodID)> { + let activity = get_activity(); + if activity.is_null() { + return None; + } + let class = ((**env).GetObjectClass?)(env, activity); + if class.is_null() { + clear_exception(env); + return None; + } + let name = CString::new(name).ok()?; + let sig = CString::new(sig).ok()?; + let method = ((**env).GetMethodID?)(env, class, name.as_ptr(), sig.as_ptr()); + if let Some(delete) = (**env).DeleteLocalRef { + delete(env, class); + } + if method.is_null() { + // GetMethodID throws NoSuchMethodError when the Java half is older. + clear_exception(env); + return None; + } + Some((activity, method)) +} + +// The `A` (jvalue-array) call forms are used throughout: the variadic forms +// take C promotion rules that Rust does not apply, which silently mangles +// `float` and `boolean` arguments on aarch64. + +unsafe fn call_activity_void( + env: *mut jni::JNIEnv, + name: &str, + sig: &str, + args: &[jni::jvalue], +) -> bool { + let Some((activity, method)) = activity_method(env, name, sig) else { + return false; + }; + let Some(call) = (**env).CallVoidMethodA else { + return false; + }; + call(env, activity, method, args.as_ptr()); + clear_exception(env); + true +} + +unsafe fn call_activity_bool(env: *mut jni::JNIEnv, name: &str, sig: &str) -> bool { + let Some((activity, method)) = activity_method(env, name, sig) else { + return false; + }; + let Some(call) = (**env).CallBooleanMethodA else { + return false; + }; + let result = call(env, activity, method, std::ptr::null()); + clear_exception(env); + result != 0 +} + +unsafe fn call_activity_object( + env: *mut jni::JNIEnv, + name: &str, + sig: &str, + args: &[jni::jvalue], +) -> jni::jobject { + let Some((activity, method)) = activity_method(env, name, sig) else { + return std::ptr::null_mut(); + }; + let Some(call) = (**env).CallObjectMethodA else { + return std::ptr::null_mut(); + }; + let result = call(env, activity, method, args.as_ptr()); + clear_exception(env); + result +} + +unsafe fn delete_local_ref(env: *mut jni::JNIEnv, object: jni::jobject) { + if object.is_null() { + return; + } + if let Some(delete) = (**env).DeleteLocalRef { + delete(env, object); + } +} + +unsafe fn new_jstring(env: *mut jni::JNIEnv, text: &str) -> jni::jstring { + let text = CString::new(text) + .unwrap_or_else(|_| CString::new(text.replace('\0', " ")).unwrap_or_default()); + match (**env).NewStringUTF { + Some(new) => new(env, text.as_ptr()), + None => std::ptr::null_mut(), + } +} + +unsafe fn jstring_to_string(env: *mut jni::JNIEnv, text: jni::jstring) -> String { + if text.is_null() { + return String::new(); + } + let Some(get) = (**env).GetStringUTFChars else { + return String::new(); + }; + let chars = get(env, text, std::ptr::null_mut()); + if chars.is_null() { + clear_exception(env); + return String::new(); + } + let out = CStr::from_ptr(chars).to_string_lossy().into_owned(); + if let Some(release) = (**env).ReleaseStringUTFChars { + release(env, text, chars); + } + out +} + +unsafe fn jbyte_array_to_vec(env: *mut jni::JNIEnv, array: jni::jbyteArray) -> Vec { + if array.is_null() { + return Vec::new(); + } + let (Some(length_of), Some(region)) = ((**env).GetArrayLength, (**env).GetByteArrayRegion) + else { + return Vec::new(); + }; + let length = length_of(env, array); + if length <= 0 { + return Vec::new(); + } + let mut out = vec![0u8; length as usize]; + region(env, array, 0, length, out.as_mut_ptr() as *mut jni::jbyte); + clear_exception(env); + out +} + +// ------------------------------------------------------------------- session + +/// Live `listen` sessions. The Java half calls back on the main looper while +/// the Rust caller is off elsewhere, so the sinks live in a global map keyed by +/// a session id rather than travelling through JNI as a pointer. +fn sinks() -> &'static Mutex>> { + static SINKS: OnceLock>>> = OnceLock::new(); + SINKS.get_or_init(|| Mutex::new(HashMap::new())) +} + +static NEXT_SESSION: AtomicU64 = AtomicU64::new(1); + +fn recognizer_error(word: &str) -> SpeechError { + match word { + "permission" => SpeechError::PermissionDenied, + "" => SpeechError::Backend("android recognizer failed".to_string()), + other => SpeechError::Backend(other.to_string()), + } +} + +/// `MakepadSpeech.onSttEvent`. `kind`: 0 level, 1 partial, 2 final, 3 error, +/// 4 ended — the Java half sends exactly one `ended` per session, last. +#[no_mangle] +pub unsafe extern "C" fn Java_dev_makepad_android_MakepadSpeech_onSttEvent( + env: *mut jni::JNIEnv, + _class: jni::jclass, + session: jni::jlong, + kind: jni::jint, + text: jni::jstring, + level: jni::jfloat, +) { + let session = session as u64; + let text = jstring_to_string(env, text); + let Ok(mut sinks) = sinks().lock() else { + return; + }; + if kind == 4 { + // Ended retires the session: the sink is dropped here, which is what + // tells a receiver blocked on the channel that the utterance is over. + if let Some(sink) = sinks.remove(&session) { + let _ = sink.send(SttEvent::Ended); + } + return; + } + let Some(sink) = sinks.get(&session) else { + return; + }; + let event = match kind { + 0 => SttEvent::Level(level.clamp(0.0, 1.0)), + 1 => SttEvent::Partial(text), + 2 => SttEvent::Final(Transcript::from_text(text)), + 3 => SttEvent::Error(recognizer_error(text.trim())), + _ => return, + }; + let _ = sink.send(event); +} + +// ----------------------------------------------------------------------- STT + +pub(crate) fn stt_available() -> bool { + unsafe { + let Some(env) = attach_env() else { + return false; + }; + call_activity_bool(env, "speechSttAvailable", "()Z") + } +} + +pub(crate) fn stt_capabilities() -> SttCapabilities { + SttCapabilities { + // `SpeechRecognizer` owns the microphone itself; there is no PCM input. + pcm_input: false, + engine_mic: true, + partial_results: true, + // EXTRA_PREFER_OFFLINE is honoured where an on-device model exists; + // an engine without one still recognizes over the network. + offline: true, + } +} + +pub(crate) fn stt_prepare(_language: &str) -> Result<(), SpeechError> { + if stt_available() { + Ok(()) + } else { + Err(SpeechError::Unavailable("no android recognition service installed".to_string())) + } +} + +pub(crate) fn stt_transcribe( + _samples_16k: &[f32], + _options: &SttOptions, +) -> Result { + Err(SpeechError::Unsupported( + "the Android recognizer only listens on the microphone; use listen", + )) +} + +pub(crate) fn stt_listen( + options: &SttOptions, + sink: Sender, +) -> Result { + if !stt_available() { + return Err(SpeechError::Unavailable( + "no android recognition service installed".to_string(), + )); + } + let session = NEXT_SESSION.fetch_add(1, Ordering::Relaxed); + let language = bcp47(&options.language); + let partial = options.partial_results; + let prefer_offline = options.prefer_offline; + + match sinks().lock() { + Ok(mut sinks) => { + sinks.insert(session, sink); + } + Err(_) => return Err(SpeechError::Backend("speech session registry poisoned".to_string())), + } + + let started = unsafe { + match attach_env() { + Some(env) => { + let language = new_jstring(env, &language); + let args = [ + jni::jvalue { j: session as jni::jlong }, + jni::jvalue { l: language }, + jni::jvalue { z: partial as jni::jboolean }, + jni::jvalue { z: prefer_offline as jni::jboolean }, + ]; + let ok = call_activity_void( + env, + "speechSttStart", + "(JLjava/lang/String;ZZ)V", + &args, + ); + delete_local_ref(env, language); + ok + } + None => false, + } + }; + if !started { + if let Ok(mut sinks) = sinks().lock() { + sinks.remove(&session); + } + return Err(SpeechError::Unavailable("android speech bridge missing".to_string())); + } + + Ok(ListenHandle::new(move || unsafe { + if let Some(env) = attach_env() { + let args = [jni::jvalue { j: session as jni::jlong }]; + call_activity_void(env, "speechSttStop", "(J)V", &args); + } + })) +} + +// ----------------------------------------------------------------------- TTS + +pub(crate) fn tts_available() -> bool { + unsafe { + let Some(env) = attach_env() else { + return false; + }; + call_activity_bool(env, "speechTtsAvailable", "()Z") + } +} + +pub(crate) fn tts_voices() -> Vec { + unsafe { + let Some(env) = attach_env() else { + return Vec::new(); + }; + let array = + call_activity_object(env, "speechTtsVoices", "()[Ljava/lang/String;", &[]); + if array.is_null() { + return Vec::new(); + } + let (Some(length_of), Some(element_of)) = + ((**env).GetArrayLength, (**env).GetObjectArrayElement) + else { + delete_local_ref(env, array); + return Vec::new(); + }; + let length = length_of(env, array); + let mut voices = Vec::new(); + for index in 0..length { + let item = element_of(env, array, index); + let line = jstring_to_string(env, item); + delete_local_ref(env, item); + // "name\tlanguageTag\tqualityInt\tnetworkRequiredBool" + let mut fields = line.split('\t'); + let (Some(name), Some(language), Some(_quality), Some(network)) = + (fields.next(), fields.next(), fields.next(), fields.next()) + else { + continue; + }; + if name.is_empty() { + continue; + } + voices.push(Voice { + id: name.to_string(), + name: name.to_string(), + language: language.to_string(), + // Android's Voice carries no gender; the name often hints at + // one, but guessing from it would be a lie. + gender: VoiceGender::Unknown, + offline: !network.eq_ignore_ascii_case("true"), + }); + } + delete_local_ref(env, array); + voices + } +} + +pub(crate) fn tts_synthesize(text: &str, options: &TtsOptions) -> Result { + unsafe { + let Some(env) = attach_env() else { + return Err(SpeechError::Unavailable("no java vm on this thread".to_string())); + }; + let text = new_jstring(env, text); + let voice = match options.voice.as_deref().filter(|v| !v.is_empty()) { + Some(voice) => new_jstring(env, voice), + None => std::ptr::null_mut(), + }; + let language = new_jstring(env, &bcp47(&options.language)); + let args = [ + jni::jvalue { l: text }, + jni::jvalue { l: voice }, + jni::jvalue { l: language }, + jni::jvalue { f: options.rate }, + jni::jvalue { f: options.pitch }, + ]; + let wav = call_activity_object( + env, + "speechTtsSynthesize", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;FF)[B", + &args, + ); + delete_local_ref(env, text); + delete_local_ref(env, voice); + delete_local_ref(env, language); + + if wav.is_null() { + let last_error = + call_activity_object(env, "speechTtsLastError", "()Ljava/lang/String;", &[]); + let reason = jstring_to_string(env, last_error); + delete_local_ref(env, last_error); + let reason = if reason.trim().is_empty() { + "android tts produced no audio".to_string() + } else { + reason + }; + return Err(SpeechError::Backend(reason)); + } + let bytes = jbyte_array_to_vec(env, wav); + delete_local_ref(env, wav); + if bytes.is_empty() { + return Err(SpeechError::Empty); + } + crate::wav::decode(&bytes).map_err(SpeechError::Backend) + } +} diff --git a/libs/system_speech/src/platform/apple.rs b/libs/system_speech/src/platform/apple.rs new file mode 100644 index 000000000..7bf1ef146 --- /dev/null +++ b/libs/system_speech/src/platform/apple.rs @@ -0,0 +1,185 @@ +//! macOS / iOS: `SpeechAnalyzer` for STT (PCM in) and `AVSpeechSynthesizer` +//! rendered to a buffer for TTS, both through `swift/*.swift` (symbols `mss_*`). + +use crate::{ + bcp47, ListenHandle, Segment, SpeechAudio, SpeechError, SttCapabilities, SttEvent, SttOptions, + Transcript, TtsOptions, Voice, VoiceGender, +}; +use std::ffi::{c_void, CStr, CString}; +use std::os::raw::{c_char, c_float, c_int}; +use std::sync::mpsc::Sender; + +pub(crate) const STT_ENGINE: &str = "apple-speechanalyzer"; +pub(crate) const TTS_ENGINE: &str = "apple-avspeech"; + +/// Mirrors `MssSegment` in stt_bridge.swift. +#[repr(C)] +struct MssSegment { + text: *mut c_char, + start_ms: i64, + end_ms: i64, +} + +/// Mirrors `MssVoice` in tts_bridge.swift. +#[repr(C)] +struct MssVoice { + id: *mut c_char, + name: *mut c_char, + language: *mut c_char, + gender: i32, +} + +extern "C" { + fn mss_stt_transcribe( + samples: *const f32, + sample_count: i64, + lang: *const c_char, + want_timestamps: i32, + out_count: *mut i32, + out_segments: *mut *mut c_void, + ) -> i32; + fn mss_stt_free_segments(ptr: *mut c_void, count: i32); + fn mss_stt_prepare(lang: *const c_char) -> i32; + + fn mss_tts_synthesize( + text: *const c_char, + voice: *const c_char, + language: *const c_char, + rate: c_float, + pitch: c_float, + out_len: *mut c_int, + out_rate: *mut c_float, + ) -> *mut c_float; + fn mss_tts_free(ptr: *mut c_float); + fn mss_tts_voices(out_count: *mut i32) -> *mut c_void; + fn mss_tts_free_voices(ptr: *mut c_void, count: i32); +} + +fn cstring(s: &str) -> CString { + CString::new(s).unwrap_or_else(|_| CString::new(s.replace('\0', " ")).unwrap()) +} + +unsafe fn owned_str(ptr: *const c_char) -> String { + if ptr.is_null() { + String::new() + } else { + CStr::from_ptr(ptr).to_string_lossy().into_owned() + } +} + +pub(crate) fn stt_available() -> bool { + true +} + +pub(crate) fn stt_capabilities() -> SttCapabilities { + SttCapabilities { pcm_input: true, engine_mic: false, partial_results: false, offline: true } +} + +pub(crate) fn stt_prepare(language: &str) -> Result<(), SpeechError> { + let lang = cstring(&bcp47(language)); + match unsafe { mss_stt_prepare(lang.as_ptr()) } { + 0 => Ok(()), + -2 => Err(SpeechError::Unsupported("language not supported by the Apple recognizer")), + code => Err(SpeechError::Backend(format!("apple stt prepare failed ({code})"))), + } +} + +pub(crate) fn stt_transcribe(samples_16k: &[f32], options: &SttOptions) -> Result { + let lang = cstring(&bcp47(&options.language)); + let mut count: i32 = 0; + let mut raw: *mut c_void = std::ptr::null_mut(); + let ret = unsafe { + mss_stt_transcribe( + samples_16k.as_ptr(), + samples_16k.len() as i64, + lang.as_ptr(), + options.timestamps as i32, + &mut count, + &mut raw, + ) + }; + if ret != 0 { + return Err(SpeechError::Backend(format!("apple stt transcribe failed ({ret})"))); + } + if count <= 0 || raw.is_null() { + return Ok(Transcript::default()); + } + let segments = unsafe { + let ptr = raw as *const MssSegment; + let out = (0..count as usize) + .map(|i| { + let cs = &*ptr.add(i); + Segment { start_ms: cs.start_ms, end_ms: cs.end_ms, text: owned_str(cs.text) } + }) + .collect(); + mss_stt_free_segments(raw, count); + out + }; + Ok(Transcript { segments }) +} + +pub(crate) fn stt_listen(_options: &SttOptions, _sink: Sender) -> Result { + Err(SpeechError::Unsupported("the Apple bridge takes PCM; record and call transcribe")) +} + +pub(crate) fn tts_available() -> bool { + true +} + +pub(crate) fn tts_voices() -> Vec { + let mut count: i32 = 0; + let raw = unsafe { mss_tts_voices(&mut count) }; + if raw.is_null() || count <= 0 { + return Vec::new(); + } + unsafe { + let ptr = raw as *const MssVoice; + let voices = (0..count as usize) + .map(|i| { + let v = &*ptr.add(i); + Voice { + id: owned_str(v.id), + name: owned_str(v.name), + language: owned_str(v.language), + gender: match v.gender { + // AVSpeechSynthesisVoiceGender: unspecified 0, male 1, female 2. + 1 => VoiceGender::Male, + 2 => VoiceGender::Female, + _ => VoiceGender::Unknown, + }, + offline: true, + } + }) + .collect(); + mss_tts_free_voices(raw, count); + voices + } +} + +pub(crate) fn tts_synthesize(text: &str, options: &TtsOptions) -> Result { + let text = cstring(text); + let voice = options.voice.as_deref().filter(|v| !v.is_empty()).map(cstring); + let language = cstring(&bcp47(&options.language)); + let mut len: c_int = 0; + let mut sample_rate: c_float = 0.0; + // Safety: the bridge returns null or a buffer of `len` floats it allocated + // and we free right after copying; every CString outlives the call. + let samples = unsafe { + let ptr = mss_tts_synthesize( + text.as_ptr(), + voice.as_ref().map_or(std::ptr::null(), |v| v.as_ptr()), + language.as_ptr(), + options.rate, + options.pitch, + &mut len, + &mut sample_rate, + ); + if ptr.is_null() || len <= 0 { + return Err(SpeechError::Empty); + } + let samples = std::slice::from_raw_parts(ptr, len as usize).to_vec(); + mss_tts_free(ptr); + samples + }; + Ok(SpeechAudio { samples, sample_rate: sample_rate as u32 }) +} diff --git a/libs/system_speech/src/platform/linux.rs b/libs/system_speech/src/platform/linux.rs new file mode 100644 index 000000000..2c79386c5 --- /dev/null +++ b/libs/system_speech/src/platform/linux.rs @@ -0,0 +1,360 @@ +//! Linux: no system speech recognizer exists, so STT is always unavailable. +//! TTS shells out to the `espeak-ng` command-line synthesizer (falling back +//! to the older `espeak` binary name) via `std::process::Command` — no +//! linking, no bundled model. + +use crate::{ + bcp47, ListenHandle, SpeechAudio, SpeechError, SttCapabilities, SttEvent, SttOptions, + Transcript, TtsOptions, Voice, VoiceGender, +}; +use std::io::{Read, Write}; +use std::process::{Command, Stdio}; +use std::sync::mpsc::{self, Sender}; +use std::sync::OnceLock; +use std::thread; +use std::time::{Duration, Instant}; + +pub(crate) const STT_ENGINE: &str = "none"; +pub(crate) const TTS_ENGINE: &str = "espeak-ng"; + +const SYNTHESIZE_TIMEOUT: Duration = Duration::from_secs(60); + +// ------------------------------------------------------------------- probe + +/// Which binary name works, probed once and cached: `espeak-ng` is tried +/// first, `espeak` (older distros) second. `None` means neither runs. +fn espeak_binary() -> Option<&'static str> { + static BINARY: OnceLock> = OnceLock::new(); + *BINARY.get_or_init(|| { + for bin in ["espeak-ng", "espeak"] { + let ok = Command::new(bin) + .arg("--version") + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .status() + .map(|status| status.success()) + .unwrap_or(false); + if ok { + return Some(bin); + } + } + None + }) +} + +// --------------------------------------------------------------------- STT + +fn stt_unavailable() -> SpeechError { + SpeechError::Unavailable("linux has no system speech recognizer".to_string()) +} + +pub(crate) fn stt_available() -> bool { + false +} + +pub(crate) fn stt_capabilities() -> SttCapabilities { + SttCapabilities::default() +} + +pub(crate) fn stt_prepare(_language: &str) -> Result<(), SpeechError> { + Err(stt_unavailable()) +} + +pub(crate) fn stt_transcribe(_samples_16k: &[f32], _options: &SttOptions) -> Result { + Err(stt_unavailable()) +} + +pub(crate) fn stt_listen(_options: &SttOptions, _sink: Sender) -> Result { + Err(stt_unavailable()) +} + +// --------------------------------------------------------------------- TTS + +pub(crate) fn tts_available() -> bool { + espeak_binary().is_some() +} + +/// Parse the `Pty Language Age/Gender VoiceName File Other Languages` table +/// printed by `espeak-ng --voices` / `espeak --voices`. The header line is +/// skipped by position (it never has a usable data shape anyway). +fn parse_voices_table(output: &str) -> Vec { + let mut voices = Vec::new(); + for (i, line) in output.lines().enumerate() { + if i == 0 { + continue; + } + let fields: Vec<&str> = line.split_whitespace().collect(); + if fields.len() < 4 { + continue; + } + let language = espeak_language_to_bcp47(fields[1]); + let gender = match fields[2].chars().last() { + Some('M') => VoiceGender::Male, + Some('F') => VoiceGender::Female, + _ => VoiceGender::Unknown, + }; + let name = fields[3].to_string(); + voices.push(Voice { id: name.clone(), name, language, gender, offline: true }); + } + voices +} + +/// `"en-gb"` -> `"en-GB"`: keep the language part as espeak wrote it, +/// uppercase the region/variant suffix. +fn espeak_language_to_bcp47(language_col: &str) -> String { + match language_col.split_once('-') { + Some((lang, region)) => format!("{lang}-{}", region.to_ascii_uppercase()), + None => language_col.to_string(), + } +} + +pub(crate) fn tts_voices() -> Vec { + let Some(bin) = espeak_binary() else { return Vec::new() }; + match Command::new(bin).arg("--voices").output() { + Ok(output) if output.status.success() => { + parse_voices_table(&String::from_utf8_lossy(&output.stdout)) + } + _ => Vec::new(), + } +} + +/// espeak `-s` words-per-minute: 175 is its own default at `rate == 1.0`. +fn wpm_from_rate(rate: f32) -> u32 { + (175.0 * rate).clamp(80.0, 450.0).round() as u32 +} + +/// espeak `-p` pitch, 0..99: 50 is its own default at `pitch == 1.0`. +fn pitch_from_pitch(pitch: f32) -> u32 { + (50.0 * pitch).clamp(0.0, 99.0).round() as u32 +} + +/// Run ` --stdout -v -s -p `, feeding `text` on +/// stdin (never argv — it can be long and start with `-`). Reader threads +/// drain stdout/stderr concurrently so a large WAV can't deadlock the pipe; +/// the main thread only polls `try_wait`, killing the child past the cap. +fn run_espeak(bin: &str, voice: &str, wpm: u32, pitch: u32, text: &str) -> Result, SpeechError> { + let mut child = Command::new(bin) + .args(["--stdout", "-v", voice, "-s", &wpm.to_string(), "-p", &pitch.to_string()]) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .map_err(|e| SpeechError::Backend(format!("failed to spawn {bin}: {e}")))?; + + if let Some(mut stdin) = child.stdin.take() { + let _ = stdin.write_all(text.as_bytes()); + // dropped here, closing the pipe so espeak sees EOF on stdin + } + + let mut stdout = child.stdout.take().expect("stdout was piped"); + let mut stderr = child.stderr.take().expect("stderr was piped"); + let (stdout_tx, stdout_rx) = mpsc::channel(); + let stdout_reader = thread::spawn(move || { + let mut buf = Vec::new(); + let _ = stdout.read_to_end(&mut buf); + let _ = stdout_tx.send(buf); + }); + let (stderr_tx, stderr_rx) = mpsc::channel(); + let stderr_reader = thread::spawn(move || { + let mut buf = String::new(); + let _ = stderr.read_to_string(&mut buf); + let _ = stderr_tx.send(buf); + }); + + let deadline = Instant::now() + SYNTHESIZE_TIMEOUT; + let status = loop { + match child.try_wait() { + Ok(Some(status)) => break status, + Ok(None) => { + if Instant::now() >= deadline { + let _ = child.kill(); + let _ = child.wait(); + return Err(SpeechError::Timeout); + } + thread::sleep(Duration::from_millis(20)); + } + Err(e) => return Err(SpeechError::Backend(format!("wait failed: {e}"))), + } + }; + + let stdout_bytes = stdout_reader.join().ok().and_then(|_| stdout_rx.recv().ok()).unwrap_or_default(); + let stderr_text = stderr_reader.join().ok().and_then(|_| stderr_rx.recv().ok()).unwrap_or_default(); + + if !status.success() { + return Err(SpeechError::Backend(stderr_text.trim().to_string())); + } + Ok(stdout_bytes) +} + +/// Some espeak-ng builds write a `data` chunk size of `0` (or `0xFFFFFFFF`) +/// to `--stdout` since they don't know the final length up front. Patch it +/// to "rest of file" before handing the bytes to `wav::decode`, which +/// otherwise reads a zero-length chunk and reports no samples. +fn patch_wav_data_size(bytes: &mut [u8]) { + if bytes.len() < 12 || &bytes[0..4] != b"RIFF" || &bytes[8..12] != b"WAVE" { + return; + } + let mut pos = 12; + while pos + 8 <= bytes.len() { + let id = [bytes[pos], bytes[pos + 1], bytes[pos + 2], bytes[pos + 3]]; + let size = u32::from_le_bytes([bytes[pos + 4], bytes[pos + 5], bytes[pos + 6], bytes[pos + 7]]); + let body_start = pos + 8; + if &id == b"data" { + if size == 0 || size == 0xFFFF_FFFF { + let actual = (bytes.len() - body_start) as u32; + bytes[pos + 4..pos + 8].copy_from_slice(&actual.to_le_bytes()); + } + return; + } + let body_end = body_start.saturating_add(size as usize).min(bytes.len()); + pos = body_end + (size as usize & 1); + } +} + +fn decode_espeak_wav(mut bytes: Vec) -> Result { + patch_wav_data_size(&mut bytes); + let audio = crate::wav::decode(&bytes).map_err(SpeechError::Backend)?; + if audio.samples.is_empty() { + return Err(SpeechError::Empty); + } + Ok(audio) +} + +pub(crate) fn tts_synthesize(text: &str, options: &TtsOptions) -> Result { + let bin = espeak_binary() + .ok_or_else(|| SpeechError::Unavailable("espeak-ng (or espeak) is not installed".to_string()))?; + let wpm = wpm_from_rate(options.rate); + let pitch = pitch_from_pitch(options.pitch); + + // options.voice wins outright; otherwise derive an espeak voice name + // from the language, and if espeak rejects that (unknown region), fall + // back to just the bare language part. + let (voice, derived) = match options.voice.as_deref() { + Some(v) if !v.is_empty() => (v.to_string(), false), + _ => (bcp47(&options.language).to_ascii_lowercase(), true), + }; + + match run_espeak(bin, &voice, wpm, pitch, text) { + Ok(wav) => decode_espeak_wav(wav), + Err(_) if derived && voice.contains('-') => { + let lang_only = voice.split('-').next().unwrap_or(&voice).to_string(); + let wav = run_espeak(bin, &lang_only, wpm, pitch, text)?; + decode_espeak_wav(wav) + } + Err(err) => Err(err), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + const SAMPLE_VOICES_TABLE: &str = "\ +Pty Language Age/Gender VoiceName File Other Languages + 5 en-gb M english en/en-gb + 5 en-us F english-us en/en-us + 5 fr 5M french europe/fr + 5 de - german de +"; + + #[test] + fn parses_the_voices_table() { + let voices = parse_voices_table(SAMPLE_VOICES_TABLE); + assert_eq!(voices.len(), 4); + + assert_eq!(voices[0].id, "english"); + assert_eq!(voices[0].name, "english"); + assert_eq!(voices[0].language, "en-GB"); + assert_eq!(voices[0].gender, VoiceGender::Male); + assert!(voices[0].offline); + + assert_eq!(voices[1].language, "en-US"); + assert_eq!(voices[1].gender, VoiceGender::Female); + + // "5M" (age + gender) still resolves to Male via the trailing letter. + assert_eq!(voices[2].gender, VoiceGender::Male); + + // "-" (no gender given) resolves to Unknown, and a bare language + // code with no region passes through unchanged. + assert_eq!(voices[3].gender, VoiceGender::Unknown); + assert_eq!(voices[3].language, "de"); + } + + #[test] + fn empty_or_header_only_output_yields_no_voices() { + assert!(parse_voices_table("").is_empty()); + assert!(parse_voices_table("Pty Language Age/Gender VoiceName File Other Languages\n").is_empty()); + } + + #[test] + fn wpm_from_rate_clamps_to_espeak_range() { + assert_eq!(wpm_from_rate(1.0), 175); + assert_eq!(wpm_from_rate(0.0), 80); + assert_eq!(wpm_from_rate(0.1), 80); + assert_eq!(wpm_from_rate(10.0), 450); + assert_eq!(wpm_from_rate(2.0), 350); + } + + #[test] + fn pitch_from_pitch_clamps_to_espeak_range() { + assert_eq!(pitch_from_pitch(1.0), 50); + assert_eq!(pitch_from_pitch(0.0), 0); + assert_eq!(pitch_from_pitch(-5.0), 0); + assert_eq!(pitch_from_pitch(5.0), 99); + } + + #[test] + fn patches_a_zero_size_data_chunk_to_rest_of_file() { + let mut bytes = Vec::new(); + bytes.extend_from_slice(b"RIFF"); + bytes.extend_from_slice(&0u32.to_le_bytes()); // riff size: irrelevant to decode() + bytes.extend_from_slice(b"WAVE"); + bytes.extend_from_slice(b"fmt "); + bytes.extend_from_slice(&16u32.to_le_bytes()); + bytes.extend_from_slice(&1u16.to_le_bytes()); // PCM + bytes.extend_from_slice(&1u16.to_le_bytes()); // mono + bytes.extend_from_slice(&22_050u32.to_le_bytes()); + bytes.extend_from_slice(&(22_050u32 * 2).to_le_bytes()); + bytes.extend_from_slice(&2u16.to_le_bytes()); + bytes.extend_from_slice(&16u16.to_le_bytes()); + bytes.extend_from_slice(b"data"); + bytes.extend_from_slice(&0u32.to_le_bytes()); // the espeak bug: size 0 + bytes.extend_from_slice(&1i16.to_le_bytes()); + bytes.extend_from_slice(&2i16.to_le_bytes()); + bytes.extend_from_slice(&3i16.to_le_bytes()); + + assert_eq!(u32::from_le_bytes([bytes[40], bytes[41], bytes[42], bytes[43]]), 0); + // Unpatched, wav::decode sees a 0-length data chunk and no samples. + assert_eq!(crate::wav::decode(&bytes).unwrap().samples.len(), 0); + + patch_wav_data_size(&mut bytes); + + assert_eq!(u32::from_le_bytes([bytes[40], bytes[41], bytes[42], bytes[43]]), 6); + let decoded = crate::wav::decode(&bytes).unwrap(); + assert_eq!(decoded.samples.len(), 3); + assert_eq!(decoded.sample_rate, 22_050); + } + + #[test] + fn patch_leaves_a_correctly_sized_data_chunk_alone() { + let mut bytes = Vec::new(); + bytes.extend_from_slice(b"RIFF"); + bytes.extend_from_slice(&38u32.to_le_bytes()); + bytes.extend_from_slice(b"WAVE"); + bytes.extend_from_slice(b"fmt "); + bytes.extend_from_slice(&16u32.to_le_bytes()); + bytes.extend_from_slice(&1u16.to_le_bytes()); + bytes.extend_from_slice(&1u16.to_le_bytes()); + bytes.extend_from_slice(&22_050u32.to_le_bytes()); + bytes.extend_from_slice(&(22_050u32 * 2).to_le_bytes()); + bytes.extend_from_slice(&2u16.to_le_bytes()); + bytes.extend_from_slice(&16u16.to_le_bytes()); + bytes.extend_from_slice(b"data"); + bytes.extend_from_slice(&2u32.to_le_bytes()); + bytes.extend_from_slice(&1i16.to_le_bytes()); + + patch_wav_data_size(&mut bytes); + assert_eq!(u32::from_le_bytes([bytes[40], bytes[41], bytes[42], bytes[43]]), 2); + } +} diff --git a/libs/system_speech/src/platform/mod.rs b/libs/system_speech/src/platform/mod.rs new file mode 100644 index 000000000..651a39f43 --- /dev/null +++ b/libs/system_speech/src/platform/mod.rs @@ -0,0 +1,51 @@ +//! One module per OS, all implementing the same nine items. `none` is the +//! reference: every function here must be safe to call on any platform. +//! +//! Contract (implemented by each platform file with these exact signatures): +//! ```ignore +//! pub(crate) const STT_ENGINE: &str; +//! pub(crate) const TTS_ENGINE: &str; +//! pub(crate) fn stt_available() -> bool; +//! pub(crate) fn stt_capabilities() -> SttCapabilities; +//! pub(crate) fn stt_prepare(language: &str) -> Result<(), SpeechError>; +//! pub(crate) fn stt_transcribe(samples_16k: &[f32], options: &SttOptions) -> Result; +//! pub(crate) fn stt_listen(options: &SttOptions, sink: Sender) -> Result; +//! pub(crate) fn tts_available() -> bool; +//! pub(crate) fn tts_voices() -> Vec; +//! pub(crate) fn tts_synthesize(text: &str, options: &TtsOptions) -> Result; +//! ``` + +#[cfg(all(any(target_os = "macos", target_os = "ios"), apple_speech))] +mod apple; +#[cfg(all(any(target_os = "macos", target_os = "ios"), apple_speech))] +pub(crate) use apple::*; + +#[cfg(windows)] +mod windows; +#[cfg(windows)] +pub(crate) use windows::*; + +#[cfg(target_os = "android")] +mod android; +#[cfg(target_os = "android")] +pub(crate) use android::*; + +#[cfg(all(target_os = "linux", not(target_os = "android")))] +mod linux; +#[cfg(all(target_os = "linux", not(target_os = "android")))] +pub(crate) use linux::*; + +#[cfg(not(any( + all(any(target_os = "macos", target_os = "ios"), apple_speech), + windows, + target_os = "android", + all(target_os = "linux", not(target_os = "android")), +)))] +mod none; +#[cfg(not(any( + all(any(target_os = "macos", target_os = "ios"), apple_speech), + windows, + target_os = "android", + all(target_os = "linux", not(target_os = "android")), +)))] +pub(crate) use none::*; diff --git a/libs/system_speech/src/platform/none.rs b/libs/system_speech/src/platform/none.rs new file mode 100644 index 000000000..2c8d20cb8 --- /dev/null +++ b/libs/system_speech/src/platform/none.rs @@ -0,0 +1,47 @@ +//! No OS speech services here (web, Apple without the Swift bridge, OpenHarmony). +//! Everything reports unavailable; nothing panics. + +use crate::{ + ListenHandle, SpeechAudio, SpeechError, SttCapabilities, SttEvent, SttOptions, Transcript, + TtsOptions, Voice, +}; +use std::sync::mpsc::Sender; + +pub(crate) const STT_ENGINE: &str = "none"; +pub(crate) const TTS_ENGINE: &str = "none"; + +fn unavailable() -> SpeechError { + SpeechError::Unavailable("no system speech engine on this platform".to_string()) +} + +pub(crate) fn stt_available() -> bool { + false +} + +pub(crate) fn stt_capabilities() -> SttCapabilities { + SttCapabilities::default() +} + +pub(crate) fn stt_prepare(_language: &str) -> Result<(), SpeechError> { + Err(unavailable()) +} + +pub(crate) fn stt_transcribe(_samples_16k: &[f32], _options: &SttOptions) -> Result { + Err(unavailable()) +} + +pub(crate) fn stt_listen(_options: &SttOptions, _sink: Sender) -> Result { + Err(unavailable()) +} + +pub(crate) fn tts_available() -> bool { + false +} + +pub(crate) fn tts_voices() -> Vec { + Vec::new() +} + +pub(crate) fn tts_synthesize(_text: &str, _options: &TtsOptions) -> Result { + Err(unavailable()) +} diff --git a/libs/system_speech/src/platform/windows.rs b/libs/system_speech/src/platform/windows.rs new file mode 100644 index 000000000..a8ce1a882 --- /dev/null +++ b/libs/system_speech/src/platform/windows.rs @@ -0,0 +1,506 @@ +//! Windows: `Windows.Media.SpeechSynthesis` for TTS and +//! `Windows.Media.SpeechRecognition` for STT. +//! +//! The synthesizer renders into a WinRT WAV stream that [`crate::wav`] turns +//! into PCM. The recognizer has no PCM-input API at all — it owns the +//! microphone itself — so [`stt_transcribe`] is unsupported here and +//! [`stt_listen`] carries the whole STT story. +//! +//! Everything runs on ordinary worker threads. No `RoInitialize` call is +//! needed: `windows-core`'s factory cache falls back to `CoIncrementMTAUsage` +//! when a class is activated on a thread that has not initialised COM +//! (`libs/windows/windows-core/src/imp/factory_cache.rs`), so activation is +//! apartment-agnostic. + +use crate::{ + bcp47, ListenHandle, SpeechAudio, SpeechError, SttCapabilities, SttEvent, SttOptions, + Transcript, TtsOptions, Voice, VoiceGender, +}; +use std::sync::mpsc::{self, Sender, TryRecvError}; +use std::sync::OnceLock; +use std::time::{Duration, Instant}; +use windows::Foundation::{TimeSpan, TypedEventHandler}; +use windows::Globalization::Language; +use windows::Media::SpeechRecognition::{ + SpeechContinuousRecognitionCompletedEventArgs, + SpeechContinuousRecognitionResultGeneratedEventArgs, SpeechContinuousRecognitionSession, + SpeechRecognitionConfidence, SpeechRecognitionHypothesisGeneratedEventArgs, + SpeechRecognitionResultStatus, SpeechRecognizer, +}; +use windows::Media::SpeechSynthesis::{ + SpeechSynthesisStream, SpeechSynthesizer, VoiceGender as WinVoiceGender, VoiceInformation, +}; +use windows::Storage::Streams::DataReader; +use windows_core::{RuntimeType, HSTRING}; +use windows_future::{AsyncStatus, IAsyncAction, IAsyncOperation}; + +pub(crate) const STT_ENGINE: &str = "windows-speechrecognition"; +pub(crate) const TTS_ENGINE: &str = "windows-speechsynthesis"; + +/// One WinRT tick is 100 ns. +const TICKS_PER_SEC: i64 = 10_000_000; + +/// `SPERR_SPEECH_PRIVACY_POLICY_NOT_ACCEPTED`. The machine has "online speech +/// recognition" turned off in Settings → Privacy, so the recognizer refuses to +/// start. That is a permission problem, not a broken engine. +const SPERR_SPEECH_PRIVACY_POLICY_NOT_ACCEPTED: i32 = 0x8004_5509_u32 as i32; +/// `HRESULT_FROM_WIN32(ERROR_TIMEOUT)`, for a wait that outlived its budget. +const E_TIMEOUT: windows_core::HRESULT = windows_core::HRESULT(0x8007_05B4_u32 as i32); + +const SYNTHESIZE_TIMEOUT: Duration = Duration::from_secs(60); +const STREAM_TIMEOUT: Duration = Duration::from_secs(30); +const COMPILE_TIMEOUT: Duration = Duration::from_secs(30); +const START_TIMEOUT: Duration = Duration::from_secs(15); +const STOP_TIMEOUT: Duration = Duration::from_secs(10); +/// How long we still wait for `Completed` after asking the session to stop. +const DRAIN_TIMEOUT: Duration = Duration::from_secs(5); + +fn backend(err: windows_core::Error) -> SpeechError { + SpeechError::Backend(format!("{err}")) +} + +// ------------------------------------------------------------------ waiting + +/// Poll a WinRT async object to completion. `windows-future` only exposes its +/// blocking join behind a spin loop, and its `IntoFuture` needs an executor; +/// this crate's contract is "block the worker thread", so it sleeps instead. +fn wait_ready( + status: impl Fn() -> windows_core::Result, + timeout: Duration, +) -> windows_core::Result<()> { + let deadline = Instant::now() + timeout; + while status()? == AsyncStatus::Started { + if Instant::now() >= deadline { + return Err(windows_core::Error::from_hresult(E_TIMEOUT)); + } + std::thread::sleep(Duration::from_millis(2)); + } + Ok(()) +} + +/// `GetResults` after the wait reports the engine's own failure HRESULT, so an +/// errored or cancelled operation comes back as `Err` without a second look. +fn wait_operation( + operation: &IAsyncOperation, + timeout: Duration, +) -> windows_core::Result { + wait_ready(|| operation.Status(), timeout)?; + operation.GetResults() +} + +fn wait_action(action: &IAsyncAction, timeout: Duration) -> windows_core::Result<()> { + wait_ready(|| action.Status(), timeout)?; + action.GetResults() +} + +// --------------------------------------------------------------------- TTS + +pub(crate) fn tts_available() -> bool { + static PROBE: OnceLock = OnceLock::new(); + *PROBE.get_or_init(|| SpeechSynthesizer::new().is_ok()) +} + +pub(crate) fn tts_voices() -> Vec { + installed_voices() + .iter() + .filter_map(|voice| { + Some(Voice { + id: voice.Id().ok()?.to_string_lossy(), + name: voice.DisplayName().ok()?.to_string_lossy(), + language: voice.Language().ok()?.to_string_lossy(), + gender: match voice.Gender() { + Ok(WinVoiceGender::Male) => VoiceGender::Male, + Ok(WinVoiceGender::Female) => VoiceGender::Female, + _ => VoiceGender::Unknown, + }, + // Every installed SAPI voice renders locally. + offline: true, + }) + }) + .collect() +} + +fn installed_voices() -> Vec { + match SpeechSynthesizer::AllVoices() { + Ok(voices) => voices.into_iter().collect(), + Err(_) => Vec::new(), + } +} + +pub(crate) fn tts_synthesize(text: &str, options: &TtsOptions) -> Result { + let synth = SpeechSynthesizer::new().map_err(backend)?; + + if let Some(voice) = pick_voice(&installed_voices(), options) { + synth.SetVoice(&voice).map_err(backend)?; + } + + // `SpeechSynthesizerOptions`' rate and pitch arrived in Windows 10 1703; on + // anything older the QI fails and the utterance plays at normal speed. + if let Ok(synth_options) = synth.Options() { + let _ = synth_options.SetSpeakingRate(options.rate.clamp(0.5, 6.0) as f64); + let _ = synth_options.SetAudioPitch(options.pitch.clamp(0.5, 2.0) as f64); + } + + let operation = synth + .SynthesizeTextToStreamAsync(&HSTRING::from(text)) + .map_err(backend)?; + let stream = wait_operation(&operation, SYNTHESIZE_TIMEOUT).map_err(backend)?; + + let bytes = read_stream(&stream).map_err(backend)?; + let audio = crate::wav::decode(&bytes).map_err(SpeechError::Backend)?; + if audio.is_empty() { + return Err(SpeechError::Empty); + } + Ok(audio) +} + +/// The requested voice by id, else the first voice whose language matches — +/// exactly first, then on the language prefix, so `"en"` finds `en-GB`. +fn pick_voice(voices: &[VoiceInformation], options: &TtsOptions) -> Option { + if let Some(wanted) = options.voice.as_deref().filter(|id| !id.is_empty()) { + return voices + .iter() + .find(|voice| voice.Id().map(|id| id.to_string_lossy() == wanted).unwrap_or(false)) + .cloned(); + } + let wanted = bcp47(&options.language).to_ascii_lowercase(); + let prefix = wanted.split('-').next().unwrap_or(&wanted).to_string(); + let language_of = |voice: &VoiceInformation| { + voice.Language().map(|l| l.to_string_lossy().to_ascii_lowercase()).unwrap_or_default() + }; + voices + .iter() + .find(|voice| language_of(voice) == wanted) + .or_else(|| { + voices + .iter() + .find(|voice| language_of(voice).split('-').next() == Some(prefix.as_str())) + }) + .cloned() +} + +/// Drain a `SpeechSynthesisStream` into the RIFF/WAVE bytes it holds. +fn read_stream(stream: &SpeechSynthesisStream) -> windows_core::Result> { + let size = stream.Size()?; + if size == 0 { + return Ok(Vec::new()); + } + let reader = DataReader::CreateDataReader(stream)?; + let load = reader.LoadAsync(size.min(u32::MAX as u64) as u32)?; + // `LoadAsync` reports how much it actually buffered, which is what + // `ReadBytes` will hand over. + let loaded = wait_operation(&load, STREAM_TIMEOUT)?; + let mut bytes = vec![0u8; loaded as usize]; + reader.ReadBytes(&mut bytes)?; + Ok(bytes) +} + +// --------------------------------------------------------------------- STT + +pub(crate) fn stt_capabilities() -> SttCapabilities { + SttCapabilities { + pcm_input: false, + engine_mic: true, + partial_results: true, + offline: false, + } +} + +pub(crate) fn stt_available() -> bool { + static PROBE: OnceLock = OnceLock::new(); + *PROBE.get_or_init(|| SpeechRecognizer::new().is_ok()) +} + +pub(crate) fn stt_prepare(language: &str) -> Result<(), SpeechError> { + let recognizer = recognizer_for(language)?; + compile_constraints(&recognizer) +} + +pub(crate) fn stt_transcribe( + _samples_16k: &[f32], + _options: &SttOptions, +) -> Result { + Err(SpeechError::Unsupported( + "the Windows recognizer only listens on the microphone; use listen", + )) +} + +pub(crate) fn stt_listen( + options: &SttOptions, + sink: Sender, +) -> Result { + let (ready_tx, ready_rx) = mpsc::channel::>(); + let (stop_tx, stop_rx) = mpsc::channel::<()>(); + let language = options.language.clone(); + let partial_results = options.partial_results; + + std::thread::Builder::new() + .name("system-speech-listen".to_string()) + .spawn(move || listen_worker(language, partial_results, sink, ready_tx, stop_rx)) + .map_err(|err| SpeechError::Backend(format!("cannot spawn listen thread: {err}")))?; + + // Block until the session is actually running so a missing microphone or a + // refused privacy policy comes back as an error rather than as an event. + match ready_rx.recv() { + Ok(Ok(())) => {} + Ok(Err(err)) => return Err(err), + Err(_) => return Err(SpeechError::Backend("listen thread stopped early".to_string())), + } + + // The closure runs on whichever thread drops the handle, and WinRT objects + // made on the worker must only be touched there — so it just signals. + Ok(ListenHandle::new(move || { + let _ = stop_tx.send(()); + })) +} + +fn recognizer_for(language: &str) -> Result { + // Settle "is there an engine at all?" first, so the mapping below can read + // a failed `Create` as a missing language pack rather than a missing engine. + if !stt_available() { + return Err(SpeechError::Unavailable( + "no Windows speech recognizer on this machine".to_string(), + )); + } + let tag = HSTRING::from(bcp47(language)); + let language = Language::CreateLanguage(&tag).map_err(backend)?; + SpeechRecognizer::Create(&language).map_err(|err| { + if err.code().0 == SPERR_SPEECH_PRIVACY_POLICY_NOT_ACCEPTED { + SpeechError::PermissionDenied + } else { + // Construction only fails for a language with no recognizer pack + // installed; anything else would already have failed the probe. + SpeechError::Unsupported("language not supported by the Windows recognizer") + } + }) +} + +/// Compile the recognizer's grammar. With no constraints added that is the +/// built-in dictation grammar, which is what a free-form transcript wants. +fn compile_constraints(recognizer: &SpeechRecognizer) -> Result<(), SpeechError> { + let operation = recognizer.CompileConstraintsAsync().map_err(compile_error)?; + let result = wait_operation(&operation, COMPILE_TIMEOUT).map_err(compile_error)?; + match result.Status().map_err(backend)? { + SpeechRecognitionResultStatus::Success => Ok(()), + SpeechRecognitionResultStatus::TopicLanguageNotSupported + | SpeechRecognitionResultStatus::GrammarLanguageMismatch => Err(SpeechError::Unsupported( + "language not supported by the Windows recognizer", + )), + SpeechRecognitionResultStatus::UserCanceled => Err(SpeechError::Cancelled), + status => Err(SpeechError::Backend(format!( + "constraint compilation failed with status {}", + status.0 + ))), + } +} + +fn compile_error(err: windows_core::Error) -> SpeechError { + if err.code().0 == SPERR_SPEECH_PRIVACY_POLICY_NOT_ACCEPTED { + SpeechError::PermissionDenied + } else { + backend(err) + } +} + +/// Give the engine room to hear a first word, but cut the utterance shortly +/// after the speaker stops. A rejected value leaves the platform default. +fn apply_timeouts(recognizer: &SpeechRecognizer) { + let Ok(timeouts) = recognizer.Timeouts() else { + return; + }; + let _ = timeouts.SetInitialSilenceTimeout(TimeSpan { Duration: 5 * TICKS_PER_SEC }); + let _ = timeouts.SetEndSilenceTimeout(TimeSpan { Duration: 12 * TICKS_PER_SEC / 10 }); + let _ = timeouts.SetBabbleTimeout(TimeSpan { Duration: 10 * TICKS_PER_SEC }); +} + +fn listen_worker( + language: String, + partial_results: bool, + sink: Sender, + ready: Sender>, + stop_rx: mpsc::Receiver<()>, +) { + let recognizer = match recognizer_for(&language) { + Ok(recognizer) => recognizer, + Err(err) => { + let _ = ready.send(Err(err)); + return; + } + }; + if let Err(err) = compile_constraints(&recognizer) { + let _ = ready.send(Err(err)); + return; + } + apply_timeouts(&recognizer); + + let session = match recognizer.ContinuousRecognitionSession() { + Ok(session) => session, + Err(err) => { + let _ = ready.send(Err(backend(err))); + return; + } + }; + + let (done_tx, done_rx) = mpsc::channel::(); + + let result_sink = sink.clone(); + let on_result = TypedEventHandler::< + SpeechContinuousRecognitionSession, + SpeechContinuousRecognitionResultGeneratedEventArgs, + >::new(move |_session, args| { + if let Some(args) = args.as_ref() { + if let Ok(result) = args.Result() { + // `Rejected` is the engine saying "that was noise". + let confidence = result.Confidence().unwrap_or(SpeechRecognitionConfidence::Rejected); + if confidence != SpeechRecognitionConfidence::Rejected { + if let Ok(text) = result.Text() { + let transcript = Transcript::from_text(text.to_string_lossy()); + if !transcript.is_empty() { + let _ = result_sink.send(SttEvent::Final(transcript)); + } + } + } + } + } + Ok(()) + }); + + let on_completed = TypedEventHandler::< + SpeechContinuousRecognitionSession, + SpeechContinuousRecognitionCompletedEventArgs, + >::new(move |_session, args| { + let status = args + .as_ref() + .and_then(|args| args.Status().ok()) + .unwrap_or(SpeechRecognitionResultStatus::Unknown); + let _ = done_tx.send(status); + Ok(()) + }); + + let result_token = match session.ResultGenerated(&on_result) { + Ok(token) => token, + Err(err) => { + let _ = ready.send(Err(backend(err))); + return; + } + }; + let completed_token = match session.Completed(&on_completed) { + Ok(token) => token, + Err(err) => { + let _ = session.RemoveResultGenerated(result_token); + let _ = ready.send(Err(backend(err))); + return; + } + }; + + let mut hypothesis_token = 0i64; + if partial_results { + let partial_sink = sink.clone(); + let on_hypothesis = TypedEventHandler::< + SpeechRecognizer, + SpeechRecognitionHypothesisGeneratedEventArgs, + >::new(move |_recognizer, args| { + if let Some(args) = args.as_ref() { + if let Ok(hypothesis) = args.Hypothesis() { + if let Ok(text) = hypothesis.Text() { + let _ = partial_sink.send(SttEvent::Partial(text.to_string_lossy())); + } + } + } + Ok(()) + }); + hypothesis_token = recognizer.HypothesisGenerated(&on_hypothesis).unwrap_or(0); + } + + let start = session + .StartAsync() + .and_then(|action| wait_action(&action, START_TIMEOUT)); + if let Err(err) = start { + remove_handlers(&recognizer, &session, result_token, completed_token, hypothesis_token); + let _ = ready.send(Err(compile_error(err))); + return; + } + let _ = ready.send(Ok(())); + + // From here the session exists, so exactly one `Ended` must reach the sink. + let mut stopped_by_caller = false; + let mut drain_deadline: Option = None; + let status = loop { + match done_rx.try_recv() { + Ok(status) => break Some(status), + Err(TryRecvError::Disconnected) => break None, + Err(TryRecvError::Empty) => {} + } + if drain_deadline.is_none() && !matches!(stop_rx.try_recv(), Err(TryRecvError::Empty)) { + stopped_by_caller = true; + // `StopAsync` lets the engine emit whatever it already has; the + // `Completed` event still fires, so keep waiting for it. + stop_session(&session); + drain_deadline = Some(Instant::now() + DRAIN_TIMEOUT); + } + if drain_deadline.is_some_and(|deadline| Instant::now() >= deadline) { + break None; + } + std::thread::sleep(Duration::from_millis(20)); + }; + + remove_handlers(&recognizer, &session, result_token, completed_token, hypothesis_token); + + if let Some(err) = status.and_then(|status| status_error(status, stopped_by_caller)) { + let _ = sink.send(SttEvent::Error(err)); + } + let _ = sink.send(SttEvent::Ended); +} + +fn stop_session(session: &SpeechContinuousRecognitionSession) { + let stopped = session + .StopAsync() + .and_then(|action| wait_action(&action, STOP_TIMEOUT)); + if stopped.is_err() { + let _ = session + .CancelAsync() + .and_then(|action| wait_action(&action, STOP_TIMEOUT)); + } +} + +fn remove_handlers( + recognizer: &SpeechRecognizer, + session: &SpeechContinuousRecognitionSession, + result_token: i64, + completed_token: i64, + hypothesis_token: i64, +) { + let _ = session.RemoveResultGenerated(result_token); + let _ = session.RemoveCompleted(completed_token); + if hypothesis_token != 0 { + let _ = recognizer.RemoveHypothesisGenerated(hypothesis_token); + } +} + +/// A finished session's status, as an event — or `None` when the ending was +/// the ordinary one (success, our own stop, or the silence timeout firing). +fn status_error( + status: SpeechRecognitionResultStatus, + stopped_by_caller: bool, +) -> Option { + match status { + SpeechRecognitionResultStatus::Success + | SpeechRecognitionResultStatus::TimeoutExceeded => None, + SpeechRecognitionResultStatus::UserCanceled if stopped_by_caller => None, + SpeechRecognitionResultStatus::UserCanceled => Some(SpeechError::Cancelled), + SpeechRecognitionResultStatus::MicrophoneUnavailable => { + Some(SpeechError::Unavailable("microphone unavailable".to_string())) + } + SpeechRecognitionResultStatus::NetworkFailure => Some(SpeechError::Backend( + "the Windows recognizer lost its network connection".to_string(), + )), + SpeechRecognitionResultStatus::TopicLanguageNotSupported + | SpeechRecognitionResultStatus::GrammarLanguageMismatch => Some(SpeechError::Unsupported( + "language not supported by the Windows recognizer", + )), + status => Some(SpeechError::Backend(format!( + "recognition ended with status {}", + status.0 + ))), + } +} diff --git a/libs/system_speech/src/wav.rs b/libs/system_speech/src/wav.rs new file mode 100644 index 000000000..b2132382d --- /dev/null +++ b/libs/system_speech/src/wav.rs @@ -0,0 +1,157 @@ +//! RIFF/WAVE in and out. The Windows, Android and Linux engines all hand back +//! WAV bytes (a WinRT stream, a file from `synthesizeToFile`, `espeak-ng +//! --stdout`); this turns them into [`SpeechAudio`] and back. + +use crate::SpeechAudio; + +/// Decode PCM WAV (8/16/24/32-bit integer or 32-bit float, any channel +/// count) to mono `f32`. Multi-channel input is averaged down. +pub fn decode(bytes: &[u8]) -> Result { + if bytes.len() < 12 || &bytes[0..4] != b"RIFF" || &bytes[8..12] != b"WAVE" { + return Err("not a RIFF/WAVE file".to_string()); + } + let mut pos = 12; + let mut format_tag = 0u16; + let mut channels = 0u16; + let mut sample_rate = 0u32; + let mut bits = 0u16; + let mut data: Option<&[u8]> = None; + while pos + 8 <= bytes.len() { + let id = &bytes[pos..pos + 4]; + let size = u32::from_le_bytes([bytes[pos + 4], bytes[pos + 5], bytes[pos + 6], bytes[pos + 7]]) as usize; + let body_start = pos + 8; + let body_end = body_start.saturating_add(size).min(bytes.len()); + let body = &bytes[body_start..body_end]; + match id { + b"fmt " => { + if body.len() < 16 { + return Err("fmt chunk too short".to_string()); + } + format_tag = u16::from_le_bytes([body[0], body[1]]); + channels = u16::from_le_bytes([body[2], body[3]]); + sample_rate = u32::from_le_bytes([body[4], body[5], body[6], body[7]]); + bits = u16::from_le_bytes([body[14], body[15]]); + // WAVE_FORMAT_EXTENSIBLE: the real tag is the sub-format GUID's first two bytes. + if format_tag == 0xFFFE && body.len() >= 26 { + format_tag = u16::from_le_bytes([body[24], body[25]]); + } + } + b"data" => { + data = Some(body); + } + _ => {} + } + // Chunks are word-aligned. + pos = body_start + size + (size & 1); + } + let data = data.ok_or_else(|| "no data chunk".to_string())?; + if channels == 0 || sample_rate == 0 { + return Err("missing fmt chunk".to_string()); + } + let channels = channels as usize; + let samples: Vec = match (format_tag, bits) { + (1, 8) => data.iter().map(|&b| (b as f32 - 128.0) / 128.0).collect(), + (1, 16) => data + .chunks_exact(2) + .map(|c| i16::from_le_bytes([c[0], c[1]]) as f32 / 32768.0) + .collect(), + (1, 24) => data + .chunks_exact(3) + .map(|c| (i32::from_le_bytes([0, c[0], c[1], c[2]]) >> 8) as f32 / 8_388_608.0) + .collect(), + (1, 32) => data + .chunks_exact(4) + .map(|c| i32::from_le_bytes([c[0], c[1], c[2], c[3]]) as f32 / 2_147_483_648.0) + .collect(), + (3, 32) => data + .chunks_exact(4) + .map(|c| f32::from_le_bytes([c[0], c[1], c[2], c[3]])) + .collect(), + (3, 64) => data + .chunks_exact(8) + .map(|c| f64::from_le_bytes([c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]]) as f32) + .collect(), + (tag, bits) => return Err(format!("unsupported wav format tag {tag} / {bits} bits")), + }; + let mono = if channels == 1 { + samples + } else { + samples + .chunks_exact(channels) + .map(|frame| frame.iter().sum::() / channels as f32) + .collect() + }; + Ok(SpeechAudio { samples: mono, sample_rate }) +} + +/// Encode mono `f32` as 16-bit PCM WAV. +pub fn encode_pcm16_mono(audio: &SpeechAudio) -> Vec { + let data_len = (audio.samples.len() * 2) as u32; + let mut out = Vec::with_capacity(44 + data_len as usize); + out.extend_from_slice(b"RIFF"); + out.extend_from_slice(&(36 + data_len).to_le_bytes()); + out.extend_from_slice(b"WAVE"); + out.extend_from_slice(b"fmt "); + out.extend_from_slice(&16u32.to_le_bytes()); + out.extend_from_slice(&1u16.to_le_bytes()); // PCM + out.extend_from_slice(&1u16.to_le_bytes()); // mono + out.extend_from_slice(&audio.sample_rate.to_le_bytes()); + out.extend_from_slice(&(audio.sample_rate * 2).to_le_bytes()); + out.extend_from_slice(&2u16.to_le_bytes()); + out.extend_from_slice(&16u16.to_le_bytes()); + out.extend_from_slice(b"data"); + out.extend_from_slice(&data_len.to_le_bytes()); + for &s in &audio.samples { + let v = (s.clamp(-1.0, 1.0) * 32767.0).round() as i16; + out.extend_from_slice(&v.to_le_bytes()); + } + out +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn pcm16_roundtrips() { + let audio = SpeechAudio { + samples: vec![0.0, 0.5, -0.5, 1.0, -1.0], + sample_rate: 22_050, + }; + let decoded = decode(&encode_pcm16_mono(&audio)).unwrap(); + assert_eq!(decoded.sample_rate, 22_050); + assert_eq!(decoded.samples.len(), 5); + for (a, b) in audio.samples.iter().zip(&decoded.samples) { + assert!((a - b).abs() < 1.0 / 32000.0, "{a} vs {b}"); + } + } + + #[test] + fn stereo_is_averaged_to_mono() { + // Hand-built stereo 16-bit WAV, one frame: L=0.5, R=-0.5 -> 0.0. + let mut bytes = Vec::new(); + bytes.extend_from_slice(b"RIFF"); + bytes.extend_from_slice(&(36u32 + 4).to_le_bytes()); + bytes.extend_from_slice(b"WAVE"); + bytes.extend_from_slice(b"fmt "); + bytes.extend_from_slice(&16u32.to_le_bytes()); + bytes.extend_from_slice(&1u16.to_le_bytes()); + bytes.extend_from_slice(&2u16.to_le_bytes()); + bytes.extend_from_slice(&48_000u32.to_le_bytes()); + bytes.extend_from_slice(&(48_000u32 * 4).to_le_bytes()); + bytes.extend_from_slice(&4u16.to_le_bytes()); + bytes.extend_from_slice(&16u16.to_le_bytes()); + bytes.extend_from_slice(b"data"); + bytes.extend_from_slice(&4u32.to_le_bytes()); + bytes.extend_from_slice(&16384i16.to_le_bytes()); + bytes.extend_from_slice(&(-16384i16).to_le_bytes()); + let decoded = decode(&bytes).unwrap(); + assert_eq!(decoded.samples, vec![0.0]); + assert_eq!(decoded.sample_rate, 48_000); + } + + #[test] + fn rejects_non_wav() { + assert!(decode(b"not a wav at all").is_err()); + } +} diff --git a/libs/voice/swift/speech_bridge.swift b/libs/system_speech/swift/stt_bridge.swift similarity index 62% rename from libs/voice/swift/speech_bridge.swift rename to libs/system_speech/swift/stt_bridge.swift index 1f3e8413a..b450e9817 100644 --- a/libs/voice/swift/speech_bridge.swift +++ b/libs/system_speech/swift/stt_bridge.swift @@ -3,22 +3,26 @@ import Speech import AVFoundation import CoreMedia -struct CSegment { +// The STT half of makepad-system-speech's Apple bridge: SpeechAnalyzer (macOS 26 / +// iOS 26) over caller-recorded 16 kHz mono PCM. Symbols are prefixed `mss_` so +// this static library can coexist with any other Swift bridge in the binary. + +struct MssSegment { var text: UnsafeMutablePointer? var start_ms: Int64 var end_ms: Int64 } -func resolveLocale(_ langStr: String) -> Locale { +func mssResolveLocale(_ tag: String) -> Locale { let defaults: [String: String] = [ "en": "en-US", "fr": "fr-FR", "de": "de-DE", "es": "es-ES", - "it": "it-IT", "pt": "pt-BR", "zh": "zh-CN", "ja": "ja-JP", - "ko": "ko-KR", "yue": "yue-CN", + "it": "it-IT", "pt": "pt-BR", "nl": "nl-NL", "zh": "zh-CN", + "ja": "ja-JP", "ko": "ko-KR", "ru": "ru-RU", "yue": "yue-CN", ] - return Locale(identifier: defaults[langStr] ?? langStr) + return Locale(identifier: defaults[tag] ?? tag.replacingOccurrences(of: "_", with: "-")) } -func runAsyncSync(_ body: @escaping @Sendable () async throws -> T) throws -> T { +func mssRunAsyncSync(_ body: @escaping @Sendable () async throws -> T) throws -> T { let sem = DispatchSemaphore(value: 0) let box = UnsafeMutablePointer>.allocate(capacity: 1) box.initialize(to: .failure(NSError(domain: "uninit", code: 0))) @@ -38,34 +42,34 @@ func runAsyncSync(_ body: @escaping @Sendable () async throws -> T) } } -@_cdecl("apple_speech_transcribe") -func transcribe( +/// Recognize `sampleCount` floats of 16 kHz mono PCM. Returns 0 and an owned +/// array of `MssSegment` (release with `mss_stt_free_segments`), or a +/// negative code: -1 recognition failed, -2 locale unsupported. +@_cdecl("mss_stt_transcribe") +func mss_stt_transcribe( _ samples: UnsafePointer, _ sampleCount: Int64, _ lang: UnsafePointer, + _ wantTimestamps: Int32, _ outCount: UnsafeMutablePointer, _ outSegments: UnsafeMutablePointer ) -> Int32 { - let langStr = String(cString: lang) - let requestedLocale = resolveLocale(langStr) + let requestedLocale = mssResolveLocale(String(cString: lang)) let count = Int(sampleCount) - - if count == 0 { - outCount.pointee = 0 - outSegments.pointee = nil - return 0 - } + outCount.pointee = 0 + outSegments.pointee = nil + if count == 0 { return 0 } let samplesCopy = Array(UnsafeBufferPointer(start: samples, count: count)) do { - let segments: [(String, Int64, Int64)] = try runAsyncSync { + let segments: [(String, Int64, Int64)] = try mssRunAsyncSync { let locale = await SpeechTranscriber.supportedLocale(equivalentTo: requestedLocale) ?? requestedLocale let preset = SpeechTranscriber.Preset( transcriptionOptions: [], reportingOptions: [], - attributeOptions: [.audioTimeRange] + attributeOptions: wantTimestamps != 0 ? [.audioTimeRange] : [] ) let transcriber = SpeechTranscriber(locale: locale, preset: preset) let analyzer = SpeechAnalyzer(modules: [transcriber]) @@ -75,8 +79,11 @@ func transcribe( sampleRate: 16000, channels: 1, interleaved: false )! + // SpeechAnalyzer's file entry point is the one that finishes + // deterministically after the last sample; write the PCM to a + // temporary CAF and hand it that. let tempURL = URL(fileURLWithPath: NSTemporaryDirectory()) - .appendingPathComponent("makepad_speech_\(UUID().uuidString).caf") + .appendingPathComponent("makepad_mss_\(UUID().uuidString).caf") defer { try? FileManager.default.removeItem(at: tempURL) } let outFile = try AVAudioFile(forWriting: tempURL, settings: inputFormat.settings) @@ -93,61 +100,53 @@ func transcribe( var segs: [(String, Int64, Int64)] = [] for try await response in transcriber.results { let text = String(response.text.characters) - let isFinal = response.isFinal - if isFinal { + if response.isFinal { let range = response.range let startMs = Int64(CMTimeGetSeconds(range.start) * 1000) - let endMs = Int64(CMTimeGetSeconds( - CMTimeAdd(range.start, range.duration)) * 1000) + let endMs = Int64(CMTimeGetSeconds(CMTimeAdd(range.start, range.duration)) * 1000) if !text.isEmpty { segs.append((text, startMs, endMs)) } } } return segs } - let n = Int32(segments.count) - outCount.pointee = n - if segments.isEmpty { - outSegments.pointee = nil - return 0 - } - let ptr = UnsafeMutablePointer.allocate(capacity: segments.count) + outCount.pointee = Int32(segments.count) + if segments.isEmpty { return 0 } + let ptr = UnsafeMutablePointer.allocate(capacity: segments.count) for (i, (text, startMs, endMs)) in segments.enumerated() { - ptr[i] = CSegment(text: strdup(text), start_ms: startMs, end_ms: endMs) + ptr[i] = MssSegment(text: strdup(text), start_ms: startMs, end_ms: endMs) } outSegments.pointee = OpaquePointer(ptr) return 0 } catch { - NSLog("[speech_bridge] transcribe ERROR: %@", error.localizedDescription) - outCount.pointee = 0 - outSegments.pointee = nil + NSLog("[makepad-system-speech] stt transcribe: %@", error.localizedDescription) return -1 } } -@_cdecl("apple_speech_free_segments") -func freeSegments(_ ptr: OpaquePointer?, _ count: Int32) { +@_cdecl("mss_stt_free_segments") +func mss_stt_free_segments(_ ptr: OpaquePointer?, _ count: Int32) { guard let rawPtr = ptr else { return } - let typed = UnsafeMutablePointer(rawPtr) + let typed = UnsafeMutablePointer(rawPtr) for i in 0..) -> Int32 { - let langStr = String(cString: lang) - let requestedLocale = resolveLocale(langStr) - +/// Make sure the on-device model for `lang` is installed (downloading it if +/// needed). 0 ready, -2 locale unsupported, -1 other failure. +@_cdecl("mss_stt_prepare") +func mss_stt_prepare(_ lang: UnsafePointer) -> Int32 { + let requestedLocale = mssResolveLocale(String(cString: lang)) do { - try runAsyncSync { + try mssRunAsyncSync { let locale = await SpeechTranscriber.supportedLocale(equivalentTo: requestedLocale) ?? requestedLocale let supported = await SpeechTranscriber.supportedLocales let bcp47 = locale.identifier(.bcp47) guard supported.contains(where: { $0.identifier(.bcp47) == bcp47 }) else { - throw NSError(domain: "speech_bridge", code: -2, + throw NSError(domain: "mss", code: -2, userInfo: [NSLocalizedDescriptionKey: "Unsupported: \(bcp47)"]) } let installed = await SpeechTranscriber.installedLocales @@ -163,7 +162,7 @@ func ensureModel(_ lang: UnsafePointer) -> Int32 { return 0 } catch let e as NSError where e.code == -2 { return -2 } catch { - NSLog("[speech_bridge] ensureModel error: %@", error.localizedDescription) + NSLog("[makepad-system-speech] stt prepare: %@", error.localizedDescription) return -1 } } diff --git a/libs/system_speech/swift/tts_bridge.swift b/libs/system_speech/swift/tts_bridge.swift new file mode 100644 index 000000000..2f93847ff --- /dev/null +++ b/libs/system_speech/swift/tts_bridge.swift @@ -0,0 +1,148 @@ +import AVFoundation +import Foundation + +// The TTS half of makepad-system-speech's Apple bridge: AVSpeechSynthesizer +// rendered to a PCM buffer (never to a device — Makepad's audio output owns +// playback). Symbols are prefixed `mss_`. + +private final class MssRendered { + var samples: [Float] = [] + var sampleRate: Double = 0 +} + +struct MssVoice { + var id: UnsafeMutablePointer? + var name: UnsafeMutablePointer? + var language: UnsafeMutablePointer? + /// 0 unknown, 1 female, 2 male (AVSpeechSynthesisVoiceGender raw values). + var gender: Int32 +} + +/// Render `text` to mono float PCM. `voice` is an `AVSpeechSynthesisVoice` +/// identifier or null (then `language`, a BCP-47 tag, picks the default +/// voice). `rate`/`pitch` are multipliers around 1.0. Returns null on failure; +/// release with `mss_tts_free`. +@_cdecl("mss_tts_synthesize") +public func mss_tts_synthesize( + _ text: UnsafePointer, + _ voice: UnsafePointer?, + _ language: UnsafePointer, + _ rate: Float, + _ pitch: Float, + _ outLen: UnsafeMutablePointer, + _ outRate: UnsafeMutablePointer +) -> UnsafeMutablePointer? { + outLen.pointee = 0 + outRate.pointee = 0 + + let string = String(cString: text) + if string.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { + return nil + } + + let utterance = AVSpeechUtterance(string: string) + if let voice, let selected = AVSpeechSynthesisVoice(identifier: String(cString: voice)) { + utterance.voice = selected + } else { + utterance.voice = AVSpeechSynthesisVoice(language: String(cString: language)) + ?? AVSpeechSynthesisVoice(language: "en-US") + } + // AVSpeechUtterance.rate is 0...1 with the default at 0.5; our 1.0 is that default. + if rate > 0 && rate.isFinite { + utterance.rate = min(max(AVSpeechUtteranceDefaultSpeechRate * rate, AVSpeechUtteranceMinimumSpeechRate), + AVSpeechUtteranceMaximumSpeechRate) + } + if pitch > 0 && pitch.isFinite { + utterance.pitchMultiplier = min(max(pitch, 0.5), 2.0) + } + + let synthesizer = AVSpeechSynthesizer() + let rendered = MssRendered() + let finished = DispatchSemaphore(value: 0) + var signalled = false + + // Buffers arrive on an internal queue; a zero-length buffer terminates the run. + synthesizer.write(utterance) { buffer in + guard let pcm = buffer as? AVAudioPCMBuffer else { return } + let frames = Int(pcm.frameLength) + if frames == 0 { + if !signalled { + signalled = true + finished.signal() + } + return + } + rendered.sampleRate = pcm.format.sampleRate + if let channels = pcm.floatChannelData { + rendered.samples.append(contentsOf: UnsafeBufferPointer(start: channels[0], count: frames)) + } else if let channels = pcm.int16ChannelData { + let source = UnsafeBufferPointer(start: channels[0], count: frames) + rendered.samples.append(contentsOf: source.map { Float($0) / 32768.0 }) + } + } + + // `write` delivers its buffers through the MAIN run loop, whichever thread + // called it (pumping the caller's own loop was tried and delivers + // nothing). Every UI app pumps main, so a worker just waits on the + // semaphore; a caller ON main must pump instead of blocking, or it + // deadlocks itself. A headless tool calling from a worker must keep its + // main thread in CFRunLoopRun — see makepad-ai-hub's speech-roundtrip. + if Thread.isMainThread { + let deadline = Date().addingTimeInterval(30) + while !signalled, Date() < deadline { + RunLoop.current.run(mode: .default, before: Date().addingTimeInterval(0.02)) + } + } else { + _ = finished.wait(timeout: .now() + 30) + } + withExtendedLifetime(synthesizer) {} + + if rendered.samples.isEmpty || rendered.sampleRate <= 0 { + return nil + } + + let count = rendered.samples.count + let out = UnsafeMutablePointer.allocate(capacity: count) + rendered.samples.withUnsafeBufferPointer { source in + out.initialize(from: source.baseAddress!, count: count) + } + outLen.pointee = Int32(count) + outRate.pointee = Float(rendered.sampleRate) + return out +} + +@_cdecl("mss_tts_free") +public func mss_tts_free(_ ptr: UnsafeMutablePointer?) { + ptr?.deallocate() +} + +/// Installed voices as an owned array of `MssVoice`; release with +/// `mss_tts_free_voices`. +@_cdecl("mss_tts_voices") +public func mss_tts_voices(_ outCount: UnsafeMutablePointer) -> OpaquePointer? { + let voices = AVSpeechSynthesisVoice.speechVoices() + outCount.pointee = Int32(voices.count) + if voices.isEmpty { return nil } + let ptr = UnsafeMutablePointer.allocate(capacity: voices.count) + for (i, v) in voices.enumerated() { + ptr[i] = MssVoice( + id: strdup(v.identifier), + name: strdup(v.name), + language: strdup(v.language), + gender: Int32(v.gender.rawValue) + ) + } + return OpaquePointer(ptr) +} + +@_cdecl("mss_tts_free_voices") +public func mss_tts_free_voices(_ ptr: OpaquePointer?, _ count: Int32) { + guard let rawPtr = ptr else { return } + let typed = UnsafeMutablePointer(rawPtr) + for i in 0.. bool { - let out_dir = env::var("OUT_DIR").unwrap(); - let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); - let swift_src = format!("{}/swift/speech_bridge.swift", manifest_dir); - let swift_module_cache = format!("{}/swift_module_cache", out_dir); - - println!("cargo:rerun-if-changed=swift/speech_bridge.swift"); - let _ = fs::create_dir_all(&swift_module_cache); - - // Compile Swift -> static library - let output_lib = format!("{}/libspeech_bridge.a", out_dir); - let mut swift_args = vec![ - "-emit-library".to_string(), - "-static".to_string(), - "-parse-as-library".to_string(), - "-module-name".to_string(), - "speech_bridge".to_string(), - "-module-cache-path".to_string(), - swift_module_cache.clone(), - ]; - if target_os == "ios" { - if let Some((swift_target, sdk_path)) = ios_swift_target_and_sdk() { - swift_args.push("-target".to_string()); - swift_args.push(swift_target); - swift_args.push("-sdk".to_string()); - swift_args.push(sdk_path); - } - } - swift_args.push("-o".to_string()); - swift_args.push(output_lib.clone()); - swift_args.push(swift_src); - - let status = match Command::new("swiftc").args(swift_args).status() { - Ok(status) => status, - Err(err) => { - println!("cargo:warning=failed to run swiftc for speech bridge: {}", err); - return false; - } - }; - - if !status.success() { - println!("cargo:warning=swiftc compilation failed for speech bridge"); - return false; - } - - // Fix the @rpath issue with libswift_Concurrency.dylib BEFORE emitting any - // link-search paths, so our override directory appears first in -L order. - // - // Background: The macOS SDK's libswift_Concurrency.tbd contains $ld$previous - // entries that tell the linker to record "@rpath/libswift_Concurrency.dylib" - // as the install name when MACOSX_DEPLOYMENT_TARGET < 15.0. Rust defaults to - // MACOSX_DEPLOYMENT_TARGET=11.0, which triggers this behavior. The resulting - // binary then fails at runtime with "dyld: Library not loaded: @rpath/...". - // - // The fix: create modified copies of the .tbd files with $ld$previous entries - // stripped, and add them to the linker search path before the SDK paths. - // Since cargo:rustc-link-search propagates from library crates to dependent - // binaries, the final binary's link step will find our clean .tbd first and - // use the absolute install name "/usr/lib/swift/libswift_Concurrency.dylib". - if target_os == "macos" { - fix_swift_rpath_tbds(&out_dir); - } - - // Link the static library - println!("cargo:rustc-link-search=native={}", out_dir); - println!("cargo:rustc-link-lib=static=speech_bridge"); - - // On iOS, ensure the linker uses the same deployment target as the Swift objects. - // Without this, Rust's default target triple (arm64-apple-ios10.0.0) causes a - // mismatch and missing symbols like ___chkstk_darwin from the Swift async runtime. - if target_os == "ios" { - let deployment_key = { - let abi = env::var("CARGO_CFG_TARGET_ABI").unwrap_or_default(); - let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default(); - if abi == "sim" || arch == "x86_64" { - "IPHONESIMULATOR_DEPLOYMENT_TARGET" - } else { - "IPHONEOS_DEPLOYMENT_TARGET" - } - }; - let deployment = - env::var(deployment_key).unwrap_or_else(|_| IOS_DEPLOYMENT_TARGET_DEFAULT.to_string()); - println!("cargo:rustc-link-arg=-miphoneos-version-min={}", deployment); - } - - // Link Apple frameworks - println!("cargo:rustc-link-lib=framework=Speech"); - println!("cargo:rustc-link-lib=framework=Foundation"); - println!("cargo:rustc-link-lib=framework=AVFoundation"); - println!("cargo:rustc-link-lib=framework=CoreMedia"); - - // Add Swift runtime library search paths so the linker can resolve symbols. - let target_info = match Command::new("swiftc").args(["-print-target-info"]).output() { - Ok(output) => output, - Err(err) => { - println!("cargo:warning=failed to get swift target info: {}", err); - return true; - } - }; - - if target_info.status.success() { - let info_str = String::from_utf8_lossy(&target_info.stdout); - for line in info_str.lines() { - let trimmed = line.trim().trim_matches('"').trim_end_matches(','); - if trimmed.starts_with("/") && trimmed.contains("lib/swift") { - println!("cargo:rustc-link-search=native={}", trimmed); - } - } - } - - true -} - -fn ios_swift_target_and_sdk() -> Option<(String, String)> { - let arch = env::var("CARGO_CFG_TARGET_ARCH").ok()?; - let abi = env::var("CARGO_CFG_TARGET_ABI").unwrap_or_default(); - let is_simulator = abi == "sim" || arch == "x86_64"; - let swift_arch = match arch.as_str() { - "aarch64" => "arm64", - "x86_64" => "x86_64", - _ => return None, - }; - let deployment_key = if is_simulator { - "IPHONESIMULATOR_DEPLOYMENT_TARGET" - } else { - "IPHONEOS_DEPLOYMENT_TARGET" - }; - let deployment = - env::var(deployment_key).unwrap_or_else(|_| IOS_DEPLOYMENT_TARGET_DEFAULT.to_string()); - let swift_target = if is_simulator { - format!("{swift_arch}-apple-ios{deployment}-simulator") - } else { - format!("{swift_arch}-apple-ios{deployment}") - }; - let sdk_name = if is_simulator { - "iphonesimulator" - } else { - "iphoneos" - }; - let sdk_path = Command::new("xcrun") - .args(["--sdk", sdk_name, "--show-sdk-path"]) - .output() - .ok() - .filter(|o| o.status.success()) - .map(|o| String::from_utf8_lossy(&o.stdout).trim().to_string())?; - Some((swift_target, sdk_path)) -} - -/// Create modified copies of Swift runtime .tbd files without $ld$previous entries. -/// -/// The $ld$previous entries in the SDK's .tbd files cause the linker to use -/// @rpath/ as the install name for deployment targets below certain thresholds. -/// By stripping these entries and placing our modified .tbd in a search directory -/// that comes before the SDK, the linker will use the actual absolute install -/// names (e.g. "/usr/lib/swift/libswift_Concurrency.dylib") regardless of the -/// deployment target. -fn fix_swift_rpath_tbds(out_dir: &str) { - let sdk_path = Command::new("xcrun") - .args(&["--show-sdk-path"]) - .output() - .ok() - .filter(|o| o.status.success()) - .map(|o| String::from_utf8_lossy(&o.stdout).trim().to_string()); - - let sdk_path = match sdk_path { - Some(p) => p, - None => return, - }; - - let override_dir = format!("{}/swift_tbd_override", out_dir); - if fs::create_dir_all(&override_dir).is_err() { - return; - } - - // Only patch the specific Swift runtime .tbd files our static library depends on. - let swift_tbd_dir = format!("{}/usr/lib/swift", sdk_path); - let tbds_to_fix = [ - "libswift_Concurrency.tbd", - "libswiftCore.tbd", - "libswiftFoundation.tbd", - "libswift_StringProcessing.tbd", - "libswift_RegexParser.tbd", - ]; - - for name in &tbds_to_fix { - let tbd_path = format!("{}/{}", swift_tbd_dir, name); - let content = match fs::read_to_string(&tbd_path) { - Ok(c) => c, - Err(_) => continue, - }; - if !content.contains("$ld$previous$@rpath/") { - continue; - } - let fixed = strip_ld_previous_rpath(&content); - let _ = fs::write(format!("{}/{}", override_dir, name), &fixed); - } - - // Emit this search path BEFORE any other Swift library search paths. - // cargo:rustc-link-search propagates from library crates to dependent binaries, - // so the final binary's linker will find our modified .tbd files first. - println!("cargo:rustc-link-search=native={}", override_dir); -} - -/// Strip $ld$previous entries that reference @rpath/ from a .tbd file's content. -fn strip_ld_previous_rpath(content: &str) -> String { - let mut result = content.to_string(); - - // $ld$previous entries appear as quoted strings in YAML: - // '$ld$previous$@rpath/libswift_Concurrency.dylib$$1$10.9$12.0$$' - // They may be followed by comma + whitespace in a YAML sequence. - while let Some(start) = result.find("'$ld$previous$@rpath/") { - if let Some(end_quote_offset) = result[start + 1..].find('\'') { - let end = start + 1 + end_quote_offset + 1; // past closing quote - // Skip trailing comma and whitespace/newlines - let rest = &result[end..]; - let trimmed = - rest.trim_start_matches(|c: char| c == ',' || c == ' ' || c == '\n' || c == '\r'); - let skip = rest.len() - trimmed.len(); - result = format!("{}{}", &result[..start], &result[end + skip..]); - } else { - break; - } - } - - result -} diff --git a/libs/voice/src/apple/speech.rs b/libs/voice/src/apple/speech.rs deleted file mode 100644 index 8336eb943..000000000 --- a/libs/voice/src/apple/speech.rs +++ /dev/null @@ -1,90 +0,0 @@ -use crate::decode_loop::{Segment, WhisperParams}; -use std::ffi::{c_void, CStr, CString}; -use std::os::raw::c_char; - -/// C-compatible segment layout matching Swift CSegment struct. -/// Must stay in sync with speech_bridge.swift. -#[repr(C)] -struct CSegment { - text: *mut c_char, - start_ms: i64, - end_ms: i64, -} - -extern "C" { - /// Swift @_cdecl uses OpaquePointer for the segments pointer, - /// which maps to void* in C. We cast on the Rust side. - fn apple_speech_transcribe( - samples: *const f32, - sample_count: i64, - lang: *const c_char, - out_count: *mut i32, - out_segments: *mut *mut c_void, - ) -> i32; - - fn apple_speech_free_segments(ptr: *mut c_void, count: i32); - - fn apple_speech_ensure_model(lang: *const c_char) -> i32; -} - -/// Transcribe PCM audio (f32, 16kHz, mono) using Apple SpeechAnalyzer. -/// Returns segments with timestamps, matching the same `Segment` type as the CPU Whisper backend. -pub fn transcribe(samples: &[f32], params: &WhisperParams) -> Vec { - let lang = - CString::new(params.language.as_str()).unwrap_or_else(|_| CString::new("en").unwrap()); - let mut count: i32 = 0; - let mut raw_ptr: *mut c_void = std::ptr::null_mut(); - - let ret = unsafe { - apple_speech_transcribe( - samples.as_ptr(), - samples.len() as i64, - lang.as_ptr(), - &mut count, - &mut raw_ptr, - ) - }; - - if ret != 0 || count <= 0 || raw_ptr.is_null() { - return Vec::new(); - } - - let ptr = raw_ptr as *mut CSegment; - - let segments = unsafe { - (0..count as usize) - .map(|i| { - let cs = &*ptr.add(i); - let text = if cs.text.is_null() { - String::new() - } else { - CStr::from_ptr(cs.text).to_string_lossy().into_owned() - }; - Segment { - start_ms: cs.start_ms, - end_ms: cs.end_ms, - text, - } - }) - .collect() - }; - - unsafe { - apple_speech_free_segments(raw_ptr, count); - } - - segments -} - -/// Ensure the speech model for a language is downloaded. -/// Call this before the first transcription for a given language. -/// Returns Ok(()) if the model is ready, Err(()) on failure. -pub fn ensure_model(language: &str) -> Result<(), ()> { - let lang = CString::new(language).unwrap_or_else(|_| CString::new("en").unwrap()); - let ret = unsafe { apple_speech_ensure_model(lang.as_ptr()) }; - if ret == 0 { - Ok(()) - } else { - Err(()) - } -} diff --git a/libs/voice/src/bin/apple_speech_test.rs b/libs/voice/src/bin/apple_speech_test.rs deleted file mode 100644 index 6e12d88b3..000000000 --- a/libs/voice/src/bin/apple_speech_test.rs +++ /dev/null @@ -1,116 +0,0 @@ -#[cfg(all(any(target_os = "macos", target_os = "ios"), not(force_whisper)))] -fn main() { - use std::io::{Read, Seek, SeekFrom}; - - let wav_path = std::env::args() - .nth(1) - .unwrap_or_else(|| "local/whisper.cpp/samples/jfk.wav".into()); - - eprintln!("loading audio: {}", wav_path); - let samples = read_wav_pcm_f32(&wav_path); - - let params = makepad_voice::WhisperParams::default(); - eprintln!( - "params: language='{}', translate={}", - params.language, params.translate - ); - - // Try ensure_model first - eprintln!("ensuring model for '{}'...", params.language); - match makepad_voice::apple_speech::ensure_model(¶ms.language) { - Ok(()) => eprintln!("model ready"), - Err(()) => eprintln!("WARNING: ensure_model failed (may still work)"), - } - - eprintln!( - "transcribing {} samples ({:.2}s)...", - samples.len(), - samples.len() as f64 / 16000.0 - ); - let t0 = std::time::Instant::now(); - let segments = makepad_voice::apple_speech::transcribe(&samples, ¶ms); - let elapsed = t0.elapsed().as_secs_f64(); - eprintln!( - "transcription done in {:.2}s, got {} segments", - elapsed, - segments.len() - ); - - if segments.is_empty() { - eprintln!("WARNING: no segments returned!"); - } - - for seg in &segments { - let t0 = seg.start_ms as f64 / 1000.0; - let t1 = seg.end_ms as f64 / 1000.0; - println!("[{:.2} --> {:.2}] {}", t0, t1, seg.text); - } - - fn read_wav_pcm_f32(path: &str) -> Vec { - let mut f = std::fs::File::open(path).expect("failed to open wav"); - let mut riff_header = [0u8; 12]; - f.read_exact(&mut riff_header) - .expect("failed to read RIFF header"); - assert_eq!(&riff_header[0..4], b"RIFF"); - assert_eq!(&riff_header[8..12], b"WAVE"); - - let mut channels = 1u16; - let mut _sample_rate = 16000u32; - let mut bits_per_sample = 16u16; - let mut audio_data = Vec::new(); - - loop { - let mut chunk_header = [0u8; 8]; - if f.read_exact(&mut chunk_header).is_err() { - break; - } - let chunk_id = &chunk_header[0..4]; - let chunk_size = u32::from_le_bytes([ - chunk_header[4], - chunk_header[5], - chunk_header[6], - chunk_header[7], - ]) as usize; - - if chunk_id == b"fmt " { - let mut fmt = vec![0u8; chunk_size]; - f.read_exact(&mut fmt).expect("failed to read fmt"); - channels = u16::from_le_bytes([fmt[2], fmt[3]]); - _sample_rate = u32::from_le_bytes([fmt[4], fmt[5], fmt[6], fmt[7]]); - bits_per_sample = u16::from_le_bytes([fmt[14], fmt[15]]); - } else if chunk_id == b"data" { - audio_data = vec![0u8; chunk_size]; - f.read_exact(&mut audio_data).expect("failed to read data"); - break; - } else { - f.seek(SeekFrom::Current(chunk_size as i64)).expect("skip"); - } - } - - eprintln!( - "wav: {} Hz, {} ch, {} bit", - _sample_rate, channels, bits_per_sample - ); - - let n_samples = audio_data.len() / 2; - let mut samples = Vec::with_capacity(n_samples); - for i in 0..n_samples { - let s = i16::from_le_bytes([audio_data[i * 2], audio_data[i * 2 + 1]]); - samples.push(s as f32 / 32768.0); - } - if channels == 2 { - samples = samples.iter().step_by(2).copied().collect(); - } - eprintln!( - "wav: {} samples ({:.1}s)", - samples.len(), - samples.len() as f64 / 16000.0 - ); - samples - } -} - -#[cfg(not(all(any(target_os = "macos", target_os = "ios"), not(force_whisper))))] -fn main() { - eprintln!("apple-speech path unavailable on this target/config"); -} diff --git a/libs/voice/src/transcriber.rs b/libs/voice/src/transcriber.rs deleted file mode 100644 index 5a0f96f55..000000000 --- a/libs/voice/src/transcriber.rs +++ /dev/null @@ -1,298 +0,0 @@ -use crate::{Segment, WhisperModel, WhisperParams, WhisperState}; -#[allow(unused_imports)] -use std::path::Path; - -const DEFAULT_MODEL_PATH: &str = "ggml-large-v3-turbo.bin"; - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum VoiceBackendKind { - Whisper, - NativeApple, -} - -impl VoiceBackendKind { - pub fn default_for_platform() -> Self { - #[cfg(any( - all(target_os = "ios", not(force_whisper)), - all(target_os = "macos", not(force_whisper)) - ))] - { - Self::NativeApple - } - #[cfg(not(any( - all(target_os = "ios", not(force_whisper)), - all(target_os = "macos", not(force_whisper)) - )))] - { - Self::Whisper - } - } - - pub fn from_makepad_env() -> Self { - #[cfg(all(target_os = "ios", not(force_whisper)))] - { - return Self::NativeApple; - } - - if std::env::var("MAKEPAD").ok().is_some_and(|configs| { - configs - .split(['+', ',']) - .any(|config| config.eq_ignore_ascii_case("whisper")) - }) { - return Self::Whisper; - } - Self::default_for_platform() - } -} - -#[derive(Clone, Debug)] -pub struct VoiceTranscribeParams { - pub language: String, - pub translate: bool, - pub include_timestamps: bool, - pub single_segment: bool, - pub max_tokens: usize, - pub silence_threshold: f32, - pub suppress_blank: bool, - pub temperature: f32, -} - -impl Default for VoiceTranscribeParams { - fn default() -> Self { - let whisper = WhisperParams::default(); - Self { - language: whisper.language, - translate: whisper.translate, - include_timestamps: !whisper.no_timestamps, - single_segment: whisper.single_segment, - max_tokens: whisper.max_tokens, - silence_threshold: whisper.no_speech_thold, - suppress_blank: whisper.suppress_blank, - temperature: whisper.temperature, - } - } -} - -impl VoiceTranscribeParams { - pub fn for_live_dictation() -> Self { - let mut out = Self::default(); - out.include_timestamps = false; - out.single_segment = true; - out.max_tokens = 48; - out.silence_threshold = 0.65; - out.suppress_blank = true; - out.temperature = 0.0; - out - } - - fn to_whisper_params(&self) -> WhisperParams { - let mut out = WhisperParams::default(); - out.language = self.language.clone(); - out.translate = self.translate; - out.no_timestamps = !self.include_timestamps; - out.single_segment = self.single_segment; - out.max_tokens = self.max_tokens; - out.no_speech_thold = self.silence_threshold; - out.suppress_blank = self.suppress_blank; - out.temperature = self.temperature; - out - } -} - -#[derive(Debug)] -pub enum VoiceTranscribeError { - BackendUnavailable(&'static str), - ModelLoadFailed(String), - BackendFailed(&'static str), -} - -pub struct WhisperTranscriber { - model_path: String, - model: Option, - state: Option, - model_load_failed: bool, -} - -impl WhisperTranscriber { - fn model_path_from_env() -> String { - std::env::var("MAKEPAD_VOICE_MODEL").unwrap_or_else(|_| DEFAULT_MODEL_PATH.to_string()) - } - - pub fn new_from_env() -> Self { - Self { - model_path: Self::model_path_from_env(), - model: None, - state: None, - model_load_failed: false, - } - } - - fn ensure_loaded(&mut self) -> Result<(), VoiceTranscribeError> { - if self.model.is_some() && self.state.is_some() { - return Ok(()); - } - if self.model_load_failed { - return Err(VoiceTranscribeError::ModelLoadFailed( - self.model_path.clone(), - )); - } - match WhisperModel::load_file(&self.model_path) { - Ok(model) => { - self.state = Some(WhisperState::new(&model)); - self.model = Some(model); - Ok(()) - } - Err(_) => { - self.model_load_failed = true; - Err(VoiceTranscribeError::ModelLoadFailed( - self.model_path.clone(), - )) - } - } - } - - pub fn preload(&mut self, _params: &VoiceTranscribeParams) -> Result<(), VoiceTranscribeError> { - self.ensure_loaded() - } - - pub fn transcribe( - &mut self, - samples: &[f32], - params: &VoiceTranscribeParams, - ) -> Result, VoiceTranscribeError> { - self.ensure_loaded()?; - let whisper = params.to_whisper_params(); - match (self.model.as_ref(), self.state.as_mut()) { - (Some(model), Some(state)) => Ok(state.transcribe(model, samples, &whisper)), - _ => Err(VoiceTranscribeError::BackendFailed( - "whisper backend state unavailable", - )), - } - } -} - -pub struct NativeAppleTranscriber; - -#[cfg(any( - all(target_os = "ios", not(force_whisper)), - all(target_os = "macos", not(force_whisper)) -))] -impl NativeAppleTranscriber { - pub fn new() -> Self { - Self - } - - pub fn preload(&mut self, params: &VoiceTranscribeParams) -> Result<(), VoiceTranscribeError> { - crate::apple_speech::ensure_model(¶ms.language) - .map_err(|_| VoiceTranscribeError::BackendFailed("apple ensure_model failed")) - } - - pub fn transcribe( - &mut self, - samples: &[f32], - params: &VoiceTranscribeParams, - ) -> Result, VoiceTranscribeError> { - Ok(crate::apple_speech::transcribe( - samples, - ¶ms.to_whisper_params(), - )) - } -} - -#[cfg(not(any( - all(target_os = "ios", not(force_whisper)), - all(target_os = "macos", not(force_whisper)) -)))] -impl NativeAppleTranscriber { - pub fn new() -> Self { - Self - } - - pub fn preload(&mut self, _params: &VoiceTranscribeParams) -> Result<(), VoiceTranscribeError> { - Err(VoiceTranscribeError::BackendUnavailable( - "native apple backend unavailable", - )) - } - - pub fn transcribe( - &mut self, - _samples: &[f32], - _params: &VoiceTranscribeParams, - ) -> Result, VoiceTranscribeError> { - Err(VoiceTranscribeError::BackendUnavailable( - "native apple backend unavailable", - )) - } -} - -pub enum VoiceTranscriber { - Whisper(WhisperTranscriber), - NativeApple(NativeAppleTranscriber), -} - -impl VoiceTranscriber { - pub fn new(kind: VoiceBackendKind) -> Self { - match kind { - VoiceBackendKind::Whisper => Self::Whisper(WhisperTranscriber::new_from_env()), - VoiceBackendKind::NativeApple => Self::NativeApple(NativeAppleTranscriber::new()), - } - } - - pub fn from_makepad_env() -> Self { - #[cfg(all(target_os = "ios", not(force_whisper)))] - { - return Self::NativeApple(NativeAppleTranscriber::new()); - } - - let kind = VoiceBackendKind::from_makepad_env(); - - #[cfg(all(target_os = "macos", not(force_whisper)))] - { - let model_path = WhisperTranscriber::model_path_from_env(); - let model_exists = Path::new(&model_path).exists(); - - if kind == VoiceBackendKind::Whisper { - if !model_exists { - eprintln!( - "[voice] whisper model not found at '{}', using native apple backend", - model_path - ); - return Self::NativeApple(NativeAppleTranscriber::new()); - } - return Self::Whisper(WhisperTranscriber::new_from_env()); - } - - // On Apple platforms, auto-prefer Whisper when the model is available. - if model_exists { - return Self::Whisper(WhisperTranscriber::new_from_env()); - } - } - - Self::new(kind) - } - - pub fn kind(&self) -> VoiceBackendKind { - match self { - Self::Whisper(_) => VoiceBackendKind::Whisper, - Self::NativeApple(_) => VoiceBackendKind::NativeApple, - } - } - - pub fn preload(&mut self, params: &VoiceTranscribeParams) -> Result<(), VoiceTranscribeError> { - match self { - Self::Whisper(inner) => inner.preload(params), - Self::NativeApple(inner) => inner.preload(params), - } - } - - pub fn transcribe( - &mut self, - samples: &[f32], - params: &VoiceTranscribeParams, - ) -> Result, VoiceTranscribeError> { - match self { - Self::Whisper(inner) => inner.transcribe(samples, params), - Self::NativeApple(inner) => inner.transcribe(samples, params), - } - } -} diff --git a/tools/cargo_makepad/src/android/compile.rs b/tools/cargo_makepad/src/android/compile.rs index 51576406d..b58c9c563 100644 --- a/tools/cargo_makepad/src/android/compile.rs +++ b/tools/cargo_makepad/src/android/compile.rs @@ -1116,6 +1116,7 @@ fn compile_java( makepad_java_classes_dir.join("MakepadActivity.java"), makepad_java_classes_dir.join("MakepadInputConnection.java"), makepad_java_classes_dir.join("MakepadNetwork.java"), + makepad_java_classes_dir.join("MakepadSpeech.java"), makepad_java_classes_dir.join("MakepadSocketStream.java"), makepad_java_classes_dir.join("MakepadWebSocket.java"), makepad_java_classes_dir.join("MakepadWebSocketReader.java"), diff --git a/tools/cargo_makepad/src/android/java/dev/makepad/android/MakepadActivity.java b/tools/cargo_makepad/src/android/java/dev/makepad/android/MakepadActivity.java index 44ac32d8b..b32dde631 100644 --- a/tools/cargo_makepad/src/android/java/dev/makepad/android/MakepadActivity.java +++ b/tools/cargo_makepad/src/android/java/dev/makepad/android/MakepadActivity.java @@ -1415,6 +1415,9 @@ public class MakepadActivity } clearLatestSurfaceSnapshot(); mSurfaceSnapshotCopyInFlight = false; + if (mSpeech != null) { + mSpeech.shutdown(); + } cleanupVideoPlaybackState(); shutdownVideoPlaybackThread(); if (!mIsSwitchingActivity) { @@ -2766,6 +2769,47 @@ public class MakepadActivity }); } + // The OS speech engines (makepad-system-speech). Everything real lives in + // MakepadSpeech; these are just the names the JNI side resolves on the + // activity, because a natively attached thread's class loader cannot find + // app classes with FindClass. + private MakepadSpeech mSpeech; + + private synchronized MakepadSpeech speech() { + if (mSpeech == null) { + mSpeech = new MakepadSpeech(this); + } + return mSpeech; + } + + public boolean speechSttAvailable() { + return speech().sttAvailable(); + } + + public void speechSttStart(long session, String languageTag, boolean partial, boolean preferOffline) { + speech().sttStart(session, languageTag, partial, preferOffline); + } + + public void speechSttStop(long session) { + speech().sttStop(session); + } + + public boolean speechTtsAvailable() { + return speech().ttsAvailable(); + } + + public String[] speechTtsVoices() { + return speech().ttsVoices(); + } + + public byte[] speechTtsSynthesize(String text, String voiceName, String languageTag, float rate, float pitch) { + return speech().ttsSynthesize(text, voiceName, languageTag, rate, pitch); + } + + public String speechTtsLastError() { + return speech().ttsLastError(); + } + public void attachCameraNativePreview(final long videoId, final int left, final int top, final int right, final int bottom) { runOnUiThread(new Runnable() { @Override diff --git a/tools/cargo_makepad/src/android/java/dev/makepad/android/MakepadSpeech.java b/tools/cargo_makepad/src/android/java/dev/makepad/android/MakepadSpeech.java new file mode 100644 index 000000000..c98e1b1c5 --- /dev/null +++ b/tools/cargo_makepad/src/android/java/dev/makepad/android/MakepadSpeech.java @@ -0,0 +1,463 @@ +package dev.makepad.android; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.speech.RecognitionListener; +import android.speech.RecognizerIntent; +import android.speech.SpeechRecognizer; +import android.speech.tts.TextToSpeech; +import android.speech.tts.UtteranceProgressListener; +import android.speech.tts.Voice; +import android.util.Log; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Locale; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +// The OS speech engines for makepad-system-speech. Both of them insist on the +// main looper (TextToSpeech's service connection and every SpeechRecognizer +// method), while the Rust side calls from worker threads and blocks; so the +// work is posted to the main looper and the caller parks on a CountDownLatch. +// +// Minimum API level is 26: SpeechRecognizer.createSpeechRecognizer + +// EXTRA_PREFER_OFFLINE (API 23), not createOnDeviceSpeechRecognizer (API 31); +// synthesizeToFile(CharSequence, Bundle, File, String) (API 21), not the +// ParcelFileDescriptor overload (API 30). +public class MakepadSpeech { + private static final String TAG = "Makepad"; + private static final long TTS_INIT_TIMEOUT_S = 10; + private static final long TTS_RENDER_TIMEOUT_S = 60; + + private final Activity mActivity; + private final Handler mMainHandler; + + // One engine, so one utterance at a time. + private final Object mTtsLock = new Object(); + private volatile TextToSpeech mTts; + private volatile String mTtsLastError = ""; + private final AtomicLong mUtteranceCounter = new AtomicLong(1); + private volatile CountDownLatch mUtteranceLatch; + private volatile String mUtteranceId; + private volatile boolean mUtteranceOk; + + // Touched only on the main looper, so it needs no lock. + private final HashMap mRecognizers = new HashMap<>(); + + public MakepadSpeech(Activity activity) { + mActivity = activity; + mMainHandler = new Handler(Looper.getMainLooper()); + } + + public static native void onSttEvent(long session, int kind, String text, float level); + + // ------------------------------------------------------------------- TTS + + public String ttsLastError() { + return mTtsLastError; + } + + public boolean ttsAvailable() { + return ensureTts() != null; + } + + public String[] ttsVoices() { + TextToSpeech tts = ensureTts(); + if (tts == null) { + return new String[0]; + } + ArrayList out = new ArrayList<>(); + try { + Set voices = tts.getVoices(); + if (voices != null) { + for (Voice voice : voices) { + if (voice == null || voice.getName() == null) { + continue; + } + Locale locale = voice.getLocale(); + String tag = locale == null ? "" : locale.toLanguageTag(); + out.add(voice.getName() + "\t" + tag + "\t" + voice.getQuality() + + "\t" + voice.isNetworkConnectionRequired()); + } + } + } + catch (Exception e) { + mTtsLastError = "ttsVoices: " + e.toString(); + Log.e(TAG, "ttsVoices: " + e.toString()); + } + return out.toArray(new String[0]); + } + + public byte[] ttsSynthesize(String text, String voiceName, String languageTag, float rate, float pitch) { + TextToSpeech tts = ensureTts(); + if (tts == null) { + return null; + } + synchronized (mTtsLock) { + File file = null; + try { + if (languageTag != null && !languageTag.isEmpty()) { + int result = tts.setLanguage(Locale.forLanguageTag(languageTag)); + if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { + // Not fatal: the engine keeps its previous language and + // still renders, so report it only if the render fails. + mTtsLastError = "language " + languageTag + " unavailable"; + } + } + if (voiceName != null && !voiceName.isEmpty()) { + Set voices = tts.getVoices(); + if (voices != null) { + for (Voice voice : voices) { + if (voice != null && voiceName.equals(voice.getName())) { + tts.setVoice(voice); + break; + } + } + } + } + tts.setSpeechRate(rate); + tts.setPitch(pitch); + + String utteranceId = "makepad-" + mUtteranceCounter.getAndIncrement(); + CountDownLatch done = new CountDownLatch(1); + mUtteranceId = utteranceId; + mUtteranceOk = false; + mUtteranceLatch = done; + + file = File.createTempFile("makepad-tts", ".wav", mActivity.getCacheDir()); + int queued = tts.synthesizeToFile(text, new Bundle(), file, utteranceId); + if (queued != TextToSpeech.SUCCESS) { + mTtsLastError = "synthesizeToFile refused the utterance"; + return null; + } + if (!done.await(TTS_RENDER_TIMEOUT_S, TimeUnit.SECONDS)) { + mTtsLastError = "tts render timed out after " + TTS_RENDER_TIMEOUT_S + "s"; + return null; + } + if (!mUtteranceOk) { + return null; + } + byte[] bytes = readAll(file); + if (bytes == null || bytes.length == 0) { + mTtsLastError = "tts wrote no audio"; + return null; + } + return bytes; + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + mTtsLastError = "interrupted while rendering"; + return null; + } + catch (Exception e) { + mTtsLastError = "ttsSynthesize: " + e.toString(); + Log.e(TAG, "ttsSynthesize: " + e.toString()); + return null; + } + finally { + mUtteranceLatch = null; + mUtteranceId = null; + if (file != null) { + file.delete(); + } + } + } + } + + // Called from onDestroy on the main thread, so it must not take mTtsLock: a + // render in flight can hold that for a minute, and blocking the UI thread + // that long is an ANR. + public void shutdown() { + TextToSpeech tts = mTts; + mTts = null; + if (tts != null) { + try { + tts.stop(); + tts.shutdown(); + } + catch (Exception e) { + Log.e(TAG, "tts shutdown: " + e.toString()); + } + } + mTtsLastError = "the speech engine was shut down"; + CountDownLatch pending = mUtteranceLatch; + if (pending != null) { + mUtteranceOk = false; + pending.countDown(); + } + mMainHandler.post(new Runnable() { + @Override public void run() { + for (Long session : new ArrayList<>(mRecognizers.keySet())) { + finishSession(session); + } + } + }); + } + + // TextToSpeech delivers onInit on the main looper, so the engine is built + // there and the calling worker parks on a latch. Calling this from the main + // thread would wait for a callback that can only run once we return. + private TextToSpeech ensureTts() { + if (Looper.myLooper() == Looper.getMainLooper()) { + mTtsLastError = "system speech must be used from a worker thread"; + return null; + } + synchronized (mTtsLock) { + if (mTts != null) { + return mTts; + } + final CountDownLatch ready = new CountDownLatch(1); + final int[] status = new int[]{ TextToSpeech.ERROR }; + final TextToSpeech[] engine = new TextToSpeech[1]; + mMainHandler.post(new Runnable() { + @Override public void run() { + try { + engine[0] = new TextToSpeech(mActivity, new TextToSpeech.OnInitListener() { + @Override public void onInit(int code) { + status[0] = code; + ready.countDown(); + } + }); + } + catch (Exception e) { + Log.e(TAG, "tts create: " + e.toString()); + ready.countDown(); + } + } + }); + try { + if (!ready.await(TTS_INIT_TIMEOUT_S, TimeUnit.SECONDS)) { + mTtsLastError = "no text-to-speech engine answered within " + TTS_INIT_TIMEOUT_S + "s"; + return null; + } + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + mTtsLastError = "interrupted waiting for the tts engine"; + return null; + } + if (status[0] != TextToSpeech.SUCCESS || engine[0] == null) { + mTtsLastError = "no text-to-speech engine installed (init status " + status[0] + ")"; + final TextToSpeech dead = engine[0]; + if (dead != null) { + mMainHandler.post(new Runnable() { + @Override public void run() { dead.shutdown(); } + }); + } + return null; + } + engine[0].setOnUtteranceProgressListener(new UtteranceProgressListener() { + @Override public void onStart(String utteranceId) {} + @Override public void onDone(String utteranceId) { + finishUtterance(utteranceId, true, null); + } + // Abstract in the base class even though it is deprecated. + @Override public void onError(String utteranceId) { + finishUtterance(utteranceId, false, "tts engine error"); + } + // API 21; the base implementation forwards to onError(String), + // which this overrides away so the utterance finishes once. + @Override public void onError(String utteranceId, int errorCode) { + finishUtterance(utteranceId, false, "tts engine error " + errorCode); + } + }); + mTts = engine[0]; + return mTts; + } + } + + private void finishUtterance(String utteranceId, boolean ok, String error) { + CountDownLatch latch = mUtteranceLatch; + if (latch == null || utteranceId == null || !utteranceId.equals(mUtteranceId)) { + return; + } + if (!ok && error != null) { + mTtsLastError = error; + } + mUtteranceOk = ok; + latch.countDown(); + } + + private static byte[] readAll(File file) { + FileInputStream in = null; + try { + in = new FileInputStream(file); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] chunk = new byte[64 * 1024]; + int read; + while ((read = in.read(chunk)) > 0) { + out.write(chunk, 0, read); + } + return out.toByteArray(); + } + catch (Exception e) { + Log.e(TAG, "reading rendered speech: " + e.toString()); + return null; + } + finally { + if (in != null) { + try { in.close(); } catch (Exception ignored) {} + } + } + } + + // ------------------------------------------------------------------- STT + + public boolean sttAvailable() { + try { + return SpeechRecognizer.isRecognitionAvailable(mActivity); + } + catch (Exception e) { + return false; + } + } + + public void sttStart(final long session, final String languageTag, final boolean partial, final boolean preferOffline) { + mMainHandler.post(new Runnable() { + @Override public void run() { + if (mRecognizers.containsKey(session)) { + return; + } + try { + if (!SpeechRecognizer.isRecognitionAvailable(mActivity)) { + onSttEvent(session, 3, "client", 0.0f); + onSttEvent(session, 4, null, 0.0f); + return; + } + SpeechRecognizer recognizer = SpeechRecognizer.createSpeechRecognizer(mActivity); + mRecognizers.put(session, recognizer); + recognizer.setRecognitionListener(new SessionListener(session)); + + Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); + intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); + intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, languageTag); + intent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, partial); + // API 23. A request, not a promise: an engine with no + // on-device model still recognizes over the network. + intent.putExtra(RecognizerIntent.EXTRA_PREFER_OFFLINE, preferOffline); + // Some engines reject a session without a calling package. + intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, mActivity.getPackageName()); + recognizer.startListening(intent); + } + catch (Exception e) { + Log.e(TAG, "sttStart: " + e.toString()); + onSttEvent(session, 3, "client", 0.0f); + finishSession(session); + } + } + }); + } + + public void sttStop(final long session) { + mMainHandler.post(new Runnable() { + @Override public void run() { + SpeechRecognizer recognizer = mRecognizers.get(session); + if (recognizer == null) { + return; + } + try { + // The final result still arrives, through onResults. + recognizer.stopListening(); + } + catch (Exception e) { + Log.e(TAG, "sttStop: " + e.toString()); + finishSession(session); + } + } + }); + } + + // Exactly one Ended per session: the map entry is the token, and only the + // call that removes it reports the end. + private void finishSession(long session) { + SpeechRecognizer recognizer = mRecognizers.remove(session); + if (recognizer == null) { + return; + } + try { + recognizer.destroy(); + } + catch (Exception e) { + Log.e(TAG, "recognizer destroy: " + e.toString()); + } + onSttEvent(session, 4, null, 0.0f); + } + + private static String firstResult(Bundle results) { + if (results == null) { + return ""; + } + ArrayList texts = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); + if (texts == null || texts.isEmpty() || texts.get(0) == null) { + return ""; + } + return texts.get(0); + } + + private class SessionListener implements RecognitionListener { + private final long mSession; + + SessionListener(long session) { + mSession = session; + } + + @Override public void onReadyForSpeech(Bundle params) {} + @Override public void onBeginningOfSpeech() {} + @Override public void onBufferReceived(byte[] buffer) {} + @Override public void onEndOfSpeech() {} + @Override public void onEvent(int eventType, Bundle params) {} + + @Override public void onRmsChanged(float rmsdB) { + // The framework documents no range; in practice it spans roughly + // -2 dB (silence) to 10 dB (loud), so normalize across that. + float level = (rmsdB + 2.0f) / 12.0f; + if (level < 0.0f) level = 0.0f; + if (level > 1.0f) level = 1.0f; + onSttEvent(mSession, 0, null, level); + } + + @Override public void onPartialResults(Bundle partialResults) { + String text = firstResult(partialResults); + if (!text.isEmpty()) { + onSttEvent(mSession, 1, text, 0.0f); + } + } + + @Override public void onResults(Bundle results) { + onSttEvent(mSession, 2, firstResult(results), 0.0f); + finishSession(mSession); + } + + @Override public void onError(int code) { + String word; + switch (code) { + case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS: word = "permission"; break; + case SpeechRecognizer.ERROR_NETWORK: word = "network"; break; + case SpeechRecognizer.ERROR_NETWORK_TIMEOUT: word = "network"; break; + case SpeechRecognizer.ERROR_SERVER: word = "server"; break; + case SpeechRecognizer.ERROR_AUDIO: word = "audio"; break; + case SpeechRecognizer.ERROR_RECOGNIZER_BUSY: word = "busy"; break; + case SpeechRecognizer.ERROR_NO_MATCH: word = "nomatch"; break; + case SpeechRecognizer.ERROR_SPEECH_TIMEOUT: word = "timeout"; break; + default: word = "client"; break; + } + if (word.equals("nomatch") || word.equals("timeout")) { + // Heard nothing worth a word: an empty utterance, not a failure. + onSttEvent(mSession, 2, "", 0.0f); + } + else { + onSttEvent(mSession, 3, word, 0.0f); + } + finishSession(mSession); + } + } +} diff --git a/tools/cargo_makepad/src/android/mod.rs b/tools/cargo_makepad/src/android/mod.rs index 68768b72b..1cb9e518b 100644 --- a/tools/cargo_makepad/src/android/mod.rs +++ b/tools/cargo_makepad/src/android/mod.rs @@ -129,6 +129,11 @@ impl AndroidVariant { + + + + "# @@ -227,6 +232,11 @@ impl AndroidVariant { + + + + diff --git a/widgets/Cargo.toml b/widgets/Cargo.toml index cf7db5b25..de4c5c982 100644 --- a/widgets/Cargo.toml +++ b/widgets/Cargo.toml @@ -16,7 +16,11 @@ makepad-derive-widget = {path = "./derive_widget", version="2.0.0"} makepad-mbtile-reader = { path = "../libs/mbtile_reader", version = "1.0.0", optional = true } i_overlay = { path = "../libs/i_overlay", version = "7.0.3", optional = true, default-features = false } makepad-fast-inflate = { path = "../libs/fast_inflate", optional = true } -makepad-voice = { path = "../libs/voice", version = "0.1.0", optional = true } +# Silero VAD (the speech gate) from the speech model family; only that module. +makepad-ai-speech = { path = "../libs/ai/models/speech", default-features = false, features = ["vad"], optional = true } +# Speech-to-text sessions (Whisper here / machine / LAN, else the OS engine). +# No default features: only the speech pipes, never the image/video backends. +makepad-ai-hub = { path = "../libs/ai/hub", default-features = false, features = ["stt"], optional = true } makepad-cef = { path = "../libs/cef", optional = true } makepad-html = { path = "../libs/html", version = "1.0.0" } @@ -31,7 +35,7 @@ serde = { version = "1.0", optional = true, features = ["derive"] } [features] default = [] -voice = ["dep:makepad-voice"] +voice = ["dep:makepad-ai-speech", "dep:makepad-ai-hub"] maps = ["dep:makepad-mbtile-reader", "dep:makepad-fast-inflate", "dep:i_overlay"] pdf = ["dep:makepad-pdf-parse"] cef = ["dep:makepad-cef"] diff --git a/widgets/src/window_voice_input.rs b/widgets/src/window_voice_input.rs index 880d7f813..d965667b3 100644 --- a/widgets/src/window_voice_input.rs +++ b/widgets/src/window_voice_input.rs @@ -4,7 +4,8 @@ use crate::makepad_draw::{ thread::SignalToUI, Cx, CxMediaApi, Event, NextFrame, }; -use makepad_voice::{Segment, SileroVad, VadStream, VoiceTranscribeParams, VoiceTranscriber}; +use makepad_ai_hub::speech::{Segment, SttConfig, SttEvent, SttSession}; +use makepad_ai_speech::vad::{SileroVad, VadStream}; use std::collections::VecDeque; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::{self, Receiver, SyncSender}; @@ -39,13 +40,19 @@ const VOICE_ENTER_DELAY_SECS: f64 = 0.075; enum VoiceControlMessage { Reset, - Preload, + /// Capture (re)started: an engine that owns the microphone starts listening. + Start, + /// Capture stopped: a mic-owning engine stops listening. + Stop, Shutdown, } pub enum VoiceWaveEvent { Append(Vec), Submitted(Vec), + /// Input level 0..1 from an engine that owns the microphone (no samples + /// reach us in that mode, so this drives the activity glow instead). + Level(f32), } #[derive(Clone, Debug)] @@ -66,6 +73,10 @@ pub struct WindowVoiceInput { pending_permission_request: Option, capture_enabled: Arc, echo_cancellation: bool, + /// Set by the worker once the recognizer is known to own the microphone + /// itself (Android / Windows system engines): our own capture must then + /// stay off — two recorders on one mic is a conflict, not a feature. + engine_mic: Arc, callback_state: Arc>, control_tx: mpsc::Sender, text_rx: Receiver, @@ -93,6 +104,7 @@ impl Default for WindowVoiceInput { text_signal.clone(), ))); let capture_enabled = Arc::new(AtomicBool::new(false)); + let engine_mic = Arc::new(AtomicBool::new(false)); Self { desired_enabled: false, @@ -102,6 +114,7 @@ impl Default for WindowVoiceInput { default_input: None, pending_permission_request: None, capture_enabled, + engine_mic, // Constant AEC while capturing: swapping the unit mid-stream to // dodge ducking glitches the assistant's own audio start, and // standard+Min ducking is gentle enough to live with. @@ -144,10 +157,14 @@ impl WindowVoiceInput { return; } if let Some((audio_rx, control_rx, text_tx, wave_tx)) = self.worker_inputs.take() { - spawn_voice_worker(audio_rx, control_rx, text_tx, wave_tx, self.text_signal.clone()); - // Keep the backend warm once per instance lifetime: worker/model/ - // threadpools stay alive and are not restarted on mic toggles. - let _ = self.control_tx.send(VoiceControlMessage::Preload); + spawn_voice_worker( + audio_rx, + control_rx, + text_tx, + wave_tx, + self.text_signal.clone(), + self.engine_mic.clone(), + ); } let callback_state = self.callback_state.clone(); let capture_enabled = self.capture_enabled.clone(); @@ -248,13 +265,18 @@ impl WindowVoiceInput { fn start_capture(&mut self, cx: &mut Cx) { self.reset_pipeline(); - let _ = self.control_tx.send(VoiceControlMessage::Preload); + let _ = self.control_tx.send(VoiceControlMessage::Start); self.rearm_capture(cx); } /// (Re)apply device + options for the current capture state. Called on /// start and whenever the echo-cancellation need flips. fn rearm_capture(&mut self, cx: &mut Cx) { + if self.engine_mic.load(Ordering::Relaxed) { + self.capture_enabled.store(false, Ordering::Relaxed); + cx.use_audio_inputs(&[]); + return; + } if let Some(device_id) = self.default_input { self.capture_enabled.store(true, Ordering::Relaxed); cx.use_audio_inputs_with_options( @@ -283,6 +305,7 @@ impl WindowVoiceInput { } fn stop_capture_graceful(&mut self, cx: &mut Cx) { + let _ = self.control_tx.send(VoiceControlMessage::Stop); self.capture_enabled.store(false, Ordering::Relaxed); cx.use_audio_inputs(&[]); if let Ok(mut callback_state) = self.callback_state.lock() { @@ -400,6 +423,10 @@ impl WindowVoiceInput { return Vec::new(); } + if self.engine_mic.load(Ordering::Relaxed) && self.capture_enabled.load(Ordering::Relaxed) { + self.rearm_capture(_cx); + } + let mut text_count = 0usize; while let Ok(text) = self.text_rx.try_recv() { self.queue_transcript_parts(text); @@ -419,6 +446,11 @@ impl WindowVoiceInput { self.submit_flash_until = Self::now_secs() + 0.16; self.voice_active_until = 0.0; } + VoiceWaveEvent::Level(level) => { + if level > 0.3 { + self.voice_active_until = Self::now_secs() + 0.22; + } + } } } @@ -623,21 +655,20 @@ fn spawn_voice_worker( text_tx: mpsc::Sender, wave_tx: SyncSender, text_signal: SignalToUI, + engine_mic: Arc, ) { std::thread::spawn(move || { - let mut transcriber = VoiceTranscriber::from_makepad_env(); - let params = VoiceTranscribeParams::for_live_dictation(); - crate::log!("voice: backend {:?}", transcriber.kind()); - // Eager weight load: otherwise the whisper model loads on the FIRST - // utterance, stalling the first transcription by seconds. - let t0 = std::time::Instant::now(); - match transcriber.preload(¶ms) { - Ok(()) => crate::log!( - "voice: model preloaded in {:.1}s", - t0.elapsed().as_secs_f64() - ), - Err(err) => crate::log!("voice: model preload failed: {err:?}"), - } + // The hub picks the recognizer: Whisper in this process (weights here, + // machine election), on the machine node, on a LAN node, else the OS + // engine. Loading happens on the session's own thread and reports + // through `poll`, so this worker keeps eating audio meanwhile. + let session = SttSession::start(SttConfig::live_dictation()); + // PCM mode (Whisper, Apple): we gate with VAD and hand over utterances. + // Engine-mic mode (Android / Windows system recognizers): the engine + // owns the microphone; we only relay its results. + let mut engine_owns_mic = false; + let mut listening_wanted = false; + let mut engine_ready = false; // Learned gate when the Silero weights are present, RMS energy gate // otherwise. The VAD stream carries its own 512-sample chunking, so it @@ -661,6 +692,62 @@ fn spawn_voice_worker( let mut idle_timeout_ticks = 0usize; 'worker: loop { + for event in session.poll() { + match event { + SttEvent::Loading { phase, fraction } => { + if fraction == 0.0 || fraction >= 1.0 { + crate::log!("voice: {phase}"); + } + } + SttEvent::Ready(info) => { + crate::log!( + "voice: backend {} via {}{} caps={:?}", + info.engine, + info.pipe, + match &info.remote { + Some(node) => format!(" on {node}"), + None => String::new(), + }, + info.capabilities + ); + engine_ready = true; + engine_owns_mic = !info.capabilities.pcm_input && info.capabilities.engine_mic; + if engine_owns_mic { + engine_mic.store(true, Ordering::Relaxed); + // Tell the UI side to release its own capture. + text_signal.set(); + if listening_wanted { + session.listen(); + } + } + } + SttEvent::Failed(why) => { + crate::log!("voice: no speech recognizer available: {why}"); + } + SttEvent::Level(level) => { + let _ = wave_tx.try_send(VoiceWaveEvent::Level(level)); + text_signal.set(); + } + SttEvent::Partial(_) => {} + SttEvent::Final { transcript, secs, .. } => { + let text = normalize_transcript(&transcript.segments); + if !text.is_empty() { + crate::log!("voice: transcript ({secs:.2}s) {text}"); + let _ = text_tx.send(text); + text_signal.set(); + } + } + SttEvent::Error { message, .. } => crate::log!("voice: {message}"), + SttEvent::ListenEnded => { + // Continuous dictation: the engine ends a session per + // utterance; start the next one while the mic is on. + if listening_wanted && engine_owns_mic { + session.listen(); + } + } + } + } + while let Ok(control) = control_rx.try_recv() { match control { VoiceControlMessage::Reset => { @@ -672,9 +759,19 @@ fn spawn_voice_worker( if let Some(vad) = vad.as_mut() { vad.reset(); } + session.cancel(); } - VoiceControlMessage::Preload => { - let _ = transcriber.preload(¶ms); + VoiceControlMessage::Start => { + listening_wanted = true; + if engine_owns_mic && engine_ready { + session.listen(); + } + } + VoiceControlMessage::Stop => { + listening_wanted = false; + if engine_owns_mic { + session.stop_listening(); + } } VoiceControlMessage::Shutdown => break 'worker, } @@ -682,6 +779,10 @@ fn spawn_voice_worker( match audio_rx.recv_timeout(Duration::from_millis(10)) { Ok(audio_chunk) => { + if engine_owns_mic { + // Our capture is being released; nothing to gate. + continue; + } idle_timeout_ticks = 0; // Classify the packet as speech / undecided / pause. Silero // updates its probability every 512 samples, so between @@ -767,13 +868,11 @@ fn spawn_voice_worker( } } - if flush_on_pause || flush_on_idle { - trim_trailing_silence(&mut chunk); - silence_packet_run = 0; - saw_speech_since_flush = false; - voiced_samples_since_flush = 0; - idle_timeout_ticks = 0; - } + trim_trailing_silence(&mut chunk); + silence_packet_run = 0; + saw_speech_since_flush = false; + voiced_samples_since_flush = 0; + idle_timeout_ticks = 0; if chunk.len() < VOICE_TRANSCRIBE_MIN_SAMPLES { continue; @@ -793,23 +892,10 @@ fn spawn_voice_worker( let normalized_chunk = normalize_for_whisper(&chunk); let _ = wave_tx.try_send(VoiceWaveEvent::Submitted(normalized_chunk.clone())); text_signal.set(); - - let segments = match transcriber.transcribe(&normalized_chunk, ¶ms) { - Ok(segments) => segments, - Err(_) => Vec::new(), - }; - let text = normalize_transcript(&segments); - if !text.is_empty() { - crate::log!("voice: transcript {}", text); - let _ = text_tx.send(text); - text_signal.set(); - } - - // After any submission, wait for fresh voiced audio before next flush. - silence_packet_run = 0; - saw_speech_since_flush = false; - voiced_samples_since_flush = 0; - idle_timeout_ticks = 0; + // Non-blocking: the session recognizes on its own thread and + // the result comes back through `poll` above, so audio keeps + // flowing into the gate while Whisper works. + session.transcribe(normalized_chunk); } } }); From 45b5b98612667708370a10a29c01e234cbe96ef1 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 23:33:26 +0200 Subject: [PATCH 029/417] ai-body: the crop size is a runtime knob, and the loop reports where its time goes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The backbone, conditioning and decoder now take any square crop whose side is a multiple of 16 (512 is the trained size); BodyModel::set_crop_size selects it and caches the dense positional grid per size. Measured on the oracle image against the reference: 512 gives 1.7 mm mean keypoint error, 384 and 256 about 2 cm mean (6 to 7 cm worst joint), 192 falls apart — the knob is a real accuracy trade, not free speed. The decoder loop reports its split (layer chain, heads, rig+camera, refinement) so the next optimisation is chosen on numbers. Co-Authored-By: Claude Fable 5.1 --- libs/ai/models/body/src/condition.rs | 35 ++++++----- libs/ai/models/body/src/decoder.rs | 51 ++++++++++++---- libs/ai/models/body/src/dino.rs | 67 +++++++++++++-------- libs/ai/models/body/src/model.rs | 86 +++++++++++++++++++++++---- libs/ai/models/body/src/preprocess.rs | 55 ++++++++++++----- 5 files changed, 215 insertions(+), 79 deletions(-) diff --git a/libs/ai/models/body/src/condition.rs b/libs/ai/models/body/src/condition.rs index 26418dc18..3b31e5323 100644 --- a/libs/ai/models/body/src/condition.rs +++ b/libs/ai/models/body/src/condition.rs @@ -11,13 +11,18 @@ const RAY_FEATURES: usize = 99; const RAY_FREQUENCIES: usize = 16; pub fn dense_pe(g: &[f32]) -> Vec { + dense_pe_at(g, PATCHES_SIDE) +} + +/// The dense positional encoding of a `side x side` patch grid. +pub fn dense_pe_at(g: &[f32], side: usize) -> Vec { assert_eq!(g.len(), 2 * PE_HALF, "dense PE matrix must be 2x640"); - let mut output = vec![0.0f32; NUM_PATCHES * DINO_DIM]; - for gy in 0..PATCHES_SIDE { - let y = 2.0 * ((gy as f32 + 0.5) / PATCHES_SIDE as f32) - 1.0; - for gx in 0..PATCHES_SIDE { - let x = 2.0 * ((gx as f32 + 0.5) / PATCHES_SIDE as f32) - 1.0; - let row = gy * PATCHES_SIDE + gx; + let mut output = vec![0.0f32; side * side * DINO_DIM]; + for gy in 0..side { + let y = 2.0 * ((gy as f32 + 0.5) / side as f32) - 1.0; + for gx in 0..side { + let x = 2.0 * ((gx as f32 + 0.5) / side as f32) - 1.0; + let row = gy * side + gx; for k in 0..PE_HALF { let angle = 2.0 * std::f32::consts::PI * (x * g[k] + y * g[PE_HALF + k]); output[row * DINO_DIM + k] = angle.sin(); @@ -29,9 +34,10 @@ pub fn dense_pe(g: &[f32]) -> Vec { } pub fn ray_features(rays: &[f32]) -> Vec { - assert_eq!(rays.len(), NUM_PATCHES * 2, "patch rays must be 1024x2"); - let mut output = vec![0.0f32; NUM_PATCHES * RAY_FEATURES]; - for token in 0..NUM_PATCHES { + assert_eq!(rays.len() % 2, 0, "patch rays must be (x, y) pairs"); + let tokens = rays.len() / 2; + let mut output = vec![0.0f32; tokens * RAY_FEATURES]; + for token in 0..tokens { let ray = [rays[token * 2], rays[token * 2 + 1], 1.0]; let row = &mut output[token * RAY_FEATURES..(token + 1) * RAY_FEATURES]; row[..3].copy_from_slice(&ray); @@ -90,18 +96,19 @@ impl RayCond { no_mask_embed: &[f32; DINO_DIM], feats: &[f32], ) -> Result { - if e.rows() != NUM_PATCHES || e.cols() != DINO_DIM { + let tokens = e.rows(); + if e.cols() != DINO_DIM { return Err(DiffusionError::workflow(format!( - "ray conditioning image shape is {}x{}, expected {NUM_PATCHES}x{DINO_DIM}", + "ray conditioning image shape is {}x{}, expected {tokens}x{DINO_DIM}", e.rows(), e.cols() ))); } - if feats.len() != NUM_PATCHES * RAY_FEATURES { + if feats.len() != tokens * RAY_FEATURES { return Err(DiffusionError::workflow(format!( "ray conditioning features have {} values, expected {}", feats.len(), - NUM_PATCHES * RAY_FEATURES + tokens * RAY_FEATURES ))); } // W_e no_mask: 1.6M multiply-adds on the host, once per frame. @@ -111,7 +118,7 @@ impl RayCond { *value = row.iter().zip(no_mask_embed).map(|(w, m)| w * m).sum(); } let bias = gpu_upload(&bias, 1, DINO_DIM).map_err(DiffusionError::model)?; - let feats = gpu_upload(feats, NUM_PATCHES, RAY_FEATURES).map_err(DiffusionError::model)?; + let feats = gpu_upload(feats, tokens, RAY_FEATURES).map_err(DiffusionError::model)?; let from_image = gpu_linear_f32_resident(e, &self.image_w, None).map_err(DiffusionError::model)?; let from_rays = gpu_linear_f32_resident(&feats, &self.ray_w, Some(&bias)).map_err(DiffusionError::model)?; diff --git a/libs/ai/models/body/src/decoder.rs b/libs/ai/models/body/src/decoder.rs index 64b149d0e..f43d9db2a 100644 --- a/libs/ai/models/body/src/decoder.rs +++ b/libs/ai/models/body/src/decoder.rs @@ -8,7 +8,7 @@ use crate::heads::{DecoderHeads, GpuStepHeads, HostLinear}; use crate::weights::BodyWeights; use crate::{ DEC_DEPTH, DEC_DIM, DEC_FFN, DEC_HEADS, DEC_INNER, DEC_NORM_EPS, DINO_DIM, NCAM, - NPOSE, NUM_KEYPOINTS, NUM_PATCHES, PATCHES_SIDE, DiffusionError, Result, + NPOSE, NUM_KEYPOINTS, DiffusionError, Result, }; pub const TOKEN_ROWS: usize = 5 + 2 * NUM_KEYPOINTS; @@ -320,6 +320,18 @@ pub struct DecoderOutput { pub hand_logits: [[f32; 2]; 2], pub last_pose_pred: Vec, pub last_cam_pred: Vec, + pub timing: LoopTiming, +} + +/// Where the loop's time went, milliseconds over all six steps: the GPU +/// layer chain, the pose-row fetch + heads, the caller's step (rig, camera, +/// projection), and the refinement update (FFNs, sampling, uploads). +#[derive(Clone, Copy, Debug, Default)] +pub struct LoopTiming { + pub layers_ms: f32, + pub heads_ms: f32, + pub step_ms: f32, + pub refine_ms: f32, } impl Decoder { @@ -370,16 +382,20 @@ impl Decoder { F: FnMut(StepInput) -> StepFeedback, { validate_run_inputs(&tokens, context, context_pe)?; + let context_rows = context.rows(); + let grid_side = (context_rows as f64).sqrt().round() as usize; let context_host = gpu_download(context).map_err(DiffusionError::model)?; - let context_pe = gpu_upload(context_pe, NUM_PATCHES, DINO_DIM) + let context_pe = gpu_upload(context_pe, context_rows, DINO_DIM) .map_err(DiffusionError::model)?; let mut hidden = gpu_upload(&tokens.tokens, TOKEN_ROWS, DEC_DIM) .map_err(DiffusionError::model)?; let mut final_normed = Vec::new(); let mut last_pose = Vec::new(); let mut last_camera = Vec::new(); + let mut timing = LoopTiming::default(); for (layer_index, layer) in self.layers.iter().enumerate() { + let t0 = std::time::Instant::now(); let token_pe = gpu_upload(&tokens.token_augment, TOKEN_ROWS, DEC_DIM) .map_err(DiffusionError::model)?; let token_pe = layer_norm_gpu(&token_pe, &layer.ln_pe_1)?; @@ -410,6 +426,8 @@ impl Decoder { hidden = gpu_add(&hidden, &ffn).map_err(DiffusionError::model)?; let normed = layer_norm_gpu(&hidden, &self.norm_final)?; + timing.layers_ms += t0.elapsed().as_secs_f32() * 1000.0; + let t1 = std::time::Instant::now(); // Only the pose token leaves the GPU mid-loop; the whole block // is downloaded once at the end (the hand-box rows and the // output) or when a trace wants every layer. @@ -429,18 +447,28 @@ impl Decoder { add_in_place(&mut last_pose, &self.init_pose); last_camera = self.step_heads.camera(pose_token)?; add_in_place(&mut last_camera, &self.init_camera); + timing.heads_ms += t1.elapsed().as_secs_f32() * 1000.0; + let t2 = std::time::Instant::now(); let feedback = step(StepInput { layer: layer_index, pose_pred_519: last_pose.clone(), cam_pred_3: last_camera.clone(), tokens_normed_row0: pose_token.to_vec(), }); + timing.step_ms += t2.elapsed().as_secs_f32() * 1000.0; if layer_index + 1 < DEC_DEPTH { - let delta = self.refinement_update(&mut tokens.token_augment, &context_host, feedback)?; + let t3 = std::time::Instant::now(); + let delta = self.refinement_update( + &mut tokens.token_augment, + &context_host, + grid_side, + feedback, + )?; let delta = gpu_upload(&delta, TOKEN_ROWS, DEC_DIM) .map_err(DiffusionError::model)?; hidden = gpu_add(&hidden, &delta).map_err(DiffusionError::model)?; + timing.refine_ms += t3.elapsed().as_secs_f32() * 1000.0; } } @@ -457,6 +485,7 @@ impl Decoder { hand_logits, last_pose_pred: last_pose, last_cam_pred: last_camera, + timing, }) } @@ -464,6 +493,7 @@ impl Decoder { &self, token_augment: &mut [f32], context: &[f32], + grid_side: usize, feedback: StepFeedback, ) -> Result> { if feedback.kp2d_cropped.len() != NUM_KEYPOINTS * 2 @@ -497,8 +527,8 @@ impl Decoder { if valid[index] { let value = bilinear_sample( context, - PATCHES_SIDE, - PATCHES_SIDE, + grid_side, + grid_side, DINO_DIM, 2.0 * point[0], 2.0 * point[1], @@ -592,20 +622,21 @@ fn validate_run_inputs(tokens: &TokenSet, context: &GpuTensor, context_pe: &[f32 TOKEN_ROWS * DEC_DIM, ))); } - if context.rows() != NUM_PATCHES || context.cols() != DINO_DIM { + let rows = context.rows(); + let side = (rows as f64).sqrt().round() as usize; + if context.cols() != DINO_DIM || side * side != rows { return Err(DiffusionError::workflow(format!( - "decoder context is {}x{}, expected {}x{}", + "decoder context is {}x{}, expected a square patch grid x {}", context.rows(), context.cols(), - NUM_PATCHES, DINO_DIM, ))); } - if context_pe.len() != NUM_PATCHES * DINO_DIM { + if context_pe.len() != rows * DINO_DIM { return Err(DiffusionError::workflow(format!( "decoder context PE has {} values, expected {}", context_pe.len(), - NUM_PATCHES * DINO_DIM, + rows * DINO_DIM, ))); } Ok(()) diff --git a/libs/ai/models/body/src/dino.rs b/libs/ai/models/body/src/dino.rs index 104db077f..6643d8ef4 100644 --- a/libs/ai/models/body/src/dino.rs +++ b/libs/ai/models/body/src/dino.rs @@ -13,8 +13,8 @@ use crate::backend::{ use crate::weights::BodyWeights; use crate::{ emit_progress, DiffusionError, ProgressHook, Result, DINO_DEPTH, DINO_DIM, DINO_FFN, - DINO_HEADS, DINO_HEAD_DIM, DINO_NORM_EPS, DINO_PREFIX_TOKENS, DINO_ROPE_BASE, IMAGE_SIZE, - NUM_PATCHES, PATCH, PATCHES_SIDE, ROPE_HALF, + DINO_HEADS, DINO_HEAD_DIM, DINO_NORM_EPS, DINO_PREFIX_TOKENS, DINO_ROPE_BASE, PATCH, + ROPE_HALF, }; use makepad_ai_common::quant::GGML_TYPE_BF16; use makepad_ai_loader::MlxDType; @@ -164,6 +164,21 @@ fn f32_to_bf16_bytes(values: &[f32]) -> Vec { bytes } +/// The crop side of a normalised CHW buffer: square, a multiple of the patch. +pub(crate) fn crop_side(values: usize) -> Result { + if values % 3 != 0 { + return Err(DiffusionError::workflow(format!("body crop has {values} values, not 3 planes"))); + } + let plane = values / 3; + let side = (plane as f64).sqrt().round() as usize; + if side * side != plane || side % PATCH != 0 || side == 0 { + return Err(DiffusionError::workflow(format!( + "body crop plane of {plane} values is not a square with a side that is a multiple of {PATCH}" + ))); + } + Ok(side) +} + /// Head-dim-64 attention: the FA2 flash kernel (f16 operands, f32 softmax /// and accumulation — the reference's own precision class) where the /// backend has it, else the composite f32 path. @@ -274,19 +289,19 @@ impl BodyDino { }) } - fn rope_tables(&self) -> (Vec, Vec) { - let rows = DINO_PREFIX_TOKENS + NUM_PATCHES; + fn rope_tables(&self, side: usize) -> (Vec, Vec) { + let rows = DINO_PREFIX_TOKENS + side * side; let mut inv_freq = [0.0f32; 16]; for (j, value) in inv_freq.iter_mut().enumerate() { *value = 1.0 / DINO_ROPE_BASE.powf(j as f32 * 4.0 / DINO_HEAD_DIM as f32); } let mut cos = vec![1.0f32; rows * ROPE_HALF]; let mut sin = vec![0.0f32; rows * ROPE_HALF]; - for gy in 0..PATCHES_SIDE { - for gx in 0..PATCHES_SIDE { - let row = DINO_PREFIX_TOKENS + gy * PATCHES_SIDE + gx; - let y = 2.0 * ((gy as f32 + 0.5) / PATCHES_SIDE as f32) - 1.0; - let x = 2.0 * ((gx as f32 + 0.5) / PATCHES_SIDE as f32) - 1.0; + for gy in 0..side { + for gx in 0..side { + let row = DINO_PREFIX_TOKENS + gy * side + gx; + let y = 2.0 * ((gy as f32 + 0.5) / side as f32) - 1.0; + let x = 2.0 * ((gx as f32 + 0.5) / side as f32) - 1.0; for (j, frequency) in inv_freq.iter().enumerate() { let ay = 2.0 * std::f32::consts::PI * y * frequency; let ax = 2.0 * std::f32::consts::PI * x * frequency; @@ -300,40 +315,39 @@ impl BodyDino { (cos, sin) } + /// `pixels` is a normalised CHW crop of any square side that is a + /// multiple of the patch (512 is the trained size); the output has + /// `(side / 16)^2` rows. pub fn forward_normalized(&self, pixels: &[f32]) -> Result { - if pixels.len() != 3 * IMAGE_SIZE * IMAGE_SIZE { - return Err(DiffusionError::workflow(format!( - "body DINO input has {} values, expected {}", - pixels.len(), - 3 * IMAGE_SIZE * IMAGE_SIZE - ))); - } + let size = crop_side(pixels.len())?; + let side = size / PATCH; + let num_patches = side * side; // Patch vectors use [channel][patch_y][patch_x], matching flattened // conv2d weights [out, channel, patch_y, patch_x]. - let mut patch_rows = vec![0.0f32; NUM_PATCHES * PATCH_DIM]; - let plane = IMAGE_SIZE * IMAGE_SIZE; - for gy in 0..PATCHES_SIDE { - for gx in 0..PATCHES_SIDE { - let row = gy * PATCHES_SIDE + gx; + let mut patch_rows = vec![0.0f32; num_patches * PATCH_DIM]; + let plane = size * size; + for gy in 0..side { + for gx in 0..side { + let row = gy * side + gx; let base = row * PATCH_DIM; for c in 0..3 { for py in 0..PATCH { - let src = c * plane + (gy * PATCH + py) * IMAGE_SIZE + gx * PATCH; + let src = c * plane + (gy * PATCH + py) * size + gx * PATCH; let dst = base + c * PATCH * PATCH + py * PATCH; patch_rows[dst..dst + PATCH].copy_from_slice(&pixels[src..src + PATCH]); } } } } - let patch_rows = gpu_upload(&patch_rows, NUM_PATCHES, PATCH_DIM) + let patch_rows = gpu_upload(&patch_rows, num_patches, PATCH_DIM) .map_err(DiffusionError::model)?; let patches = self.patch.forward(&patch_rows)?; let mut hidden = gpu_concat_rows_many(&[&self.prefix, &patches]) .map_err(DiffusionError::model)?; - let rows = DINO_PREFIX_TOKENS + NUM_PATCHES; - let (cos, sin) = self.rope_tables(); + let rows = DINO_PREFIX_TOKENS + num_patches; + let (cos, sin) = self.rope_tables(side); let cos = gpu_upload(&cos, rows, ROPE_HALF).map_err(DiffusionError::model)?; let sin = gpu_upload(&sin, rows, ROPE_HALF).map_err(DiffusionError::model)?; @@ -378,7 +392,7 @@ impl BodyDino { DINO_NORM_EPS, ) .map_err(DiffusionError::model)?; - gpu_slice_rows(&normalized, DINO_PREFIX_TOKENS, NUM_PATCHES) + gpu_slice_rows(&normalized, DINO_PREFIX_TOKENS, num_patches) .map_err(DiffusionError::model) } @@ -392,6 +406,7 @@ impl BodyDino { mod tests { use super::*; use crate::backend::gpu_device_available; + use crate::{NUM_PATCHES, PATCHES_SIDE}; fn planar_to_tokens(values: &[f32]) -> Vec { let mut output = vec![0.0f32; NUM_PATCHES * DINO_DIM]; diff --git a/libs/ai/models/body/src/model.rs b/libs/ai/models/body/src/model.rs index 09b30d226..f99cd4862 100644 --- a/libs/ai/models/body/src/model.rs +++ b/libs/ai/models/body/src/model.rs @@ -7,17 +7,20 @@ //! parameters come from the body decoder, the hand crops of the reference's //! "full" mode are a later phase. -use crate::condition::{dense_pe, ray_features, RayCond}; -use crate::decoder::{Decoder, StepFeedback, StepInput}; +use crate::condition::{dense_pe_at, ray_features, RayCond}; +use crate::decoder::{Decoder, LoopTiming, StepFeedback, StepInput}; use crate::dino::BodyDino; use crate::mhr::MhrRig; use crate::packet::{BodyPacket, BodyPerson}; use crate::pose::{camera_translation, model_params, project, unpack_pose, PoseHeadParams}; use crate::preprocess::{ - condition_info, crop_geometry, crop_normalized, full_to_crop, patch_rays, CropGeometry, + condition_info, crop_geometry_at, crop_normalized, full_to_crop, patch_rays, CropGeometry, }; use crate::weights::BodyWeights; -use crate::{DiffusionError, ProgressHook, Result, DINO_DIM, MHR_JOINTS, NUM_KEYPOINTS}; +use crate::{ + DiffusionError, ProgressHook, Result, DINO_DIM, IMAGE_SIZE, MHR_JOINTS, NUM_KEYPOINTS, PATCH, +}; +use std::collections::HashMap; use std::path::Path; use std::time::Instant; @@ -25,13 +28,19 @@ pub struct BodyModel { pub weights: BodyWeights, dino: BodyDino, ray_cond: RayCond, - dense_pe: Vec, + gaussian: Vec, + dense_pe: HashMap>, no_mask_embed: [f32; DINO_DIM], decoder: Decoder, rig: MhrRig, + /// The crop side the backbone sees; 512 is the trained size, smaller is + /// faster and less accurate (see `set_crop_size`). + crop_size: usize, /// Per-stage wall times of the last `infer`, milliseconds: /// crop, backbone, context, decoder loop (incl. rig), packet. pub last_stage_ms: [f32; 5], + /// The decoder loop's breakdown for the last `infer`. + pub last_loop: LoopTiming, } /// Everything one refinement step produced; the last one is the answer. @@ -63,16 +72,41 @@ impl BodyModel { let decoder = Decoder::load(&weights)?; let mut rig = MhrRig::load(&weights)?; rig.prepare_gpu()?; - Ok(Self { + let mut model = Self { weights, dino, ray_cond, - dense_pe: dense_pe(&gaussian), + gaussian, + dense_pe: HashMap::new(), no_mask_embed, decoder, rig, + crop_size: IMAGE_SIZE, last_stage_ms: [0.0; 5], - }) + last_loop: LoopTiming::default(), + }; + model.set_crop_size(IMAGE_SIZE)?; + Ok(model) + } + + /// The crop side: a multiple of 16 between 128 and 1024. The model was + /// trained at 512; 256 runs the backbone on a quarter of the tokens. + pub fn set_crop_size(&mut self, size: usize) -> Result<()> { + if size % PATCH != 0 || !(128..=1024).contains(&size) { + return Err(DiffusionError::workflow(format!( + "body crop size {size}: must be a multiple of {PATCH} in 128..=1024" + ))); + } + let side = size / PATCH; + if !self.dense_pe.contains_key(&size) { + self.dense_pe.insert(size, dense_pe_at(&self.gaussian, side)); + } + self.crop_size = size; + Ok(()) + } + + pub fn crop_size(&self) -> usize { + self.crop_size } /// `rgb` is `width * height * 3` bytes; `bbox` is the person box in @@ -94,7 +128,7 @@ impl BodyModel { } let bbox = bbox.unwrap_or([0.0, 0.0, width as f32, height as f32]); let total = Instant::now(); - let geo = crop_geometry(bbox, w, h, None); + let geo = crop_geometry_at(bbox, w, h, None, self.crop_size); let crop = crop_normalized(rgb, w, h, &geo); let t_crop = total.elapsed(); @@ -108,9 +142,11 @@ impl BodyModel { let tokens = self.decoder.build_tokens(condition_info(&geo)); let rig = &self.rig; + let dense_pe = &self.dense_pe[&self.crop_size]; let mut last: Option = None; - self.decoder - .run(tokens, &context, &self.dense_pe, |step: StepInput| { + let output = self + .decoder + .run(tokens, &context, dense_pe, |step: StepInput| { let result = close_the_loop(rig, &geo, &step); let feedback = StepFeedback { kp2d_cropped: full_to_crop(&result.kp2d, &geo), @@ -120,6 +156,7 @@ impl BodyModel { last = Some(result); feedback })?; + self.last_loop = output.timing; let t_decoder = total.elapsed(); let last = last.ok_or_else(|| DiffusionError::model("body decoder ran no steps"))?; @@ -233,14 +270,37 @@ mod tests { // A second run reports the warm timings. let packet = model.infer(&rgb, w, h, None).unwrap_or(packet); eprintln!( - "body infer warm {:.1} ms: crop {:.1}, backbone {:.1}, context {:.1}, decoder+rig {:.1}, packet {:.1}", + "body infer warm {:.1} ms: crop {:.1}, backbone {:.1}, context {:.1}, decoder+rig {:.1}, packet {:.1}; loop: layers {:.1}, heads {:.1}, rig+camera {:.1}, refine {:.1}", packet.ms, model.last_stage_ms[0], model.last_stage_ms[1], model.last_stage_ms[2], model.last_stage_ms[3], - model.last_stage_ms[4] + model.last_stage_ms[4], + model.last_loop.layers_ms, + model.last_loop.heads_ms, + model.last_loop.step_ms, + model.last_loop.refine_ms ); + // The same image through smaller crops: the speed/accuracy knob, + // reported against the reference at 512 (not asserted tightly: these + // sizes were never trained). + let reference_kp3d = fixture::load("final_pred_keypoints_3d").unwrap().1; + let reference_kp2d = fixture::load("final_pred_keypoints_2d").unwrap().1; + for size in [384usize, 256, 192] { + model.set_crop_size(size).expect("crop size"); + let _ = model.infer(&rgb, w, h, None).expect("infer at size"); + let small = model.infer(&rgb, w, h, None).expect("infer at size"); + let (e3, _) = max_abs(&small.people[0].kp3d, &reference_kp3d); + let (e2, _) = max_abs(&small.people[0].kp2d, &reference_kp2d); + let mean3: f32 = small.people[0].kp3d.iter().zip(&reference_kp3d).map(|(a, b)| (a - b).abs()).sum::() / reference_kp3d.len() as f32; + eprintln!( + "body crop {size}: warm {:.1} ms (backbone {:.1}, loop {:.1}); vs reference kp3d max {e3:.4} m mean {mean3:.4} m, kp2d max {e2:.2} px", + small.ms, model.last_stage_ms[1], model.last_stage_ms[3] + ); + assert!(e3 < 0.15, "crop {size} is off by {e3} m"); + } + model.set_crop_size(IMAGE_SIZE).expect("crop size"); let person = &packet.people[0]; let (kp3d_err, kp3d_at) = max_abs(&person.kp3d, &fixture::load("final_pred_keypoints_3d").unwrap().1); let (kp2d_err, kp2d_at) = max_abs(&person.kp2d, &fixture::load("final_pred_keypoints_2d").unwrap().1); diff --git a/libs/ai/models/body/src/preprocess.rs b/libs/ai/models/body/src/preprocess.rs index c67deaf14..c1a3ea70d 100644 --- a/libs/ai/models/body/src/preprocess.rs +++ b/libs/ai/models/body/src/preprocess.rs @@ -1,6 +1,6 @@ //! CPU crop, camera conditioning, and patch-ray construction. -use crate::{IMAGE_SIZE, PATCH, PATCHES_SIDE}; +use crate::{IMAGE_SIZE, PATCH}; const IMAGENET_MEAN: [f32; 3] = [0.485, 0.456, 0.406]; const IMAGENET_STD: [f32; 3] = [0.229, 0.224, 0.225]; @@ -13,6 +13,9 @@ pub struct CropGeometry { pub affine: [f32; 6], pub focal: f32, pub principal: [f32; 2], + /// The crop's pixel size (square, a multiple of the patch): 512 is what + /// the model was trained at; smaller trades accuracy for speed. + pub crop: usize, } pub fn crop_geometry( @@ -20,6 +23,16 @@ pub fn crop_geometry( image_w: usize, image_h: usize, intrinsics: Option<[f32; 3]>, +) -> CropGeometry { + crop_geometry_at(bbox_xyxy, image_w, image_h, intrinsics, IMAGE_SIZE) +} + +pub fn crop_geometry_at( + bbox_xyxy: [f32; 4], + image_w: usize, + image_h: usize, + intrinsics: Option<[f32; 3]>, + crop: usize, ) -> CropGeometry { let center = [ 0.5 * (bbox_xyxy[0] + bbox_xyxy[2]), @@ -35,14 +48,14 @@ pub fn crop_geometry( scale[0] = scale[1] * 0.75; } let side = scale[0].max(scale[1]); - let k = IMAGE_SIZE as f32 / side; + let k = crop as f32 / side; let affine = [ k, 0.0, - 0.5 * IMAGE_SIZE as f32 - k * center[0], + 0.5 * crop as f32 - k * center[0], 0.0, k, - 0.5 * IMAGE_SIZE as f32 - k * center[1], + 0.5 * crop as f32 - k * center[1], ]; let [focal, cx, cy] = intrinsics.unwrap_or_else(|| { let w = image_w as f32; @@ -55,6 +68,7 @@ pub fn crop_geometry( affine, focal, principal: [cx, cy], + crop, } } @@ -84,16 +98,17 @@ pub fn crop_normalized( h: usize, geo: &CropGeometry, ) -> Vec { - let mut output = vec![0.0; 3 * IMAGE_SIZE * IMAGE_SIZE]; + let crop = geo.crop; + let mut output = vec![0.0; 3 * crop * crop]; let k = geo.affine[0]; - let plane = IMAGE_SIZE * IMAGE_SIZE; - for v in 0..IMAGE_SIZE { + let plane = crop * crop; + for v in 0..crop { let src_y = (v as f32 - geo.affine[5]) / k; - for u in 0..IMAGE_SIZE { + for u in 0..crop { let src_x = (u as f32 - geo.affine[2]) / k; for c in 0..3 { let pixel = bilinear_zero_border(rgb, w, h, src_x, src_y, c) / 255.0; - output[c * plane + v * IMAGE_SIZE + u] = + output[c * plane + v * crop + u] = (pixel - IMAGENET_MEAN[c]) / IMAGENET_STD[c]; } } @@ -117,11 +132,15 @@ pub fn condition_info(geo: &CropGeometry) -> [f32; 3] { /// for interior patches, pulled inward at the two edges (oracle-verified: /// block centres are 0.1 off in the conditioned context, this is 1e-3). pub fn patch_sample_coord(index: usize) -> f32 { + patch_sample_coord_at(index, IMAGE_SIZE) +} + +pub fn patch_sample_coord_at(index: usize, crop: usize) -> f32 { let centre = (index as f32 + 0.5) * PATCH as f32 - 0.5; let mut weight_sum = 0.0f32; let mut coord_sum = 0.0f32; let lo = (centre - PATCH as f32).floor().max(0.0) as usize; - let hi = ((centre + PATCH as f32).ceil() as usize).min(IMAGE_SIZE - 1); + let hi = ((centre + PATCH as f32).ceil() as usize).min(crop - 1); for tap in lo..=hi { let weight = (1.0 - (tap as f32 - centre).abs() / PATCH as f32).max(0.0); weight_sum += weight; @@ -131,12 +150,13 @@ pub fn patch_sample_coord(index: usize) -> f32 { } pub fn patch_rays(geo: &CropGeometry) -> Vec { - let mut rays = Vec::with_capacity(PATCHES_SIDE * PATCHES_SIDE * 2); + let side = geo.crop / PATCH; + let mut rays = Vec::with_capacity(side * side * 2); let k = geo.affine[0]; - let coords: Vec = (0..PATCHES_SIDE).map(patch_sample_coord).collect(); - for gy in 0..PATCHES_SIDE { + let coords: Vec = (0..side).map(|i| patch_sample_coord_at(i, geo.crop)).collect(); + for gy in 0..side { let full_y = (coords[gy] - geo.affine[5]) / k; - for gx in 0..PATCHES_SIDE { + for gx in 0..side { let full_x = (coords[gx] - geo.affine[2]) / k; rays.push((full_x - geo.principal[0]) / geo.focal); rays.push((full_y - geo.principal[1]) / geo.focal); @@ -150,8 +170,8 @@ pub fn full_to_crop(kp2d_full: &[f32], geo: &CropGeometry) -> Vec { for point in kp2d_full.chunks_exact(2) { let x = geo.affine[0] * point[0] + geo.affine[1] * point[1] + geo.affine[2]; let y = geo.affine[3] * point[0] + geo.affine[4] * point[1] + geo.affine[5]; - output.push(x / IMAGE_SIZE as f32 - 0.5); - output.push(y / IMAGE_SIZE as f32 - 0.5); + output.push(x / geo.crop as f32 - 0.5); + output.push(y / geo.crop as f32 - 0.5); } output } @@ -159,6 +179,7 @@ pub fn full_to_crop(kp2d_full: &[f32], geo: &CropGeometry) -> Vec { #[cfg(test)] mod tests { use super::*; + use crate::PATCHES_SIDE; fn assert_close(actual: f32, expected: f32, tolerance: f32) { assert!( @@ -193,6 +214,7 @@ mod tests { affine: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0], focal: 512.0, principal: [256.0, 256.0], + crop: IMAGE_SIZE, }; let rays = patch_rays(&geo); assert_eq!(rays.len(), 1024 * 2); @@ -246,6 +268,7 @@ mod tests { ], focal, principal: [cx, cy], + crop: IMAGE_SIZE, }; let rgb: Vec = image_values.iter().map(|value| *value as u8).collect(); let crop = crop_normalized(&rgb, w, h, &geo); From 4be6d1969514ee8b5cafa7dd9f3eb37119cb28f9 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 23:43:53 +0200 Subject: [PATCH 030/417] ai-body: the test modules import the grid constants they still use Co-Authored-By: Claude Fable 5.1 --- libs/ai/models/body/src/condition.rs | 3 ++- libs/ai/models/body/src/decoder.rs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/ai/models/body/src/condition.rs b/libs/ai/models/body/src/condition.rs index 3b31e5323..b775ea11b 100644 --- a/libs/ai/models/body/src/condition.rs +++ b/libs/ai/models/body/src/condition.rs @@ -4,7 +4,7 @@ use crate::backend::{ gpu_add, gpu_layer_norm_mul_add, gpu_linear_f32_resident, gpu_upload, GpuTensor, }; use crate::weights::BodyWeights; -use crate::{DiffusionError, Result, DEC_NORM_EPS, DINO_DIM, NUM_PATCHES, PATCHES_SIDE}; +use crate::{DiffusionError, Result, DEC_NORM_EPS, DINO_DIM, PATCHES_SIDE}; const PE_HALF: usize = DINO_DIM / 2; const RAY_FEATURES: usize = 99; @@ -132,6 +132,7 @@ impl RayCond { mod tests { use super::*; use crate::backend::{gpu_device_available, gpu_download, gpu_upload}; + use crate::NUM_PATCHES; fn assert_close(actual: f32, expected: f32, tolerance: f32) { assert!( diff --git a/libs/ai/models/body/src/decoder.rs b/libs/ai/models/body/src/decoder.rs index f43d9db2a..142f619db 100644 --- a/libs/ai/models/body/src/decoder.rs +++ b/libs/ai/models/body/src/decoder.rs @@ -738,6 +738,7 @@ mod tests { use super::*; use crate::backend::gpu_device_available; use crate::fixture; + use crate::NUM_PATCHES; fn identity(input: &[f32]) -> Vec { input.to_vec() From 7598346ff5e717b1ebb14efd0145d0c7be07b335 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 23:49:46 +0200 Subject: [PATCH 031/417] ai-body: tensor-core GEMMs for the backbone, and the rig's correctives only where they count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The backbone's linears now take the cuBLASLt bias-epilogue / bf16 mm paths (bf16 operands, f32 accumulation, bf16 output — the reference's precision) with the f32-accumulating GEMM as the fallback. The rig's pose correctives run on the final refinement step only by default: the intermediate steps only feed keypoints back into the decoder, and the oracle shows the difference is 0.4 mm (2.1 vs 1.7 mm against the reference) for half the loop's rig time; `correctives_every_step` keeps the exact mode. Co-Authored-By: Claude Fable 5.1 --- libs/ai/models/body/src/dino.rs | 47 ++++++++++++++++++++++---------- libs/ai/models/body/src/model.rs | 25 +++++++++++++++-- 2 files changed, 55 insertions(+), 17 deletions(-) diff --git a/libs/ai/models/body/src/dino.rs b/libs/ai/models/body/src/dino.rs index 6643d8ef4..1f0881e25 100644 --- a/libs/ai/models/body/src/dino.rs +++ b/libs/ai/models/body/src/dino.rs @@ -6,8 +6,8 @@ use crate::backend::{ gpu_add, gpu_attention_packed_cross, gpu_attention_packed_flash2_d64, gpu_concat_rows_many, - gpu_download, - gpu_layer_norm_mul_add, gpu_linear_nt_cached_bf16_f32acc, gpu_mul, gpu_rope_half, + gpu_download, gpu_layer_norm_mul_add, gpu_linear_nt_cached_bf16_bias_epilogue, + gpu_linear_nt_cached_bf16_f32acc, gpu_linear_nt_cached_bf16_mm, gpu_mul, gpu_rope_half, gpu_silu, gpu_slice_rows, gpu_upload, GpuLinearPart, GpuTensor, }; use crate::weights::BodyWeights; @@ -89,19 +89,38 @@ impl Bf16Linear { }) } + /// The tensor-core paths first (cuBLASLt with the bias in the epilogue, + /// or the bias-free bf16 mm), the f32-accumulating GEMM as the fallback + /// where a backend lacks them. All three carry bf16 operands with f32 + /// accumulation; the fast paths round the output to bf16, which is the + /// reference's own precision. fn forward(&self, input: &GpuTensor) -> Result { - gpu_linear_nt_cached_bf16_f32acc( - input, - CACHE_NAMESPACE, - &[GpuLinearPart { - bt_ggml_type: GGML_TYPE_BF16, - n: self.out, - cache_key: &self.key, - bytes: &self.bytes, - }], - &self.bias, - ) - .map_err(DiffusionError::model) + let part = GpuLinearPart { + bt_ggml_type: GGML_TYPE_BF16, + n: self.out, + cache_key: &self.key, + bytes: &self.bytes, + }; + let fast = if self.bias.is_empty() { + gpu_linear_nt_cached_bf16_mm(input, CACHE_NAMESPACE, &[part]) + } else { + gpu_linear_nt_cached_bf16_bias_epilogue(input, CACHE_NAMESPACE, &[part], &self.bias) + }; + match fast { + Ok(out) => Ok(out), + Err(_) => gpu_linear_nt_cached_bf16_f32acc( + input, + CACHE_NAMESPACE, + &[GpuLinearPart { + bt_ggml_type: GGML_TYPE_BF16, + n: self.out, + cache_key: &self.key, + bytes: &self.bytes, + }], + &self.bias, + ) + .map_err(DiffusionError::model), + } } } diff --git a/libs/ai/models/body/src/model.rs b/libs/ai/models/body/src/model.rs index f99cd4862..c46f51219 100644 --- a/libs/ai/models/body/src/model.rs +++ b/libs/ai/models/body/src/model.rs @@ -36,6 +36,10 @@ pub struct BodyModel { /// The crop side the backbone sees; 512 is the trained size, smaller is /// faster and less accurate (see `set_crop_size`). crop_size: usize, + /// Pose correctives on every refinement step (the reference) or only + /// on the last one: the intermediate steps only feed keypoints back into + /// the decoder, where the corrective's few millimetres barely register. + pub correctives_every_step: bool, /// Per-stage wall times of the last `infer`, milliseconds: /// crop, backbone, context, decoder loop (incl. rig), packet. pub last_stage_ms: [f32; 5], @@ -82,6 +86,7 @@ impl BodyModel { decoder, rig, crop_size: IMAGE_SIZE, + correctives_every_step: false, last_stage_ms: [0.0; 5], last_loop: LoopTiming::default(), }; @@ -143,11 +148,13 @@ impl BodyModel { let tokens = self.decoder.build_tokens(condition_info(&geo)); let rig = &self.rig; let dense_pe = &self.dense_pe[&self.crop_size]; + let every_step = self.correctives_every_step; let mut last: Option = None; let output = self .decoder .run(tokens, &context, dense_pe, |step: StepInput| { - let result = close_the_loop(rig, &geo, &step); + let correctives = every_step || step.layer + 1 == crate::DEC_DEPTH; + let result = close_the_loop(rig, &geo, &step, correctives); let feedback = StepFeedback { kp2d_cropped: full_to_crop(&result.kp2d, &geo), depth: depths(&result.kp3d, result.cam_t), @@ -190,10 +197,10 @@ impl BodyModel { /// One refinement step's tail: head output -> rig parameters -> posed rig /// -> keypoints in camera axes -> camera translation -> projection. -fn close_the_loop(rig: &MhrRig, geo: &CropGeometry, step: &StepInput) -> StepResult { +fn close_the_loop(rig: &MhrRig, geo: &CropGeometry, step: &StepInput, correctives: bool) -> StepResult { let pose = unpack_pose(&step.pose_pred_519); let params = model_params(rig, &pose); - let rigged = rig.forward(&pose.shape, ¶ms, &pose.expr, true); + let rigged = rig.forward(&pose.shape, ¶ms, &pose.expr, correctives); // Rig output is centimetres in the rig's axes; the camera frame is // metres with y and z flipped. let to_camera = |values: &[f32], count: usize| -> Vec { @@ -266,6 +273,8 @@ mod tests { let load_started = Instant::now(); let mut model = BodyModel::load(&weights_path).expect("load body model"); eprintln!("body model load {:?}", load_started.elapsed()); + // The exact mode first (correctives on every step, as the reference). + model.correctives_every_step = true; let packet = model.infer(&rgb, w, h, None).expect("infer"); // A second run reports the warm timings. let packet = model.infer(&rgb, w, h, None).unwrap_or(packet); @@ -282,6 +291,16 @@ mod tests { model.last_loop.step_ms, model.last_loop.refine_ms ); + // Correctives only on the final step: the cheaper loop, measured. + model.correctives_every_step = false; + let _ = model.infer(&rgb, w, h, None).expect("infer"); + let lean = model.infer(&rgb, w, h, None).expect("infer"); + let (lean3, _) = max_abs(&lean.people[0].kp3d, &fixture::load("final_pred_keypoints_3d").unwrap().1); + eprintln!( + "body correctives on the last step only: warm {:.1} ms (loop {:.1}); kp3d max {lean3:.4} m vs reference", + lean.ms, model.last_stage_ms[3] + ); + assert!(lean3 < 5.0e-3, "lean rig mode drifted: {lean3} m"); // The same image through smaller crops: the speed/accuracy knob, // reported against the reference at 512 (not asserted tightly: these // sizes were never trained). From a9ce596e07b3897f4a0b6c3e01603aa27d8727b3 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 23:52:13 +0200 Subject: [PATCH 032/417] ai-body: the crop warp runs across cores Co-Authored-By: Claude Fable 5.1 --- libs/ai/models/body/src/preprocess.rs | 41 ++++++++++++++++++++------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/libs/ai/models/body/src/preprocess.rs b/libs/ai/models/body/src/preprocess.rs index c1a3ea70d..9ee5ef58a 100644 --- a/libs/ai/models/body/src/preprocess.rs +++ b/libs/ai/models/body/src/preprocess.rs @@ -102,17 +102,38 @@ pub fn crop_normalized( let mut output = vec![0.0; 3 * crop * crop]; let k = geo.affine[0]; let plane = crop * crop; - for v in 0..crop { - let src_y = (v as f32 - geo.affine[5]) / k; - for u in 0..crop { - let src_x = (u as f32 - geo.affine[2]) / k; - for c in 0..3 { - let pixel = bilinear_zero_border(rgb, w, h, src_x, src_y, c) / 255.0; - output[c * plane + v * crop + u] = - (pixel - IMAGENET_MEAN[c]) / IMAGENET_STD[c]; - } + // Row bands across the machine's cores: the warp is 0.8M samples of + // scalar bilinear work, 3 ms on one core. + let threads = std::thread::available_parallelism().map(|n| n.get()).unwrap_or(1).clamp(1, 16); + let band = crop.div_ceil(threads); + let (r, g, b) = { + let (r, rest) = output.split_at_mut(plane); + let (g, b) = rest.split_at_mut(plane); + (r, g, b) + }; + std::thread::scope(|scope| { + for (((r_band, g_band), b_band), band_index) in r + .chunks_mut(band * crop) + .zip(g.chunks_mut(band * crop)) + .zip(b.chunks_mut(band * crop)) + .zip(0..) + { + scope.spawn(move || { + let planes = [r_band, g_band, b_band]; + let v0 = band_index * band; + for (row, v) in (v0..).enumerate().take(planes[0].len() / crop) { + let src_y = (v as f32 - geo.affine[5]) / k; + for u in 0..crop { + let src_x = (u as f32 - geo.affine[2]) / k; + for c in 0..3 { + let pixel = bilinear_zero_border(rgb, w, h, src_x, src_y, c) / 255.0; + planes[c][row * crop + u] = (pixel - IMAGENET_MEAN[c]) / IMAGENET_STD[c]; + } + } + } + }); } - } + }); output } From 8964ba631306ca917d881f92a7747e0b0a40312c Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 1 Sep 2026 23:54:43 +0200 Subject: [PATCH 033/417] ai-body: an FP8 backbone mode, off by default, measured against the oracle BodyModel::set_backbone_fp8 quantises every backbone weight to E4M3 with a per-tensor absmax scale and runs the tensor-core FP8 GEMM (bias broadcast after). A backend without FP8 turns it off per layer on the first refusal, so Metal keeps bf16. The oracle test reports its accuracy and timing next to bf16; the default stays bf16 until the numbers say otherwise. Co-Authored-By: Claude Fable 5.1 --- libs/ai/models/body/Cargo.toml | 2 + libs/ai/models/body/src/dino.rs | 87 +++++++++++++++++++++++++++++++- libs/ai/models/body/src/model.rs | 17 +++++++ 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/libs/ai/models/body/Cargo.toml b/libs/ai/models/body/Cargo.toml index cb00b1c3a..fc6f9a5f7 100644 --- a/libs/ai/models/body/Cargo.toml +++ b/libs/ai/models/body/Cargo.toml @@ -8,3 +8,5 @@ license = "MIT" [dependencies] makepad-ai-common = { path = "../common" } makepad-ai-loader = { path = "../../loader" } +# Only for its FP8 E4M3 encoder (the optional FP8 backbone mode). +makepad-ai-flux = { path = "../flux" } diff --git a/libs/ai/models/body/src/dino.rs b/libs/ai/models/body/src/dino.rs index 1f0881e25..de0c35668 100644 --- a/libs/ai/models/body/src/dino.rs +++ b/libs/ai/models/body/src/dino.rs @@ -7,7 +7,8 @@ use crate::backend::{ gpu_add, gpu_attention_packed_cross, gpu_attention_packed_flash2_d64, gpu_concat_rows_many, gpu_download, gpu_layer_norm_mul_add, gpu_linear_nt_cached_bf16_bias_epilogue, - gpu_linear_nt_cached_bf16_f32acc, gpu_linear_nt_cached_bf16_mm, gpu_mul, gpu_rope_half, + gpu_linear_nt_cached_bf16_f32acc, gpu_linear_nt_cached_bf16_mm, gpu_linear_nt_cached_f8_mm, + gpu_mul, gpu_rope_half, gpu_silu, gpu_slice_rows, gpu_upload, GpuLinearPart, GpuTensor, }; use crate::weights::BodyWeights; @@ -16,7 +17,7 @@ use crate::{ DINO_HEADS, DINO_HEAD_DIM, DINO_NORM_EPS, DINO_PREFIX_TOKENS, DINO_ROPE_BASE, PATCH, ROPE_HALF, }; -use makepad_ai_common::quant::GGML_TYPE_BF16; +use makepad_ai_common::quant::{GGML_TYPE_BF16, GGML_TYPE_F8_E4M3}; use makepad_ai_loader::MlxDType; const PATCH_DIM: usize = 3 * PATCH * PATCH; @@ -27,6 +28,25 @@ struct Bf16Linear { key: String, out: usize, bias: Vec, + /// The same weight as FP8 E4M3 with one per-tensor scale, when the + /// FP8 mode is on; `None` after a backend refused it. + f8: std::cell::RefCell, f32)>>, +} + +/// Quantise a bf16-packed weight to E4M3 with a per-tensor absmax scale +/// (`w = scale * q`, q saturating at 448). +fn quantize_f8(bf16_bytes: &[u8]) -> (Vec, f32) { + let values: Vec = bf16_bytes + .chunks_exact(2) + .map(|c| f32::from_bits(u32::from(u16::from_le_bytes([c[0], c[1]])) << 16)) + .collect(); + let absmax = values.iter().fold(0.0f32, |m, v| m.max(v.abs())); + let scale = if absmax > 0.0 { absmax / 448.0 } else { 1.0 }; + let bytes = values + .iter() + .map(|v| makepad_ai_flux::flux_lora::f32_to_f8_e4m3(v / scale)) + .collect(); + (bytes, scale) } impl Bf16Linear { @@ -48,6 +68,7 @@ impl Bf16Linear { key: name.to_string(), out, bias, + f8: std::cell::RefCell::new(None), }) } @@ -72,6 +93,7 @@ impl Bf16Linear { key: format!("{name}.layerscale_folded"), out, bias, + f8: std::cell::RefCell::new(None), }) } @@ -86,6 +108,7 @@ impl Bf16Linear { key: name.to_string(), out: DINO_DIM, bias: weights.f32_shaped(&format!("{name}.bias"), &[DINO_DIM])?, + f8: std::cell::RefCell::new(None), }) } @@ -95,6 +118,39 @@ impl Bf16Linear { /// accumulation; the fast paths round the output to bf16, which is the /// reference's own precision. fn forward(&self, input: &GpuTensor) -> Result { + // FP8 first when quantised: the bias rides a broadcast add after + // the bias-free f8 mm. A backend without FP8 turns the mode off for + // this layer on its first refusal. + let f8_result = { + let f8 = self.f8.borrow(); + f8.as_ref().map(|(bytes, scale)| { + gpu_linear_nt_cached_f8_mm( + input, + CACHE_NAMESPACE, + &[GpuLinearPart { + bt_ggml_type: GGML_TYPE_F8_E4M3, + n: self.out, + cache_key: &format!("{}.f8", self.key), + bytes, + }], + *scale, + None, + ) + }) + }; + match f8_result { + Some(Ok(out)) => { + if self.bias.is_empty() { + return Ok(out); + } + let bias = gpu_upload(&self.bias, 1, self.out).map_err(DiffusionError::model)?; + return gpu_add_rows_broadcast_cols(&out, &bias); + } + Some(Err(_)) => { + *self.f8.borrow_mut() = None; + } + None => {} + } let part = GpuLinearPart { bt_ggml_type: GGML_TYPE_BF16, n: self.out, @@ -146,6 +202,21 @@ pub struct BodyDino { final_norm_b: Vec, } +/// Bias add broadcast over rows: `out[r] = x[r] + bias`. The stack's +/// `gpu_add` wants equal shapes, so the bias is tiled to the row count +/// once per call (a 1280-wide vector; cheap next to the GEMM it follows). +fn gpu_add_rows_broadcast_cols(x: &GpuTensor, bias: &GpuTensor) -> Result { + let cols = x.cols(); + let rows = x.rows(); + let bias_host = gpu_download(bias).map_err(DiffusionError::model)?; + let mut tiled = Vec::with_capacity(rows * cols); + for _ in 0..rows { + tiled.extend_from_slice(&bias_host[..cols]); + } + let tiled = gpu_upload(&tiled, rows, cols).map_err(DiffusionError::model)?; + gpu_add(x, &tiled).map_err(DiffusionError::model) +} + fn bf16_bytes_shaped( weights: &BodyWeights, name: &str, @@ -337,6 +408,18 @@ impl BodyDino { /// `pixels` is a normalised CHW crop of any square side that is a /// multiple of the patch (512 is the trained size); the output has /// `(side / 16)^2` rows. + /// Quantise every backbone weight to FP8 E4M3 (per-tensor scale) for the + /// tensor-core FP8 GEMM; `false` restores bf16. Backends without FP8 fall + /// back layer by layer. + pub fn set_fp8(&self, on: bool) { + let all = std::iter::once(&self.patch).chain(self.layers.iter().flat_map(|l| { + [&l.q, &l.k, &l.v, &l.out, &l.gate, &l.up, &l.down] + })); + for linear in all { + *linear.f8.borrow_mut() = if on { Some(quantize_f8(&linear.bytes)) } else { None }; + } + } + pub fn forward_normalized(&self, pixels: &[f32]) -> Result { let size = crop_side(pixels.len())?; let side = size / PATCH; diff --git a/libs/ai/models/body/src/model.rs b/libs/ai/models/body/src/model.rs index c46f51219..037b63c94 100644 --- a/libs/ai/models/body/src/model.rs +++ b/libs/ai/models/body/src/model.rs @@ -114,6 +114,12 @@ impl BodyModel { self.crop_size } + /// FP8 backbone (E4M3 weights, tensor-core FP8 GEMM): about half the + /// backbone time on Ada, at a measured accuracy cost (see the oracle test). + pub fn set_backbone_fp8(&self, on: bool) { + self.dino.set_fp8(on); + } + /// `rgb` is `width * height * 3` bytes; `bbox` is the person box in /// full-image pixels (xyxy), the whole image when `None`. pub fn infer( @@ -301,6 +307,17 @@ mod tests { lean.ms, model.last_stage_ms[3] ); assert!(lean3 < 5.0e-3, "lean rig mode drifted: {lean3} m"); + // FP8 backbone: the tensor-core lever, measured. + model.set_backbone_fp8(true); + let _ = model.infer(&rgb, w, h, None).expect("infer fp8"); + let fp8 = model.infer(&rgb, w, h, None).expect("infer fp8"); + let (fp8_3, _) = max_abs(&fp8.people[0].kp3d, &fixture::load("final_pred_keypoints_3d").unwrap().1); + let (fp8_2, _) = max_abs(&fp8.people[0].kp2d, &fixture::load("final_pred_keypoints_2d").unwrap().1); + eprintln!( + "body fp8 backbone: warm {:.1} ms (backbone {:.1}, loop {:.1}); kp3d max {fp8_3:.4} m, kp2d max {fp8_2:.2} px vs reference", + fp8.ms, model.last_stage_ms[1], model.last_stage_ms[3] + ); + model.set_backbone_fp8(false); // The same image through smaller crops: the speed/accuracy knob, // reported against the reference at 512 (not asserted tightly: these // sizes were never trained). From a2aaa8f778be8eb7557931a53fc85d74b66c8e9e Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 00:05:03 +0200 Subject: [PATCH 034/417] ai-body: the FP8 bias rides a column-broadcast add on the device The FP8 backbone mode added each linear's bias by downloading, tiling and re-uploading it per call, which cost more than the FP8 GEMM saved. A gpu_add_cols_broadcast op (CUDA kernel; host loop on the Metal tensor backend) adds a cols-wide bias to every row on the device, and each linear keeps its bias resident after the first upload. Co-Authored-By: Claude Fable 5.1 --- libs/ai/cuda/kernels/diffusion_ops.cu | 33 ++++++++++++++++++++++++ libs/ai/cuda/src/launch.rs | 36 +++++++++++++++++++++++++++ libs/ai/metal/src/gpu_tensor.rs | 18 ++++++++++++++ libs/ai/models/body/src/dino.rs | 28 ++++++++++----------- libs/ai/models/common/src/backend.rs | 2 +- libs/ai/models/common/src/gpu.rs | 11 ++++++++ 6 files changed, 112 insertions(+), 16 deletions(-) diff --git a/libs/ai/cuda/kernels/diffusion_ops.cu b/libs/ai/cuda/kernels/diffusion_ops.cu index 0cfe1f478..27ac07870 100644 --- a/libs/ai/cuda/kernels/diffusion_ops.cu +++ b/libs/ai/cuda/kernels/diffusion_ops.cu @@ -3753,6 +3753,39 @@ extern "C" cudaError_t makepad_cuda_group_norm_planar_multi_f32( // the rest pass through. cos/sin tables are [token][rot_half]; both rotated // halves share the same table entry (the reference duplicates the frequency // block, so cos[i + rot_half] == cos[i]). +// out[r, c] = x[r, c] + bias[c]: a per-column broadcast add (a linear's +// bias after a GEMM that has no bias epilogue). +static __global__ void makepad_cuda_add_cols_broadcast_f32_kernel( + const float * __restrict__ x, + const float * __restrict__ bias, + float * __restrict__ out, + uint32_t rows, + uint32_t cols) { + const size_t i = static_cast(blockIdx.x) * blockDim.x + threadIdx.x; + const size_t total = static_cast(rows) * cols; + if (i >= total) { + return; + } + out[i] = x[i] + bias[i % cols]; +} + +extern "C" cudaError_t makepad_cuda_add_cols_broadcast_f32( + const float * x, + const float * bias, + float * out, + uint32_t rows, + uint32_t cols, + cudaStream_t stream) { + const size_t total = static_cast(rows) * cols; + if (total == 0) { + return cudaSuccess; + } + const uint32_t block = 256; + const uint32_t grid = static_cast((total + block - 1) / block); + makepad_cuda_add_cols_broadcast_f32_kernel<<>>(x, bias, out, rows, cols); + return cudaGetLastError(); +} + static __global__ void makepad_cuda_rope_half_f32_kernel( const float * __restrict__ input, const float * __restrict__ cos_table, diff --git a/libs/ai/cuda/src/launch.rs b/libs/ai/cuda/src/launch.rs index 029109149..25400a767 100644 --- a/libs/ai/cuda/src/launch.rs +++ b/libs/ai/cuda/src/launch.rs @@ -1388,6 +1388,15 @@ mod imp { stream: cudaStream_t, ) -> cudaError_t; + fn makepad_cuda_add_cols_broadcast_f32( + x: *const f32, + bias: *const f32, + out: *mut f32, + rows: u32, + cols: u32, + stream: cudaStream_t, + ) -> cudaError_t; + fn makepad_cuda_rope_half_bf16_f32( input: *const f32, cos_table: *const f32, @@ -11393,6 +11402,33 @@ mod imp { }) } + /// `out[r] = x[r] + bias` for an f32 `[rows, cols]` tensor and a + /// `cols`-wide bias (a linear's bias after a bias-free GEMM). + pub fn gpu_add_cols_broadcast(x: &GpuTensor, bias: &GpuTensor) -> Result { + if x.half || bias.half || bias.rows * bias.cols != x.cols { + return Err(format!( + "gpu_add_cols_broadcast shape mismatch {}x{} half={} vs bias {}x{} half={}", + x.rows, x.cols, x.half, bias.rows, bias.cols, bias.half + )); + } + with_dense_linear_backend(|backend| { + backend.prepare_device()?; + let out = GpuTensor::from_pool(x.rows, x.cols)?; + let status = unsafe { + makepad_cuda_add_cols_broadcast_f32( + x.device_ptr()?, + bias.device_ptr()?, + out.device_ptr()?, + x.rows as u32, + x.cols as u32, + backend.stream, + ) + }; + gpu_check(status)?; + Ok(out) + }) + } + pub fn gpu_add(a: &GpuTensor, b: &GpuTensor) -> Result { if a.rows != b.rows || a.cols != b.cols || a.half != b.half { return Err(format!( diff --git a/libs/ai/metal/src/gpu_tensor.rs b/libs/ai/metal/src/gpu_tensor.rs index 322bc3f3b..d7d8e5562 100644 --- a/libs/ai/metal/src/gpu_tensor.rs +++ b/libs/ai/metal/src/gpu_tensor.rs @@ -181,6 +181,24 @@ pub fn add(a: &GpuTensor, b: &GpuTensor) -> Result { Ok(tensor(a.rows, a.cols, out)) } +/// `out[r] = a[r] + bias` with a `cols`-wide bias broadcast over rows. +pub fn add_cols_broadcast(a: &GpuTensor, bias: &GpuTensor) -> Result { + if bias.rows * bias.cols != a.cols { + return Err(format!( + "metal add_cols_broadcast bias width {} != {} cols", + bias.rows * bias.cols, + a.cols + )); + } + let ad = data(a)?; + let bd = data(bias)?; + let mut out = Vec::with_capacity(ad.len()); + for row in ad.chunks_exact(a.cols) { + out.extend(row.iter().zip(bd.iter()).map(|(x, b)| x + b)); + } + Ok(tensor(a.rows, a.cols, out)) +} + pub fn mul(a: &GpuTensor, b: &GpuTensor) -> Result { let ad = data(a)?; let bd = data(b)?; diff --git a/libs/ai/models/body/src/dino.rs b/libs/ai/models/body/src/dino.rs index de0c35668..663489a12 100644 --- a/libs/ai/models/body/src/dino.rs +++ b/libs/ai/models/body/src/dino.rs @@ -8,7 +8,7 @@ use crate::backend::{ gpu_add, gpu_attention_packed_cross, gpu_attention_packed_flash2_d64, gpu_concat_rows_many, gpu_download, gpu_layer_norm_mul_add, gpu_linear_nt_cached_bf16_bias_epilogue, gpu_linear_nt_cached_bf16_f32acc, gpu_linear_nt_cached_bf16_mm, gpu_linear_nt_cached_f8_mm, - gpu_mul, gpu_rope_half, + gpu_add_cols_broadcast, gpu_mul, gpu_rope_half, gpu_silu, gpu_slice_rows, gpu_upload, GpuLinearPart, GpuTensor, }; use crate::weights::BodyWeights; @@ -31,6 +31,8 @@ struct Bf16Linear { /// The same weight as FP8 E4M3 with one per-tensor scale, when the /// FP8 mode is on; `None` after a backend refused it. f8: std::cell::RefCell, f32)>>, + /// The bias resident on the device for the FP8 path (uploaded once). + bias_gpu: std::cell::RefCell>, } /// Quantise a bf16-packed weight to E4M3 with a per-tensor absmax scale @@ -69,6 +71,7 @@ impl Bf16Linear { out, bias, f8: std::cell::RefCell::new(None), + bias_gpu: std::cell::RefCell::new(None), }) } @@ -94,6 +97,7 @@ impl Bf16Linear { out, bias, f8: std::cell::RefCell::new(None), + bias_gpu: std::cell::RefCell::new(None), }) } @@ -109,6 +113,7 @@ impl Bf16Linear { out: DINO_DIM, bias: weights.f32_shaped(&format!("{name}.bias"), &[DINO_DIM])?, f8: std::cell::RefCell::new(None), + bias_gpu: std::cell::RefCell::new(None), }) } @@ -143,8 +148,11 @@ impl Bf16Linear { if self.bias.is_empty() { return Ok(out); } - let bias = gpu_upload(&self.bias, 1, self.out).map_err(DiffusionError::model)?; - return gpu_add_rows_broadcast_cols(&out, &bias); + let mut slot = self.bias_gpu.borrow_mut(); + if slot.is_none() { + *slot = Some(gpu_upload(&self.bias, 1, self.out).map_err(DiffusionError::model)?); + } + return gpu_add_rows_broadcast_cols(&out, slot.as_ref().unwrap()); } Some(Err(_)) => { *self.f8.borrow_mut() = None; @@ -202,19 +210,9 @@ pub struct BodyDino { final_norm_b: Vec, } -/// Bias add broadcast over rows: `out[r] = x[r] + bias`. The stack's -/// `gpu_add` wants equal shapes, so the bias is tiled to the row count -/// once per call (a 1280-wide vector; cheap next to the GEMM it follows). +/// Bias add broadcast over rows: `out[r] = x[r] + bias`. fn gpu_add_rows_broadcast_cols(x: &GpuTensor, bias: &GpuTensor) -> Result { - let cols = x.cols(); - let rows = x.rows(); - let bias_host = gpu_download(bias).map_err(DiffusionError::model)?; - let mut tiled = Vec::with_capacity(rows * cols); - for _ in 0..rows { - tiled.extend_from_slice(&bias_host[..cols]); - } - let tiled = gpu_upload(&tiled, rows, cols).map_err(DiffusionError::model)?; - gpu_add(x, &tiled).map_err(DiffusionError::model) + gpu_add_cols_broadcast(x, bias).map_err(DiffusionError::model) } fn bf16_bytes_shaped( diff --git a/libs/ai/models/common/src/backend.rs b/libs/ai/models/common/src/backend.rs index cdceca0a3..8ba8d0eae 100644 --- a/libs/ai/models/common/src/backend.rs +++ b/libs/ai/models/common/src/backend.rs @@ -27,7 +27,7 @@ pub use metal::{ /// Activations stay on the GPU across a whole transformer step — see the /// flux device path in flux_transformer.rs. pub use crate::gpu::{ - gpu_act_f16_enabled, gpu_add, gpu_add_bf16, gpu_alias_snake_updown2x, + gpu_act_f16_enabled, gpu_add, gpu_add_bf16, gpu_add_cols_broadcast, gpu_alias_snake_updown2x, gpu_attention_cross_fused_enabled, gpu_attention_gqa_decode_bf16, gpu_attention_gqa_decode_pair_bf16, gpu_attention_packed, gpu_attention_packed_bf16, diff --git a/libs/ai/models/common/src/gpu.rs b/libs/ai/models/common/src/gpu.rs index 99c9b10ab..5138ac26b 100644 --- a/libs/ai/models/common/src/gpu.rs +++ b/libs/ai/models/common/src/gpu.rs @@ -3224,6 +3224,17 @@ mod imp { } } + pub fn gpu_add_cols_broadcast(_x: &GpuTensor, _bias: &GpuTensor) -> Result { + #[cfg(target_os = "macos")] + { + return makepad_ai_metal::gpu_tensor::add_cols_broadcast(_x, _bias); + } + #[cfg(not(target_os = "macos"))] + { + Err(GPU_UNAVAILABLE.to_string()) + } + } + pub fn gpu_add(_a: &GpuTensor, _b: &GpuTensor) -> Result { #[cfg(target_os = "macos")] { From d53c77d4a5380add9b609ba9e13ad44297526ea2 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 00:16:31 +0200 Subject: [PATCH 035/417] metal: a device-resident ViT stack, and the body backbone rides it The Metal tensor backend is host-Vec based: every op copied its inputs up and its result back, which put the DINOv3 backbone at 2.1 s a frame on an M3 Max. try_vit_backbone_resident_f32 runs a whole pre-norm ViT stack (LayerNorm, q/k/v, rotate-half rope from tables, flash attention, out, LayerNorm, SwiGLU, down; residuals in place) inside one command buffer against cached bf16 weights, with a new kernel_makepad_rope_half_tables_f32 kernel for the rope. The precompiled metallib now carries the bf16 GEMM kernels the runtime source compile already enabled on bfloat devices. The common backend exposes it as gpu_vit_backbone_resident (CUDA declines; its per-op path is already resident) and the body backbone tries it first: 233 ms a frame on the M3 Max, same oracle parity (kp3d 1.5 mm). Co-Authored-By: Claude Fable 5.1 --- libs/ai/metal/build.rs | 4 + libs/ai/metal/shaders/ggml/ggml-metal.metal | 45 +++ libs/ai/metal/src/gpu_tensor.rs | 38 +- libs/ai/metal/src/shim.rs | 404 ++++++++++++++++++++ libs/ai/models/body/src/dino.rs | 59 ++- libs/ai/models/common/src/backend.rs | 1 + libs/ai/models/common/src/gpu.rs | 106 +++++ 7 files changed, 655 insertions(+), 2 deletions(-) diff --git a/libs/ai/metal/build.rs b/libs/ai/metal/build.rs index dab224ee3..7cc54cf1a 100644 --- a/libs/ai/metal/build.rs +++ b/libs/ai/metal/build.rs @@ -124,6 +124,10 @@ fn build_metallib() { "metal", "-O3", "-fno-fast-math", + // The runtime source compile defines this on bfloat-capable + // devices; the precompiled library must carry the same kernels + // (the shader drops the define itself below Metal 3.1). + "-DGGML_METAL_HAS_BF16=1", "-c", &metal_src, "-I", diff --git a/libs/ai/metal/shaders/ggml/ggml-metal.metal b/libs/ai/metal/shaders/ggml/ggml-metal.metal index c03cb75f8..0ab29fed6 100644 --- a/libs/ai/metal/shaders/ggml/ggml-metal.metal +++ b/libs/ai/metal/shaders/ggml/ggml-metal.metal @@ -13817,3 +13817,48 @@ kernel void kernel_mlx_affine_qmm_f32( } } +// --------------------------------------------------------------------------- +// makepad additions +// --------------------------------------------------------------------------- + +// Rotate-half rotary embedding from precomputed per-token tables (the CUDA +// `makepad_cuda_rope_half_f32` contract): for every (token, head), +// (x1, x2) = (x[i], x[i + rot_half]) -> (x1*c - x2*s, x2*c + x1*s) with +// c/s = table[token, i]; dims past 2*rot_half copy through. dst may alias x. +typedef struct { + int32_t token_count; + int32_t head_count; + int32_t head_dim; + int32_t rot_half; +} makepad_kargs_rope_half_tables; + +kernel void kernel_makepad_rope_half_tables_f32( + constant makepad_kargs_rope_half_tables & args, + device const float * x, + device const float * cos_table, + device const float * sin_table, + device float * dst, + uint3 tgpig[[threadgroup_position_in_grid]], + uint3 tpitg[[thread_position_in_threadgroup]], + uint3 ntg3[[threads_per_threadgroup]]) { + const int token = (int) tgpig.x; + const int head = (int) tgpig.y; + const uint tid = tpitg.x; + const uint ntg = ntg3.x; + if (token >= args.token_count || head >= args.head_count) { + return; + } + const ulong base = ((ulong) token * (ulong) args.head_count + (ulong) head) * (ulong) args.head_dim; + const ulong table_base = (ulong) token * (ulong) args.rot_half; + for (int i = (int) tid; i < args.rot_half; i += (int) ntg) { + const float c = cos_table[table_base + i]; + const float s = sin_table[table_base + i]; + const float x1 = x[base + i]; + const float x2 = x[base + args.rot_half + i]; + dst[base + i] = x1 * c - x2 * s; + dst[base + args.rot_half + i] = x2 * c + x1 * s; + } + for (int i = 2 * args.rot_half + (int) tid; i < args.head_dim; i += (int) ntg) { + dst[base + i] = x[base + i]; + } +} diff --git a/libs/ai/metal/src/gpu_tensor.rs b/libs/ai/metal/src/gpu_tensor.rs index d7d8e5562..764637153 100644 --- a/libs/ai/metal/src/gpu_tensor.rs +++ b/libs/ai/metal/src/gpu_tensor.rs @@ -4,10 +4,11 @@ //! goal is a working Metal path we can then keep cutting copies. use crate::gpu_types::{GpuLinearPart, GpuTensor}; +pub use crate::shim::{VitLayerRef, VitLinearRef}; use crate::shim::{ try_add_f32, try_conv2d_planar_f32, try_flash_attn_f32_packed, try_gelu_f32, try_group_norm_planar_f32, try_layer_norm_mul_add_f32, try_matmul_nt_f32, try_mul_f32, - try_silu_f32, + try_silu_f32, try_vit_backbone_resident_f32, }; use std::cell::RefCell; use std::collections::HashMap; @@ -746,6 +747,41 @@ pub fn rope_half( /// Per-row layer norm with an affine: `(x - mean) / sqrt(var + eps) * mul + add` /// (biased variance), `mul`/`add` one value per column. +/// A whole pre-norm ViT stack device-resident (see `shim::VitLayerRef`): +/// `x` `[seq, dim]` goes up once, every layer encodes into one command +/// buffer, and the final layer-normed activations come back. +#[allow(clippy::too_many_arguments)] +pub fn vit_backbone_resident( + x: &GpuTensor, + n_head: usize, + rot_half: usize, + cos: &GpuTensor, + sin: &GpuTensor, + layers: &[VitLayerRef<'_>], + final_norm_w: &[f32], + final_norm_b: &[f32], + eps: f32, +) -> Result { + let xd = data(x)?; + let cd = data(cos)?; + let sd = data(sin)?; + let out = try_vit_backbone_resident_f32( + &xd, + x.rows, + x.cols, + n_head, + rot_half, + &cd, + &sd, + layers, + final_norm_w, + final_norm_b, + eps, + ) + .ok_or_else(|| "metal resident vit backbone failed".to_string())?; + Ok(tensor(x.rows, x.cols, out)) +} + pub fn layer_norm_mul_add( x: &GpuTensor, mul: &[f32], diff --git a/libs/ai/metal/src/shim.rs b/libs/ai/metal/src/shim.rs index df9655292..94f6978b5 100644 --- a/libs/ai/metal/src/shim.rs +++ b/libs/ai/metal/src/shim.rs @@ -345,6 +345,58 @@ pub fn clear_decoder_kv_cache() { } #[allow(clippy::too_many_arguments)] +/// One linear of a device-resident ViT layer: a row-major `[n, k]` weight in +/// a ggml dtype, its output width and its bias (empty for none). +#[derive(Clone, Copy)] +pub struct VitLinearRef<'a> { + pub w_bytes: &'a [u8], + pub w_ggml_type: u32, + pub n: usize, + pub bias: &'a [f32], +} + +/// One pre-norm ViT layer with rotary attention and a SwiGLU feed-forward +/// (the DINOv3 block): `x += out(attn(rope(q(n1)), rope(k(n1)), v(n1)))`, +/// then `x += down(silu(gate(n2)) * up(n2))`, both norms LayerNorm with an +/// affine. Layer scales are expected folded into `out` and `down`. +#[derive(Clone, Copy)] +pub struct VitLayerRef<'a> { + pub norm1_w: &'a [f32], + pub norm1_b: &'a [f32], + pub q: VitLinearRef<'a>, + pub k: VitLinearRef<'a>, + pub v: VitLinearRef<'a>, + pub out: VitLinearRef<'a>, + pub norm2_w: &'a [f32], + pub norm2_b: &'a [f32], + pub gate: VitLinearRef<'a>, + pub up: VitLinearRef<'a>, + pub down: VitLinearRef<'a>, +} + +/// Runs a whole ViT stack device-resident: `x` (`[seq_len, n_state]`) goes +/// up once, every layer encodes into one command buffer against cached +/// weights, and only the final normalised activations come back. +/// `cos`/`sin` are `[seq_len, rot_half]` rotate-half tables. +#[allow(clippy::too_many_arguments)] +pub fn try_vit_backbone_resident_f32( + x: &[f32], + seq_len: usize, + n_state: usize, + n_head: usize, + rot_half: usize, + cos: &[f32], + sin: &[f32], + layers: &[VitLayerRef<'_>], + final_norm_w: &[f32], + final_norm_b: &[f32], + eps: f32, +) -> Option> { + imp::try_vit_backbone_resident_f32( + x, seq_len, n_state, n_head, rot_half, cos, sin, layers, final_norm_w, final_norm_b, eps, + ) +} + pub fn try_flash_attn_f32_self_kv_cache( layer: usize, q: &[f32], @@ -1042,6 +1094,23 @@ mod imp { pub(super) fn clear_decoder_kv_cache() {} #[allow(clippy::too_many_arguments)] + #[allow(clippy::too_many_arguments)] + pub(super) fn try_vit_backbone_resident_f32( + _x: &[f32], + _seq_len: usize, + _n_state: usize, + _n_head: usize, + _rot_half: usize, + _cos: &[f32], + _sin: &[f32], + _layers: &[super::VitLayerRef<'_>], + _final_norm_w: &[f32], + _final_norm_b: &[f32], + _eps: f32, + ) -> Option> { + None + } + pub(super) fn try_flash_attn_f32_self_kv_cache( _layer: usize, _q: &[f32], @@ -1596,6 +1665,23 @@ mod imp { pub(super) fn clear_decoder_kv_cache() {} + #[allow(clippy::too_many_arguments)] + pub(super) fn try_vit_backbone_resident_f32( + _x: &[f32], + _seq_len: usize, + _n_state: usize, + _n_head: usize, + _rot_half: usize, + _cos: &[f32], + _sin: &[f32], + _layers: &[super::VitLayerRef<'_>], + _final_norm_w: &[f32], + _final_norm_b: &[f32], + _eps: f32, + ) -> Option> { + None + } + pub(super) fn try_flash_attn_f32_self_kv_cache( _layer: usize, _q: &[f32], @@ -1790,6 +1876,9 @@ mod imp { const OP_FLASH_ATTN_EXT_VEC_NCPSG: i32 = 32; const OP_UNARY_NUM_GELU: i16 = 103; const OP_UNARY_NUM_SILU: i16 = 106; + /// Persistent-scratch tag range `[VIT_TAG_BASE, VIT_TAG_BASE + 20)` of the + /// resident ViT stack (`vit_layer_from_buffer_f32`). + const VIT_TAG_BASE: u8 = 200; const SCRATCH_FLASH_PAD: u8 = 1; const SCRATCH_FLASH_BLK: u8 = 2; const SCRATCH_FLASH_TMP: u8 = 3; @@ -2107,6 +2196,15 @@ mod imp { nrows: i32, } + #[repr(C)] + #[derive(Copy, Clone)] + struct KArgsRopeHalfTables { + token_count: i32, + head_count: i32, + head_dim: i32, + rot_half: i32, + } + #[repr(C)] #[derive(Copy, Clone)] struct KArgsUnary { @@ -4389,6 +4487,290 @@ mod imp { self.end_command_encoder(encoder_handles) } + /// Rotate-half rope from per-token cos/sin tables on a row-major + /// `[token_count, head_count * head_dim]` f32 buffer; `dst_id` may be + /// `x_id` (each thread owns both halves of its pair). + #[allow(clippy::too_many_arguments)] + fn dispatch_rope_half_tables_f32( + &mut self, + x_id: ObjcId, + cos_id: ObjcId, + sin_id: ObjcId, + dst_id: ObjcId, + token_count: usize, + head_count: usize, + head_dim: usize, + rot_half: usize, + ) -> Result<(), String> { + if token_count == 0 || head_count == 0 { + return Ok(()); + } + if rot_half * 2 > head_dim { + return Err(format!( + "rope_half_tables: rot_half {} exceeds half of head_dim {}", + rot_half, head_dim + )); + } + let name = "kernel_makepad_rope_half_tables_f32"; + let (pipeline, _smem, _nr0, _nr1, _nsg) = + self.get_or_compile_cached_pipeline(name.to_string(), name, &[], 0, 0, 0, 0)?; + let args = KArgsRopeHalfTables { + token_count: i32::try_from(token_count) + .map_err(|_| format!("rope token_count too large: {}", token_count))?, + head_count: i32::try_from(head_count) + .map_err(|_| format!("rope head_count too large: {}", head_count))?, + head_dim: i32::try_from(head_dim) + .map_err(|_| format!("rope head_dim too large: {}", head_dim))?, + rot_half: i32::try_from(rot_half) + .map_err(|_| format!("rope rot_half too large: {}", rot_half))?, + }; + let (_command_buffer, encoder, encoder_handles) = self.begin_command_encoder()?; + unsafe { + let _: () = msg_send![encoder, setComputePipelineState: pipeline]; + let _: () = msg_send![ + encoder, + setBytes: &args as *const KArgsRopeHalfTables as *const c_void + length: std::mem::size_of::() as u64 + atIndex: 0u64 + ]; + let _: () = msg_send![encoder, setBuffer: x_id offset: 0u64 atIndex: 1u64]; + let _: () = msg_send![encoder, setBuffer: cos_id offset: 0u64 atIndex: 2u64]; + let _: () = msg_send![encoder, setBuffer: sin_id offset: 0u64 atIndex: 3u64]; + let _: () = msg_send![encoder, setBuffer: dst_id offset: 0u64 atIndex: 4u64]; + let nth_max = Self::pipeline_max_threads(pipeline).max(1u64); + let nth = (rot_half.max(1) as u64).min(nth_max).min(256); + let tgs = MTLSize { + width: token_count as u64, + height: head_count as u64, + depth: 1, + }; + let tpg = MTLSize { + width: nth, + height: 1, + depth: 1, + }; + let _: () = msg_send![ + encoder, + dispatchThreadgroups: tgs + threadsPerThreadgroup: tpg + ]; + } + self.end_command_encoder(encoder_handles) + } + + fn vit_linear_from_buffer( + &mut self, + src_id: ObjcId, + m: usize, + k: usize, + lin: &super::VitLinearRef<'_>, + weight_tag: u8, + bias_tag: u8, + ) -> Result { + let bias = if lin.bias.is_empty() { + None + } else { + Some(lin.bias) + }; + self.linear_from_src_buffer( + src_id, + m, + k, + lin.w_bytes, + lin.w_ggml_type, + lin.n, + bias, + weight_tag, + bias_tag, + ) + } + + /// One resident ViT layer (see `VitLayerRef`), updating `x_id` in + /// place. The seven GEMM outputs use `tag_base + {2,4,6,8,12,14,16}` + /// as their persistent scratch tags; a stack reuses one `tag_base` + /// because layers execute sequentially inside the batch. + #[allow(clippy::too_many_arguments)] + fn vit_layer_from_buffer_f32( + &mut self, + x_id: ObjcId, + seq_len: usize, + n_state: usize, + n_head: usize, + rot_half: usize, + cos_id: ObjcId, + sin_id: ObjcId, + layer: &super::VitLayerRef<'_>, + eps: f32, + tag_base: u8, + ) -> Result<(), String> { + let head_dim = n_state / n_head; + let x_shape = shape4_from_row_major(&[seq_len, n_state], 4)?; + let ln_shape = shape4_from_row_major(&[n_state], 4)?; + let norm_bytes = x_shape + .numel + .checked_mul(std::mem::size_of::()) + .ok_or_else(|| "overflow computing vit norm buffer bytes".to_string())?; + + // Attention: n1 = LN(x); x += out(attn(rope(q), rope(k), v)). + let n1_w = self.get_or_create_cached_f32_buffer(layer.norm1_w, tag_base)?; + let n1_b = self.get_or_create_cached_f32_buffer(layer.norm1_b, tag_base + 1)?; + let norm0_id = self.get_or_create_scratch_buffer(SCRATCH_ENC_NORM0, norm_bytes)?; + self.dispatch_norm_f32( + x_id, n1_w, n1_b, norm0_id, &x_shape, &ln_shape, &ln_shape, eps, 3, + )?; + let q = self.vit_linear_from_buffer( + norm0_id, seq_len, n_state, &layer.q, tag_base + 2, tag_base + 3, + )?; + let k = self.vit_linear_from_buffer( + norm0_id, seq_len, n_state, &layer.k, tag_base + 4, tag_base + 5, + )?; + let v = self.vit_linear_from_buffer( + norm0_id, seq_len, n_state, &layer.v, tag_base + 6, tag_base + 7, + )?; + if rot_half > 0 { + self.dispatch_rope_half_tables_f32( + q.as_id(), cos_id, sin_id, q.as_id(), seq_len, n_head, head_dim, rot_half, + )?; + self.dispatch_rope_half_tables_f32( + k.as_id(), cos_id, sin_id, k.as_id(), seq_len, n_head, head_dim, rot_half, + )?; + } + let scale = 1.0 / (head_dim as f32).sqrt(); + let attn = self.flash_attn_f32_from_buffers( + q.as_id(), k.as_id(), v.as_id(), seq_len, seq_len, n_head, head_dim, scale, + )?; + let out = self.vit_linear_from_buffer( + attn.as_id(), seq_len, n_state, &layer.out, tag_base + 8, tag_base + 9, + )?; + self.dispatch_bin_f32(0, x_id, out.as_id(), x_id, &x_shape, &x_shape)?; + + // Feed-forward: n2 = LN(x); x += down(silu(gate(n2)) * up(n2)). + let n2_w = self.get_or_create_cached_f32_buffer(layer.norm2_w, tag_base + 10)?; + let n2_b = self.get_or_create_cached_f32_buffer(layer.norm2_b, tag_base + 11)?; + let norm1_id = self.get_or_create_scratch_buffer(SCRATCH_ENC_NORM1, norm_bytes)?; + self.dispatch_norm_f32( + x_id, n2_w, n2_b, norm1_id, &x_shape, &ln_shape, &ln_shape, eps, 3, + )?; + let gate = self.vit_linear_from_buffer( + norm1_id, seq_len, n_state, &layer.gate, tag_base + 12, tag_base + 13, + )?; + let up = self.vit_linear_from_buffer( + norm1_id, seq_len, n_state, &layer.up, tag_base + 14, tag_base + 15, + )?; + let ff_shape = shape4_from_row_major(&[seq_len, layer.gate.n], 4)?; + self.dispatch_unary_f32(OP_UNARY_NUM_SILU, gate.as_id(), gate.as_id(), &ff_shape)?; + self.dispatch_bin_f32(2, gate.as_id(), up.as_id(), gate.as_id(), &ff_shape, &ff_shape)?; + let down = self.vit_linear_from_buffer( + gate.as_id(), seq_len, layer.gate.n, &layer.down, tag_base + 16, tag_base + 17, + )?; + self.dispatch_bin_f32(0, x_id, down.as_id(), x_id, &x_shape, &x_shape)?; + Ok(()) + } + + #[allow(clippy::too_many_arguments)] + fn vit_backbone_resident_f32( + &mut self, + x: &[f32], + seq_len: usize, + n_state: usize, + n_head: usize, + rot_half: usize, + cos: &[f32], + sin: &[f32], + layers: &[super::VitLayerRef<'_>], + final_norm_w: &[f32], + final_norm_b: &[f32], + eps: f32, + ) -> Result, String> { + if seq_len == 0 || n_state == 0 || n_head == 0 || n_state % n_head != 0 { + return Err(format!( + "invalid vit dimensions: seq_len={}, n_state={}, n_head={}", + seq_len, n_state, n_head + )); + } + let head_dim = n_state / n_head; + if rot_half * 2 > head_dim { + return Err(format!( + "vit rot_half {} exceeds half of head_dim {}", + rot_half, head_dim + )); + } + let x_need = seq_len + .checked_mul(n_state) + .ok_or_else(|| "overflow computing vit x size".to_string())?; + if x.len() != x_need { + return Err(format!("vit x len mismatch: got {}, expected {}", x.len(), x_need)); + } + let table_need = seq_len * rot_half; + if cos.len() != table_need || sin.len() != table_need { + return Err(format!( + "vit rope table len mismatch: cos {} sin {} expected {}", + cos.len(), + sin.len(), + table_need + )); + } + if final_norm_w.len() != n_state || final_norm_b.len() != n_state { + return Err("vit final layernorm affine size mismatch".to_string()); + } + for (index, layer) in layers.iter().enumerate() { + let lin_ok = |lin: &super::VitLinearRef<'_>, n: usize| { + lin.n == n && (lin.bias.is_empty() || lin.bias.len() == n) + }; + if layer.norm1_w.len() != n_state + || layer.norm1_b.len() != n_state + || layer.norm2_w.len() != n_state + || layer.norm2_b.len() != n_state + || !lin_ok(&layer.q, n_state) + || !lin_ok(&layer.k, n_state) + || !lin_ok(&layer.v, n_state) + || !lin_ok(&layer.out, n_state) + || layer.gate.n == 0 + || !lin_ok(&layer.gate, layer.gate.n) + || !lin_ok(&layer.up, layer.gate.n) + || !lin_ok(&layer.down, n_state) + { + return Err(format!("vit layer {} has mismatched shapes", index)); + } + } + + let x_shape = shape4_from_row_major(&[seq_len, n_state], 4)?; + let ln_shape = shape4_from_row_major(&[n_state], 4)?; + let x_buf = self.new_buffer_with_bytes(f32_slice_as_bytes(x))?; + let (cos_buf, sin_buf) = if rot_half > 0 { + ( + Some(self.new_buffer_with_bytes(f32_slice_as_bytes(cos))?), + Some(self.new_buffer_with_bytes(f32_slice_as_bytes(sin))?), + ) + } else { + (None, None) + }; + let out_buf = self.new_buffer_with_length(x_need * std::mem::size_of::())?; + let cos_id = cos_buf.as_ref().map(|b| b.as_id()).unwrap_or(x_buf.as_id()); + let sin_id = sin_buf.as_ref().map(|b| b.as_id()).unwrap_or(x_buf.as_id()); + let x_id = x_buf.as_id(); + let out_id = out_buf.as_id(); + self.with_batch(|ctx| { + for layer in layers { + ctx.vit_layer_from_buffer_f32( + x_id, seq_len, n_state, n_head, rot_half, cos_id, sin_id, layer, eps, + VIT_TAG_BASE, + )?; + } + let fw = ctx.get_or_create_cached_f32_buffer(final_norm_w, VIT_TAG_BASE + 18)?; + let fb = ctx.get_or_create_cached_f32_buffer(final_norm_b, VIT_TAG_BASE + 19)?; + ctx.dispatch_norm_f32( + x_id, fw, fb, out_id, &x_shape, &ln_shape, &ln_shape, eps, 3, + ) + })?; + let out = self.read_f32_buffer(out_id, x_need)?; + drop(cos_buf); + drop(sin_buf); + drop(x_buf); + drop(out_buf); + Ok(out) + } + fn dispatch_cpy_f32_to_f16( &mut self, src_id: ObjcId, @@ -8874,6 +9256,28 @@ mod imp { } #[allow(clippy::too_many_arguments)] + #[allow(clippy::too_many_arguments)] + pub(super) fn try_vit_backbone_resident_f32( + x: &[f32], + seq_len: usize, + n_state: usize, + n_head: usize, + rot_half: usize, + cos: &[f32], + sin: &[f32], + layers: &[super::VitLayerRef<'_>], + final_norm_w: &[f32], + final_norm_b: &[f32], + eps: f32, + ) -> Option> { + with_context(|ctx| { + ctx.vit_backbone_resident_f32( + x, seq_len, n_state, n_head, rot_half, cos, sin, layers, final_norm_w, + final_norm_b, eps, + ) + }) + } + pub(super) fn try_flash_attn_f32_self_kv_cache( layer: usize, q: &[f32], diff --git a/libs/ai/models/body/src/dino.rs b/libs/ai/models/body/src/dino.rs index 663489a12..5449860d5 100644 --- a/libs/ai/models/body/src/dino.rs +++ b/libs/ai/models/body/src/dino.rs @@ -8,7 +8,8 @@ use crate::backend::{ gpu_add, gpu_attention_packed_cross, gpu_attention_packed_flash2_d64, gpu_concat_rows_many, gpu_download, gpu_layer_norm_mul_add, gpu_linear_nt_cached_bf16_bias_epilogue, gpu_linear_nt_cached_bf16_f32acc, gpu_linear_nt_cached_bf16_mm, gpu_linear_nt_cached_f8_mm, - gpu_add_cols_broadcast, gpu_mul, gpu_rope_half, + gpu_add_cols_broadcast, gpu_mul, gpu_rope_half, gpu_vit_backbone_resident, GpuVitLayer, + GpuVitLinear, gpu_silu, gpu_slice_rows, gpu_upload, GpuLinearPart, GpuTensor, }; use crate::weights::BodyWeights; @@ -208,6 +209,38 @@ pub struct BodyDino { layers: Vec, final_norm_w: Vec, final_norm_b: Vec, + /// Set once the backend declined the whole-stack resident call; the + /// per-op path is used from then on. + resident_refused: std::cell::Cell, +} + +impl Bf16Linear { + fn vit_ref(&self) -> GpuVitLinear<'_> { + GpuVitLinear { + w_bytes: &self.bytes, + w_ggml_type: GGML_TYPE_BF16, + n: self.out, + bias: &self.bias, + } + } +} + +impl DinoLayer { + fn vit_ref(&self) -> GpuVitLayer<'_> { + GpuVitLayer { + norm1_w: &self.norm1_w, + norm1_b: &self.norm1_b, + q: self.q.vit_ref(), + k: self.k.vit_ref(), + v: self.v.vit_ref(), + out: self.out.vit_ref(), + norm2_w: &self.norm2_w, + norm2_b: &self.norm2_b, + gate: self.gate.vit_ref(), + up: self.up.vit_ref(), + down: self.down.vit_ref(), + } + } } /// Bias add broadcast over rows: `out[r] = x[r] + bias`. @@ -374,6 +407,7 @@ impl BodyDino { layers, final_norm_w: weights.f32_shaped("backbone.norm.weight", &[DINO_DIM])?, final_norm_b: weights.f32_shaped("backbone.norm.bias", &[DINO_DIM])?, + resident_refused: std::cell::Cell::new(false), }) } @@ -451,6 +485,29 @@ impl BodyDino { let cos = gpu_upload(&cos, rows, ROPE_HALF).map_err(DiffusionError::model)?; let sin = gpu_upload(&sin, rows, ROPE_HALF).map_err(DiffusionError::model)?; + // The whole stack in one backend call when the backend offers it + // (Metal: one command buffer, no host round trips between ops). + if !self.resident_refused.get() { + let layers: Vec> = self.layers.iter().map(DinoLayer::vit_ref).collect(); + match gpu_vit_backbone_resident( + &hidden, + DINO_HEADS, + ROPE_HALF, + &cos, + &sin, + &layers, + &self.final_norm_w, + &self.final_norm_b, + DINO_NORM_EPS, + ) { + Ok(normalized) => { + return gpu_slice_rows(&normalized, DINO_PREFIX_TOKENS, num_patches) + .map_err(DiffusionError::model); + } + Err(_) => self.resident_refused.set(true), + } + } + for layer in &self.layers { let normed = gpu_layer_norm_mul_add( &hidden, diff --git a/libs/ai/models/common/src/backend.rs b/libs/ai/models/common/src/backend.rs index 8ba8d0eae..ad650ed6d 100644 --- a/libs/ai/models/common/src/backend.rs +++ b/libs/ai/models/common/src/backend.rs @@ -82,6 +82,7 @@ pub use crate::gpu::{ gpu_rife_conv_transpose2d, gpu_rife_fill, gpu_rife_merge_rgb8, gpu_rife_res_conv, gpu_rife_scale, gpu_rife_warp, gpu_rope_half, gpu_rope_half_bf16, gpu_rope_interleaved, gpu_silu, gpu_slice_cols, gpu_slice_rows, + gpu_vit_backbone_resident, GpuVitLayer, GpuVitLinear, gpu_splat_repo3d_tables, gpu_splat_rope_pairs_per_head, gpu_swiglu_gate_first, gpu_swiglu_value_gate, gpu_to_f16, gpu_upload, gpu_wavenet_gate, gpu_quant_linear_type_supported, diff --git a/libs/ai/models/common/src/gpu.rs b/libs/ai/models/common/src/gpu.rs index 5138ac26b..275bdfcc7 100644 --- a/libs/ai/models/common/src/gpu.rs +++ b/libs/ai/models/common/src/gpu.rs @@ -7,6 +7,55 @@ #[cfg(all(any(target_os = "linux", target_os = "windows"), makepad_ai_cuda_kernels))] pub use makepad_ai_cuda::launch::*; +/// One linear of a device-resident ViT layer: a row-major `[n, k]` weight in +/// a ggml dtype, its output width and its bias (empty for none). +#[derive(Clone, Copy)] +pub struct GpuVitLinear<'a> { + pub w_bytes: &'a [u8], + pub w_ggml_type: u32, + pub n: usize, + pub bias: &'a [f32], +} + +/// One pre-norm ViT layer with rotary attention and a SwiGLU feed-forward: +/// `x += out(attn(rope(q(n1)), rope(k(n1)), v(n1)))`, then +/// `x += down(silu(gate(n2)) * up(n2))`; LayerNorm affines on both norms, +/// layer scales folded into `out`/`down`. +#[derive(Clone, Copy)] +pub struct GpuVitLayer<'a> { + pub norm1_w: &'a [f32], + pub norm1_b: &'a [f32], + pub q: GpuVitLinear<'a>, + pub k: GpuVitLinear<'a>, + pub v: GpuVitLinear<'a>, + pub out: GpuVitLinear<'a>, + pub norm2_w: &'a [f32], + pub norm2_b: &'a [f32], + pub gate: GpuVitLinear<'a>, + pub up: GpuVitLinear<'a>, + pub down: GpuVitLinear<'a>, +} + +/// A whole ViT stack in one backend call (see `GpuVitLayer`): the Metal +/// tensor backend runs it device-resident in one command buffer; CUDA +/// declines (its per-op `gpu_*` path is already resident) and the caller +/// keeps its per-op path. +#[cfg(all(any(target_os = "linux", target_os = "windows"), makepad_ai_cuda_kernels))] +#[allow(clippy::too_many_arguments)] +pub fn gpu_vit_backbone_resident( + _x: &GpuTensor, + _n_head: usize, + _rot_half: usize, + _cos: &GpuTensor, + _sin: &GpuTensor, + _layers: &[GpuVitLayer<'_>], + _final_norm_w: &[f32], + _final_norm_b: &[f32], + _eps: f32, +) -> Result { + Err("gpu_vit_backbone_resident: CUDA runs the per-op path".to_string()) +} + #[cfg(not(all(any(target_os = "linux", target_os = "windows"), makepad_ai_cuda_kernels)))] mod imp { use makepad_ai_cuda::accel::{AffineQuantizedMatmulRowsSpec, AffineQuantizedMatmulSpec}; @@ -3224,6 +3273,63 @@ mod imp { } } + #[allow(clippy::too_many_arguments)] + pub fn gpu_vit_backbone_resident( + _x: &GpuTensor, + _n_head: usize, + _rot_half: usize, + _cos: &GpuTensor, + _sin: &GpuTensor, + _layers: &[super::GpuVitLayer<'_>], + _final_norm_w: &[f32], + _final_norm_b: &[f32], + _eps: f32, + ) -> Result { + #[cfg(target_os = "macos")] + { + use makepad_ai_metal::gpu_tensor::{VitLayerRef, VitLinearRef}; + fn lin<'a>(l: &super::GpuVitLinear<'a>) -> VitLinearRef<'a> { + VitLinearRef { + w_bytes: l.w_bytes, + w_ggml_type: l.w_ggml_type, + n: l.n, + bias: l.bias, + } + } + let layers: Vec> = _layers + .iter() + .map(|l| VitLayerRef { + norm1_w: l.norm1_w, + norm1_b: l.norm1_b, + q: lin(&l.q), + k: lin(&l.k), + v: lin(&l.v), + out: lin(&l.out), + norm2_w: l.norm2_w, + norm2_b: l.norm2_b, + gate: lin(&l.gate), + up: lin(&l.up), + down: lin(&l.down), + }) + .collect(); + return makepad_ai_metal::gpu_tensor::vit_backbone_resident( + _x, + _n_head, + _rot_half, + _cos, + _sin, + &layers, + _final_norm_w, + _final_norm_b, + _eps, + ); + } + #[cfg(not(target_os = "macos"))] + { + Err(GPU_UNAVAILABLE.to_string()) + } + } + pub fn gpu_add_cols_broadcast(_x: &GpuTensor, _bias: &GpuTensor) -> Result { #[cfg(target_os = "macos")] { From d006d0a1bc99c51091996e16e7e0cb3898f9e8b6 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 00:20:46 +0200 Subject: [PATCH 036/417] metal: resident f32 linears keep their weight on the device gpu_linear_f32_resident promised a resident weight but the Metal tensor backend re-uploaded it every call, which for the MHR rig's 664 MB pose corrective matrix cost 50 ms a step. Metal tensors now carry a content identity (fresh at creation and after every in-place write, so a cache keyed by it can never serve a stale weight), and the resident linear caches the device buffer under it. Body frame on the M3 Max: 705 -> 405 ms (rig 302 -> 20 ms, refine 41 -> 13 ms, heads 10 -> 6 ms). Co-Authored-By: Claude Fable 5.1 --- libs/ai/metal/src/gpu_tensor.rs | 40 ++++++++++++++++++++++++++++----- libs/ai/metal/src/gpu_types.rs | 14 +++++++++++- libs/ai/metal/src/rife.rs | 1 + 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/libs/ai/metal/src/gpu_tensor.rs b/libs/ai/metal/src/gpu_tensor.rs index 764637153..fdc1d5b7f 100644 --- a/libs/ai/metal/src/gpu_tensor.rs +++ b/libs/ai/metal/src/gpu_tensor.rs @@ -3,12 +3,13 @@ //! Metal try_* kernels. Small addressing ops stay on the host. No oracle; //! goal is a working Metal path we can then keep cutting copies. -use crate::gpu_types::{GpuLinearPart, GpuTensor}; +use crate::gpu_types::{fresh_tensor_id, GpuLinearPart, GpuTensor}; +use makepad_ai_cuda::quant::GGML_TYPE_F32; pub use crate::shim::{VitLayerRef, VitLinearRef}; use crate::shim::{ try_add_f32, try_conv2d_planar_f32, try_flash_attn_f32_packed, try_gelu_f32, try_group_norm_planar_f32, try_layer_norm_mul_add_f32, try_matmul_nt_f32, try_mul_f32, - try_silu_f32, try_vit_backbone_resident_f32, + try_matmul_nt_ggml_bytes_keyed, try_silu_f32, try_vit_backbone_resident_f32, }; use std::cell::RefCell; use std::collections::HashMap; @@ -20,6 +21,7 @@ fn tensor(rows: usize, cols: usize, data: Vec) -> GpuTensor { cols, data: RefCell::new(data), u32s: RefCell::new(Vec::new()), + id: std::cell::Cell::new(fresh_tensor_id()), } } @@ -134,6 +136,7 @@ pub fn upload_u32(values: &[u32]) -> Result { cols: 1, data: RefCell::new(Vec::new()), u32s: RefCell::new(values.to_vec()), + id: std::cell::Cell::new(fresh_tensor_id()), }) } @@ -152,6 +155,7 @@ pub fn upload_into(t: &GpuTensor, values: &[f32]) -> Result<(), String> { } } *slot = values.to_vec(); + t.id.set(fresh_tensor_id()); Ok(()) } @@ -162,6 +166,7 @@ pub fn copy_into(src: &GpuTensor, dst: &GpuTensor) -> Result<(), String> { .try_borrow_mut() .map_err(|_| "metal copy_into borrow".to_string())?; *dst_data = src_data; + dst.id.set(fresh_tensor_id()); Ok(()) } @@ -403,17 +408,42 @@ pub fn linear_nt( Ok(tensor(x.rows, n, out)) } +/// Linear against a long-lived f32 weight: the weight goes to the device +/// once, cached under the tensor's content identity (the CUDA contract keeps +/// the weight resident too), so a per-frame call pays for the GEMM only. pub fn linear_f32_resident( x: &GpuTensor, w: &GpuTensor, bias: Option<&GpuTensor>, ) -> Result { let xd = data(x)?; - let wd = data(w)?; let n = w.rows; let k = w.cols; - let mut out = try_matmul_nt_f32(&xd, &wd, x.rows, k, n) - .ok_or_else(|| "metal resident matmul failed".to_string())?; + if x.cols != k { + return Err(format!( + "metal resident linear k mismatch: x {}x{}, w {}x{}", + x.rows, x.cols, w.rows, w.cols + )); + } + let cache_key = format!("t{}", w.id.get()); + let mut out = try_matmul_nt_ggml_bytes_keyed( + &xd, + GGML_TYPE_F32, + x.rows, + k, + n, + "resident_f32", + &cache_key, + || { + let wd = data(w)?; + let mut bytes = Vec::with_capacity(wd.len() * 4); + for value in wd.iter() { + bytes.extend_from_slice(&value.to_le_bytes()); + } + Ok(bytes) + }, + ) + .ok_or_else(|| "metal resident matmul failed".to_string())?; if let Some(bias) = bias { let bd = data(bias)?; for r in 0..x.rows { diff --git a/libs/ai/metal/src/gpu_types.rs b/libs/ai/metal/src/gpu_types.rs index 4fd2a0a73..5acd469ba 100644 --- a/libs/ai/metal/src/gpu_types.rs +++ b/libs/ai/metal/src/gpu_types.rs @@ -1,12 +1,24 @@ //! Host-backed tensor handle used by the macOS Metal GpuTensor path. -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; +use std::sync::atomic::{AtomicU64, Ordering}; + +static NEXT_TENSOR_ID: AtomicU64 = AtomicU64::new(1); + +/// A process-unique identity for a tensor's current contents. +pub(crate) fn fresh_tensor_id() -> u64 { + NEXT_TENSOR_ID.fetch_add(1, Ordering::Relaxed) +} pub struct GpuTensor { pub(crate) rows: usize, pub(crate) cols: usize, pub(crate) data: RefCell>, pub(crate) u32s: RefCell>, + /// Identity of the current contents: fresh at creation and after every + /// in-place write, so device-side caches keyed by it can never serve a + /// stale weight (a pointer can be reused; an id cannot). + pub(crate) id: Cell, } impl GpuTensor { diff --git a/libs/ai/metal/src/rife.rs b/libs/ai/metal/src/rife.rs index 5052549cf..c67043720 100644 --- a/libs/ai/metal/src/rife.rs +++ b/libs/ai/metal/src/rife.rs @@ -54,6 +54,7 @@ fn tensor(rows: usize, cols: usize, data: Vec) -> GpuTensor { cols, data: RefCell::new(data), u32s: RefCell::new(Vec::new()), + id: std::cell::Cell::new(crate::gpu_types::fresh_tensor_id()), } } From 525ba1c2f4779c409c7b8112c2f15425851e7d69 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 00:25:59 +0200 Subject: [PATCH 037/417] metal: a device-resident two-way decoder layer, and the body decoder rides it One backend call per SAM-style decoder layer (PE norms, token self-attention, token-to-image cross-attention, erf-GELU feed-forward, final norm) inside one command buffer, with the layer's f32 weights cached on the device under their content identity and pooled transients. gpu_two_way_layer_resident in the common backend; CUDA declines and the per-op path stays. Body decoder loop on the M3 Max: layers 100 -> 9 ms, frame 405 -> 266 ms, oracle parity unchanged (kp3d 1.5 mm). Co-Authored-By: Claude Fable 5.1 --- libs/ai/metal/src/gpu_tensor.rs | 43 ++- libs/ai/metal/src/shim.rs | 438 +++++++++++++++++++++++++++ libs/ai/models/body/src/decoder.rs | 119 ++++++-- libs/ai/models/common/src/backend.rs | 1 + libs/ai/models/common/src/gpu.rs | 108 +++++++ 5 files changed, 679 insertions(+), 30 deletions(-) diff --git a/libs/ai/metal/src/gpu_tensor.rs b/libs/ai/metal/src/gpu_tensor.rs index fdc1d5b7f..44574d2ac 100644 --- a/libs/ai/metal/src/gpu_tensor.rs +++ b/libs/ai/metal/src/gpu_tensor.rs @@ -5,11 +5,12 @@ use crate::gpu_types::{fresh_tensor_id, GpuLinearPart, GpuTensor}; use makepad_ai_cuda::quant::GGML_TYPE_F32; -pub use crate::shim::{VitLayerRef, VitLinearRef}; +pub use crate::shim::{DecAttnRef, DecLinearRef, TwoWayLayerRef, VitLayerRef, VitLinearRef}; use crate::shim::{ try_add_f32, try_conv2d_planar_f32, try_flash_attn_f32_packed, try_gelu_f32, try_group_norm_planar_f32, try_layer_norm_mul_add_f32, try_matmul_nt_f32, try_mul_f32, - try_matmul_nt_ggml_bytes_keyed, try_silu_f32, try_vit_backbone_resident_f32, + try_matmul_nt_ggml_bytes_keyed, try_silu_f32, try_two_way_layer_resident_f32, + try_vit_backbone_resident_f32, }; use std::cell::RefCell; use std::collections::HashMap; @@ -812,6 +813,44 @@ pub fn vit_backbone_resident( Ok(tensor(x.rows, x.cols, out)) } +/// One two-way decoder layer device-resident (see `shim::TwoWayLayerRef`); +/// returns `(hidden, ln_final(hidden))`. +pub fn two_way_layer_resident( + hidden: &GpuTensor, + token_pe: &GpuTensor, + context: &GpuTensor, + context_pe: &GpuTensor, + layer: &TwoWayLayerRef<'_>, +) -> Result<(GpuTensor, GpuTensor), String> { + if token_pe.rows != hidden.rows + || token_pe.cols != hidden.cols + || context_pe.rows != context.rows + || context_pe.cols != context.cols + { + return Err("metal two-way layer: PE shapes do not match their tensors".to_string()); + } + let h = data(hidden)?; + let t = data(token_pe)?; + let c = data(context)?; + let cp = data(context_pe)?; + let (out, normed) = try_two_way_layer_resident_f32( + &h, + &t, + &c, + &cp, + hidden.rows, + hidden.cols, + context.rows, + context.cols, + layer, + ) + .ok_or_else(|| "metal resident two-way layer failed".to_string())?; + Ok(( + tensor(hidden.rows, hidden.cols, out), + tensor(hidden.rows, hidden.cols, normed), + )) +} + pub fn layer_norm_mul_add( x: &GpuTensor, mul: &[f32], diff --git a/libs/ai/metal/src/shim.rs b/libs/ai/metal/src/shim.rs index 94f6978b5..5e8bbccbc 100644 --- a/libs/ai/metal/src/shim.rs +++ b/libs/ai/metal/src/shim.rs @@ -32,6 +32,7 @@ pub fn is_available() -> bool { cfg!(target_os = "macos") } +use crate::gpu_types::GpuTensor; use makepad_ai_cuda::prof; fn prof_rec(cat: usize, start: std::time::Instant, f32_count: usize) { @@ -345,6 +346,67 @@ pub fn clear_decoder_kv_cache() { } #[allow(clippy::too_many_arguments)] +/// One linear of a device-resident two-way decoder layer: an f32 `[n, k]` +/// weight tensor (cached on the device under its content identity) and an +/// optional `[1, n]` bias. +#[derive(Clone, Copy)] +pub struct DecLinearRef<'a> { + pub weight: &'a GpuTensor, + pub bias: Option<&'a GpuTensor>, +} + +#[derive(Clone, Copy)] +pub struct DecAttnRef<'a> { + pub q: DecLinearRef<'a>, + pub k: DecLinearRef<'a>, + pub v: DecLinearRef<'a>, + pub out: DecLinearRef<'a>, +} + +/// One SAM-style two-way decoder layer over `hidden` `[n_tok, dim]` with +/// image context `[n_ctx, ctx_dim]`: token self-attention (queries/keys +/// carry the token PE when `pe_on_self`), token-to-image cross-attention +/// (query = LN(hidden) + token PE, key = LN(context) + image PE, value = +/// LN(context)), an erf-GELU feed-forward, then `ln_final`. All norms are +/// LayerNorm with affines; `ln_pe_1`/`ln_pe_2` normalise the two PEs. +#[derive(Clone, Copy)] +pub struct TwoWayLayerRef<'a> { + pub ln_pe_1: (&'a [f32], &'a [f32]), + pub ln_pe_2: (&'a [f32], &'a [f32]), + pub ln1: (&'a [f32], &'a [f32]), + pub ln2_1: (&'a [f32], &'a [f32]), + pub ln2_2: (&'a [f32], &'a [f32]), + pub ln3: (&'a [f32], &'a [f32]), + pub ln_final: (&'a [f32], &'a [f32]), + pub self_attn: DecAttnRef<'a>, + pub cross_attn: DecAttnRef<'a>, + pub ffn_first: DecLinearRef<'a>, + pub ffn_second: DecLinearRef<'a>, + pub n_head: usize, + pub eps: f32, + pub pe_on_self: bool, +} + +/// Runs one two-way decoder layer device-resident (one command buffer, +/// weights cached) and returns `(hidden, ln_final(hidden))`, both +/// `[n_tok, dim]`. +#[allow(clippy::too_many_arguments)] +pub fn try_two_way_layer_resident_f32( + hidden: &[f32], + token_pe: &[f32], + context: &[f32], + context_pe: &[f32], + n_tok: usize, + dim: usize, + n_ctx: usize, + ctx_dim: usize, + layer: &TwoWayLayerRef<'_>, +) -> Option<(Vec, Vec)> { + imp::try_two_way_layer_resident_f32( + hidden, token_pe, context, context_pe, n_tok, dim, n_ctx, ctx_dim, layer, + ) +} + /// One linear of a device-resident ViT layer: a row-major `[n, k]` weight in /// a ggml dtype, its output width and its bias (empty for none). #[derive(Clone, Copy)] @@ -1111,6 +1173,21 @@ mod imp { None } + #[allow(clippy::too_many_arguments)] + pub(super) fn try_two_way_layer_resident_f32( + _hidden: &[f32], + _token_pe: &[f32], + _context: &[f32], + _context_pe: &[f32], + _n_tok: usize, + _dim: usize, + _n_ctx: usize, + _ctx_dim: usize, + _layer: &super::TwoWayLayerRef<'_>, + ) -> Option<(Vec, Vec)> { + None + } + pub(super) fn try_flash_attn_f32_self_kv_cache( _layer: usize, _q: &[f32], @@ -1682,6 +1759,21 @@ mod imp { None } + #[allow(clippy::too_many_arguments)] + pub(super) fn try_two_way_layer_resident_f32( + _hidden: &[f32], + _token_pe: &[f32], + _context: &[f32], + _context_pe: &[f32], + _n_tok: usize, + _dim: usize, + _n_ctx: usize, + _ctx_dim: usize, + _layer: &super::TwoWayLayerRef<'_>, + ) -> Option<(Vec, Vec)> { + None + } + pub(super) fn try_flash_attn_f32_self_kv_cache( _layer: usize, _q: &[f32], @@ -1879,6 +1971,10 @@ mod imp { /// Persistent-scratch tag range `[VIT_TAG_BASE, VIT_TAG_BASE + 20)` of the /// resident ViT stack (`vit_layer_from_buffer_f32`). const VIT_TAG_BASE: u8 = 200; + const OP_UNARY_NUM_GELU_ERF: i16 = 104; + /// Cached-affine tag range `[TWO_WAY_TAG_BASE, TWO_WAY_TAG_BASE + 14)` of + /// the resident two-way decoder layer. + const TWO_WAY_TAG_BASE: u8 = 180; const SCRATCH_FLASH_PAD: u8 = 1; const SCRATCH_FLASH_BLK: u8 = 2; const SCRATCH_FLASH_TMP: u8 = 3; @@ -4771,6 +4867,329 @@ mod imp { Ok(out) } + /// `C(m, n) = X(m, k) @ W^T` from device buffers: `src0_id` holds the + /// `[n, k]` weight in `src0_ggml_type`, `src1_id` the f32 `[m, k]` + /// input, and the f32 `[m, n]` result lands in `dst_id`. + #[allow(clippy::too_many_arguments)] + fn matmul_nt_into_buffer( + &mut self, + src0_ggml_type: u32, + src0_id: ObjcId, + src1_id: ObjcId, + dst_id: ObjcId, + m: usize, + k: usize, + n: usize, + ) -> Result<(), String> { + let src0 = src0_type_from_ggml(src0_ggml_type).ok_or_else(|| { + format!("unsupported src0 ggml_type for metal matmul: {}", src0_ggml_type) + })?; + let (src0_row_bytes, nb00) = src0_layout_bytes_per_row(src0, k)?; + let ne00 = i32::try_from(k).map_err(|_| format!("k too large: {}", k))?; + let ne01 = i32::try_from(n).map_err(|_| format!("n too large: {}", n))?; + let ne10 = ne00; + let ne11 = i32::try_from(m).map_err(|_| format!("m too large: {}", m))?; + let ne0 = ne01; + let ne1 = ne11; + let nb01 = src0_row_bytes as u64; + let nb10 = 4u64; + let nb11 = (k as u64) + .checked_mul(4) + .ok_or_else(|| "overflow computing nb11".to_string())?; + if can_use_mul_mv_ext(src0, ne00, ne11) { + self.dispatch_mul_mv_ext( + src0, src0_id, src1_id, dst_id, ne00, ne01, ne10, ne11, nb00, nb01, nb10, + nb11, ne0, ne1, + ) + } else if ne00 >= 64 && ne11 > 8 { + match self.dispatch_mul_mm( + src0, src0_id, src1_id, dst_id, ne00, ne01, nb01, 1, nb10, nb11, ne0, ne1, + ) { + Ok(()) => Ok(()), + Err(e) => { + super::log_metal_error_once(format!( + "[ggml][metal] mul_mm failed for type {:?}, falling back to mul_mv: {}", + src0, e + )); + self.dispatch_mul_mv( + src0, src0_id, src1_id, dst_id, ne00, ne01, ne10, ne11, nb00, nb01, + nb10, nb11, ne0, ne1, + ) + } + } + } else { + self.dispatch_mul_mv( + src0, src0_id, src1_id, dst_id, ne00, ne01, ne10, ne11, nb00, nb01, nb10, + nb11, ne0, ne1, + ) + } + } + + /// The f32 contents of a host-backed tensor as little-endian bytes. + fn tensor_f32_bytes(t: &crate::gpu_types::GpuTensor) -> Result, String> { + let data = t + .data + .try_borrow() + .map_err(|_| "metal GpuTensor already borrowed".to_string())?; + let mut bytes = Vec::with_capacity(data.len() * 4); + for value in data.iter() { + bytes.extend_from_slice(&value.to_le_bytes()); + } + Ok(bytes) + } + + /// A pooled f32 `[rows, cols]` buffer registered in `keep` (given back + /// to the pool after the layer's read-back). + fn two_way_scratch( + &mut self, + rows: usize, + cols: usize, + keep: &mut Vec, + ) -> Result { + let bytes = rows + .checked_mul(cols) + .and_then(|v| v.checked_mul(4)) + .ok_or_else(|| "overflow computing two-way scratch bytes".to_string())?; + let buf = self.pool_take(bytes)?; + let id = buf.as_id(); + keep.push(buf); + Ok(id) + } + + fn two_way_linear( + &mut self, + src_id: ObjcId, + m: usize, + lin: &super::DecLinearRef<'_>, + keep: &mut Vec, + ) -> Result { + let n = lin.weight.rows; + let k = lin.weight.cols; + let weight = lin.weight; + let w_id = self.get_or_create_named_weight_buffer( + "two_way", + &format!("w{}", weight.id.get()), + || Self::tensor_f32_bytes(weight), + )?; + let dst_id = self.two_way_scratch(m, n, keep)?; + self.matmul_nt_into_buffer(GGML_TYPE_F32, w_id, src_id, dst_id, m, k, n)?; + if let Some(bias) = lin.bias { + if bias.rows * bias.cols != n { + return Err(format!( + "two-way linear bias {}x{} does not match n {}", + bias.rows, bias.cols, n + )); + } + let b_id = self.get_or_create_named_weight_buffer( + "two_way", + &format!("b{}", bias.id.get()), + || Self::tensor_f32_bytes(bias), + )?; + let dst_shape = shape4_from_row_major(&[m, n], 4)?; + let b_shape = shape4_from_row_major(&[n], 4)?; + self.dispatch_bin_f32(0, dst_id, b_id, dst_id, &dst_shape, &b_shape)?; + } + Ok(dst_id) + } + + #[allow(clippy::too_many_arguments)] + fn two_way_norm( + &mut self, + src_id: ObjcId, + rows: usize, + cols: usize, + affine: (&[f32], &[f32]), + tag: u8, + eps: f32, + keep: &mut Vec, + ) -> Result { + if affine.0.len() != cols || affine.1.len() != cols { + return Err(format!( + "two-way layernorm affine {}/{} does not match {} cols", + affine.0.len(), + affine.1.len(), + cols + )); + } + let w_id = self.get_or_create_cached_f32_buffer(affine.0, tag)?; + let b_id = self.get_or_create_cached_f32_buffer(affine.1, tag + 1)?; + let dst_id = self.two_way_scratch(rows, cols, keep)?; + let x_shape = shape4_from_row_major(&[rows, cols], 4)?; + let ln_shape = shape4_from_row_major(&[cols], 4)?; + self.dispatch_norm_f32( + src_id, w_id, b_id, dst_id, &x_shape, &ln_shape, &ln_shape, eps, 3, + )?; + Ok(dst_id) + } + + fn two_way_add( + &mut self, + a_id: ObjcId, + b_id: ObjcId, + dst_id: ObjcId, + rows: usize, + cols: usize, + ) -> Result<(), String> { + let shape = shape4_from_row_major(&[rows, cols], 4)?; + self.dispatch_bin_f32(0, a_id, b_id, dst_id, &shape, &shape) + } + + #[allow(clippy::too_many_arguments)] + fn two_way_layer_resident_f32( + &mut self, + hidden: &[f32], + token_pe: &[f32], + context: &[f32], + context_pe: &[f32], + n_tok: usize, + dim: usize, + n_ctx: usize, + ctx_dim: usize, + layer: &super::TwoWayLayerRef<'_>, + ) -> Result<(Vec, Vec), String> { + if n_tok == 0 || dim == 0 || n_ctx == 0 || ctx_dim == 0 || layer.n_head == 0 { + return Err("two-way layer: empty dimension".to_string()); + } + let tok_elems = n_tok * dim; + let ctx_elems = n_ctx * ctx_dim; + if hidden.len() != tok_elems || token_pe.len() != tok_elems { + return Err(format!( + "two-way layer: hidden {} / token_pe {} vs {}x{}", + hidden.len(), + token_pe.len(), + n_tok, + dim + )); + } + if context.len() != ctx_elems || context_pe.len() != ctx_elems { + return Err(format!( + "two-way layer: context {} / context_pe {} vs {}x{}", + context.len(), + context_pe.len(), + n_ctx, + ctx_dim + )); + } + let sa = &layer.self_attn; + let ca = &layer.cross_attn; + let inner = sa.q.weight.rows; + if inner == 0 || inner % layer.n_head != 0 { + return Err(format!( + "two-way layer: attention width {} not divisible by {} heads", + inner, layer.n_head + )); + } + let head_dim = inner / layer.n_head; + if !flash_attn_supported_head_dim(head_dim) { + return Err(format!("two-way layer: head dim {} unsupported", head_dim)); + } + let shape_ok = |lin: &super::DecLinearRef<'_>, n: usize, k: usize| { + lin.weight.rows == n && lin.weight.cols == k + }; + if !shape_ok(&sa.q, inner, dim) + || !shape_ok(&sa.k, inner, dim) + || !shape_ok(&sa.v, inner, dim) + || !shape_ok(&sa.out, dim, inner) + || !shape_ok(&ca.q, inner, dim) + || !shape_ok(&ca.k, inner, ctx_dim) + || !shape_ok(&ca.v, inner, ctx_dim) + || !shape_ok(&ca.out, dim, inner) + || layer.ffn_first.weight.cols != dim + || !shape_ok(&layer.ffn_second, dim, layer.ffn_first.weight.rows) + { + return Err("two-way layer: weight shapes do not match the layer".to_string()); + } + let ffn_width = layer.ffn_first.weight.rows; + let scale = 1.0 / (head_dim as f32).sqrt(); + let eps = layer.eps; + let tag = TWO_WAY_TAG_BASE; + + let mut keep: Vec = Vec::new(); + let x_buf = self.pool_take_filled(f32_slice_as_bytes(hidden))?; + let tpe_buf = self.pool_take_filled(f32_slice_as_bytes(token_pe))?; + let ctx_buf = self.pool_take_filled(f32_slice_as_bytes(context))?; + let cpe_buf = self.pool_take_filled(f32_slice_as_bytes(context_pe))?; + let normed_buf = self.pool_take(tok_elems * 4)?; + let x_id = x_buf.as_id(); + let normed_id = normed_buf.as_id(); + + let run = self.with_batch(|ctx| { + let keep = &mut keep; + // Positional embeddings, normalised once per layer. + let tpe_n = ctx.two_way_norm(tpe_buf.as_id(), n_tok, dim, layer.ln_pe_1, tag, eps, keep)?; + let ipe_n = + ctx.two_way_norm(cpe_buf.as_id(), n_ctx, ctx_dim, layer.ln_pe_2, tag + 2, eps, keep)?; + + // Token self-attention. + let n1 = ctx.two_way_norm(x_id, n_tok, dim, layer.ln1, tag + 4, eps, keep)?; + let qk = if layer.pe_on_self { + let qk = ctx.two_way_scratch(n_tok, dim, keep)?; + ctx.two_way_add(n1, tpe_n, qk, n_tok, dim)?; + qk + } else { + n1 + }; + let q = ctx.two_way_linear(qk, n_tok, &sa.q, keep)?; + let k = ctx.two_way_linear(qk, n_tok, &sa.k, keep)?; + let v = ctx.two_way_linear(n1, n_tok, &sa.v, keep)?; + let attn = ctx.flash_attn_f32_from_buffers( + q, k, v, n_tok, n_tok, layer.n_head, head_dim, scale, + )?; + let o = ctx.two_way_linear(attn.as_id(), n_tok, &sa.out, keep)?; + ctx.two_way_add(x_id, o, x_id, n_tok, dim)?; + drop(attn); + + // Token-to-image cross-attention. + let q2n = ctx.two_way_norm(x_id, n_tok, dim, layer.ln2_1, tag + 6, eps, keep)?; + let q2 = ctx.two_way_scratch(n_tok, dim, keep)?; + ctx.two_way_add(q2n, tpe_n, q2, n_tok, dim)?; + let cn = ctx.two_way_norm(ctx_buf.as_id(), n_ctx, ctx_dim, layer.ln2_2, tag + 8, eps, keep)?; + let kx = ctx.two_way_scratch(n_ctx, ctx_dim, keep)?; + ctx.two_way_add(cn, ipe_n, kx, n_ctx, ctx_dim)?; + let q = ctx.two_way_linear(q2, n_tok, &ca.q, keep)?; + let k = ctx.two_way_linear(kx, n_ctx, &ca.k, keep)?; + let v = ctx.two_way_linear(cn, n_ctx, &ca.v, keep)?; + let attn = ctx.flash_attn_f32_from_buffers( + q, k, v, n_tok, n_ctx, layer.n_head, head_dim, scale, + )?; + let o = ctx.two_way_linear(attn.as_id(), n_tok, &ca.out, keep)?; + ctx.two_way_add(x_id, o, x_id, n_tok, dim)?; + drop(attn); + + // Feed-forward with the exact GELU. + let n3 = ctx.two_way_norm(x_id, n_tok, dim, layer.ln3, tag + 10, eps, keep)?; + let f = ctx.two_way_linear(n3, n_tok, &layer.ffn_first, keep)?; + let f_shape = shape4_from_row_major(&[n_tok, ffn_width], 4)?; + ctx.dispatch_unary_f32(OP_UNARY_NUM_GELU_ERF, f, f, &f_shape)?; + let f2 = ctx.two_way_linear(f, n_tok, &layer.ffn_second, keep)?; + ctx.two_way_add(x_id, f2, x_id, n_tok, dim)?; + + // Final norm, read back alongside the hidden state. + let fw = ctx.get_or_create_cached_f32_buffer(layer.ln_final.0, tag + 12)?; + let fb = ctx.get_or_create_cached_f32_buffer(layer.ln_final.1, tag + 13)?; + let x_shape = shape4_from_row_major(&[n_tok, dim], 4)?; + let ln_shape = shape4_from_row_major(&[dim], 4)?; + ctx.dispatch_norm_f32( + x_id, fw, fb, normed_id, &x_shape, &ln_shape, &ln_shape, eps, 3, + ) + }); + let result = run.and_then(|()| { + let hidden_out = self.read_f32_buffer(x_id, tok_elems)?; + let normed_out = self.read_f32_buffer(normed_id, tok_elems)?; + Ok((hidden_out, normed_out)) + }); + // Everything above waited on the queue, so the transients are free. + let _ = self.wait_queue_idle(); + for buf in keep.drain(..) { + self.pool_give(buf); + } + for buf in [x_buf, tpe_buf, ctx_buf, cpe_buf, normed_buf] { + self.pool_give(buf); + } + self.pool_recycle(); + result + } + fn dispatch_cpy_f32_to_f16( &mut self, src_id: ObjcId, @@ -9278,6 +9697,25 @@ mod imp { }) } + #[allow(clippy::too_many_arguments)] + pub(super) fn try_two_way_layer_resident_f32( + hidden: &[f32], + token_pe: &[f32], + context: &[f32], + context_pe: &[f32], + n_tok: usize, + dim: usize, + n_ctx: usize, + ctx_dim: usize, + layer: &super::TwoWayLayerRef<'_>, + ) -> Option<(Vec, Vec)> { + with_context(|ctx| { + ctx.two_way_layer_resident_f32( + hidden, token_pe, context, context_pe, n_tok, dim, n_ctx, ctx_dim, layer, + ) + }) + } + pub(super) fn try_flash_attn_f32_self_kv_cache( layer: usize, q: &[f32], diff --git a/libs/ai/models/body/src/decoder.rs b/libs/ai/models/body/src/decoder.rs index 142f619db..713a0e9c6 100644 --- a/libs/ai/models/body/src/decoder.rs +++ b/libs/ai/models/body/src/decoder.rs @@ -1,8 +1,9 @@ //! Promptable body-pose decoder and its six-step refinement loop. use crate::backend::{ - gpu_add, gpu_download, gpu_gelu_erf, - gpu_layer_norm_mul_add, gpu_linear_f32_resident, gpu_slice_rows, gpu_upload, GpuTensor, + gpu_add, gpu_download, gpu_gelu_erf, gpu_layer_norm_mul_add, gpu_linear_f32_resident, + gpu_slice_rows, gpu_two_way_layer_resident, gpu_upload, GpuTensor, GpuTwoWayAttention, + GpuTwoWayLayer, GpuTwoWayLinear, }; use crate::heads::{DecoderHeads, GpuStepHeads, HostLinear}; use crate::weights::BodyWeights; @@ -290,6 +291,51 @@ pub struct Decoder { init_pose: Vec, init_camera: Vec, tokens: TokenWeights, + /// Set once the backend declined the whole-layer resident call; the + /// per-op path is used from then on. + resident_refused: std::cell::Cell, +} + +impl GpuLinear { + fn two_way_ref(&self) -> GpuTwoWayLinear<'_> { + GpuTwoWayLinear { + weight: &self.weight, + bias: Some(&self.bias), + } + } +} + +impl GpuAttention { + fn two_way_ref(&self) -> GpuTwoWayAttention<'_> { + GpuTwoWayAttention { + q: self.q.two_way_ref(), + k: self.k.two_way_ref(), + v: self.v.two_way_ref(), + out: self.out.two_way_ref(), + } + } +} + +impl DecoderLayer { + fn two_way_ref<'a>(&'a self, norm_final: &'a NormWeights, pe_on_self: bool) -> GpuTwoWayLayer<'a> { + let affine = |n: &'a NormWeights| (n.weight.as_slice(), n.bias.as_slice()); + GpuTwoWayLayer { + ln_pe_1: affine(&self.ln_pe_1), + ln_pe_2: affine(&self.ln_pe_2), + ln1: affine(&self.ln1), + ln2_1: affine(&self.ln2_1), + ln2_2: affine(&self.ln2_2), + ln3: affine(&self.ln3), + ln_final: affine(norm_final), + self_attn: self.self_attn.two_way_ref(), + cross_attn: self.cross_attn.two_way_ref(), + ffn_first: self.ffn_first.two_way_ref(), + ffn_second: self.ffn_second.two_way_ref(), + n_head: DEC_HEADS, + eps: DEC_NORM_EPS, + pe_on_self, + } + } } #[derive(Clone, Debug)] @@ -353,6 +399,7 @@ impl Decoder { init_pose: weights.init_pose, init_camera: weights.init_camera, tokens: weights.tokens, + resident_refused: std::cell::Cell::new(false), }) } @@ -398,34 +445,50 @@ impl Decoder { let t0 = std::time::Instant::now(); let token_pe = gpu_upload(&tokens.token_augment, TOKEN_ROWS, DEC_DIM) .map_err(DiffusionError::model)?; - let token_pe = layer_norm_gpu(&token_pe, &layer.ln_pe_1)?; - let image_pe = layer_norm_gpu(&context_pe, &layer.ln_pe_2)?; - - let normed = layer_norm_gpu(&hidden, &layer.ln1)?; - let self_update = if layer_index == 0 { - layer.self_attn.forward(&normed, &normed, &normed)? + // The whole layer in one backend call when the backend offers it + // (Metal: one command buffer, no host round trips between ops). + let mut resident = None; + if !self.resident_refused.get() { + let layer_ref = layer.two_way_ref(&self.norm_final, layer_index != 0); + match gpu_two_way_layer_resident(&hidden, &token_pe, context, &context_pe, &layer_ref) + { + Ok(pair) => resident = Some(pair), + Err(_) => self.resident_refused.set(true), + } + } + let normed = if let Some((new_hidden, normed)) = resident { + hidden = new_hidden; + normed } else { - let qk = gpu_add(&normed, &token_pe).map_err(DiffusionError::model)?; - layer.self_attn.forward(&qk, &qk, &normed)? + let token_pe = layer_norm_gpu(&token_pe, &layer.ln_pe_1)?; + let image_pe = layer_norm_gpu(&context_pe, &layer.ln_pe_2)?; + + let normed = layer_norm_gpu(&hidden, &layer.ln1)?; + let self_update = if layer_index == 0 { + layer.self_attn.forward(&normed, &normed, &normed)? + } else { + let qk = gpu_add(&normed, &token_pe).map_err(DiffusionError::model)?; + layer.self_attn.forward(&qk, &qk, &normed)? + }; + hidden = gpu_add(&hidden, &self_update).map_err(DiffusionError::model)?; + + let query = layer_norm_gpu(&hidden, &layer.ln2_1)?; + let query = gpu_add(&query, &token_pe).map_err(DiffusionError::model)?; + let context_normed = layer_norm_gpu(context, &layer.ln2_2)?; + let key = gpu_add(&context_normed, &image_pe).map_err(DiffusionError::model)?; + let cross_update = layer + .cross_attn + .forward(&query, &key, &context_normed)?; + hidden = gpu_add(&hidden, &cross_update).map_err(DiffusionError::model)?; + + let normed = layer_norm_gpu(&hidden, &layer.ln3)?; + let ffn = layer.ffn_first.forward(&normed)?; + let ffn = gpu_gelu_erf(&ffn).map_err(DiffusionError::model)?; + let ffn = layer.ffn_second.forward(&ffn)?; + hidden = gpu_add(&hidden, &ffn).map_err(DiffusionError::model)?; + + layer_norm_gpu(&hidden, &self.norm_final)? }; - hidden = gpu_add(&hidden, &self_update).map_err(DiffusionError::model)?; - - let query = layer_norm_gpu(&hidden, &layer.ln2_1)?; - let query = gpu_add(&query, &token_pe).map_err(DiffusionError::model)?; - let context_normed = layer_norm_gpu(context, &layer.ln2_2)?; - let key = gpu_add(&context_normed, &image_pe).map_err(DiffusionError::model)?; - let cross_update = layer - .cross_attn - .forward(&query, &key, &context_normed)?; - hidden = gpu_add(&hidden, &cross_update).map_err(DiffusionError::model)?; - - let normed = layer_norm_gpu(&hidden, &layer.ln3)?; - let ffn = layer.ffn_first.forward(&normed)?; - let ffn = gpu_gelu_erf(&ffn).map_err(DiffusionError::model)?; - let ffn = layer.ffn_second.forward(&ffn)?; - hidden = gpu_add(&hidden, &ffn).map_err(DiffusionError::model)?; - - let normed = layer_norm_gpu(&hidden, &self.norm_final)?; timing.layers_ms += t0.elapsed().as_secs_f32() * 1000.0; let t1 = std::time::Instant::now(); // Only the pose token leaves the GPU mid-loop; the whole block diff --git a/libs/ai/models/common/src/backend.rs b/libs/ai/models/common/src/backend.rs index ad650ed6d..8ae4d5409 100644 --- a/libs/ai/models/common/src/backend.rs +++ b/libs/ai/models/common/src/backend.rs @@ -83,6 +83,7 @@ pub use crate::gpu::{ gpu_rife_scale, gpu_rife_warp, gpu_rope_half, gpu_rope_half_bf16, gpu_rope_interleaved, gpu_silu, gpu_slice_cols, gpu_slice_rows, gpu_vit_backbone_resident, GpuVitLayer, GpuVitLinear, + gpu_two_way_layer_resident, GpuTwoWayAttention, GpuTwoWayLayer, GpuTwoWayLinear, gpu_splat_repo3d_tables, gpu_splat_rope_pairs_per_head, gpu_swiglu_gate_first, gpu_swiglu_value_gate, gpu_to_f16, gpu_upload, gpu_wavenet_gate, gpu_quant_linear_type_supported, diff --git a/libs/ai/models/common/src/gpu.rs b/libs/ai/models/common/src/gpu.rs index 275bdfcc7..f5a91987f 100644 --- a/libs/ai/models/common/src/gpu.rs +++ b/libs/ai/models/common/src/gpu.rs @@ -36,6 +36,59 @@ pub struct GpuVitLayer<'a> { pub down: GpuVitLinear<'a>, } +/// One linear of a device-resident two-way decoder layer: an f32 `[n, k]` +/// weight tensor and an optional `[1, n]` bias, both long-lived. +#[derive(Clone, Copy)] +pub struct GpuTwoWayLinear<'a> { + pub weight: &'a GpuTensor, + pub bias: Option<&'a GpuTensor>, +} + +#[derive(Clone, Copy)] +pub struct GpuTwoWayAttention<'a> { + pub q: GpuTwoWayLinear<'a>, + pub k: GpuTwoWayLinear<'a>, + pub v: GpuTwoWayLinear<'a>, + pub out: GpuTwoWayLinear<'a>, +} + +/// One SAM-style two-way decoder layer: token self-attention (queries and +/// keys carry the token PE when `pe_on_self`), token-to-image +/// cross-attention (query = LN(hidden) + token PE, key = LN(context) + +/// image PE, value = LN(context)), an erf-GELU feed-forward, and `ln_final` +/// on the result. `ln_pe_1`/`ln_pe_2` normalise the two PEs. +#[derive(Clone, Copy)] +pub struct GpuTwoWayLayer<'a> { + pub ln_pe_1: (&'a [f32], &'a [f32]), + pub ln_pe_2: (&'a [f32], &'a [f32]), + pub ln1: (&'a [f32], &'a [f32]), + pub ln2_1: (&'a [f32], &'a [f32]), + pub ln2_2: (&'a [f32], &'a [f32]), + pub ln3: (&'a [f32], &'a [f32]), + pub ln_final: (&'a [f32], &'a [f32]), + pub self_attn: GpuTwoWayAttention<'a>, + pub cross_attn: GpuTwoWayAttention<'a>, + pub ffn_first: GpuTwoWayLinear<'a>, + pub ffn_second: GpuTwoWayLinear<'a>, + pub n_head: usize, + pub eps: f32, + pub pe_on_self: bool, +} + +/// One two-way decoder layer in one backend call, returning +/// `(hidden, ln_final(hidden))`. The Metal tensor backend runs it +/// device-resident; CUDA declines and the caller keeps its per-op path. +#[cfg(all(any(target_os = "linux", target_os = "windows"), makepad_ai_cuda_kernels))] +pub fn gpu_two_way_layer_resident( + _hidden: &GpuTensor, + _token_pe: &GpuTensor, + _context: &GpuTensor, + _context_pe: &GpuTensor, + _layer: &GpuTwoWayLayer<'_>, +) -> Result<(GpuTensor, GpuTensor), String> { + Err("gpu_two_way_layer_resident: CUDA runs the per-op path".to_string()) +} + /// A whole ViT stack in one backend call (see `GpuVitLayer`): the Metal /// tensor backend runs it device-resident in one command buffer; CUDA /// declines (its per-op `gpu_*` path is already resident) and the caller @@ -3330,6 +3383,61 @@ mod imp { } } + pub fn gpu_two_way_layer_resident( + _hidden: &GpuTensor, + _token_pe: &GpuTensor, + _context: &GpuTensor, + _context_pe: &GpuTensor, + _layer: &super::GpuTwoWayLayer<'_>, + ) -> Result<(GpuTensor, GpuTensor), String> { + #[cfg(target_os = "macos")] + { + use makepad_ai_metal::gpu_tensor::{DecAttnRef, DecLinearRef, TwoWayLayerRef}; + fn lin<'a>(l: &super::GpuTwoWayLinear<'a>) -> DecLinearRef<'a> { + DecLinearRef { + weight: l.weight, + bias: l.bias, + } + } + fn attn<'a>(a: &super::GpuTwoWayAttention<'a>) -> DecAttnRef<'a> { + DecAttnRef { + q: lin(&a.q), + k: lin(&a.k), + v: lin(&a.v), + out: lin(&a.out), + } + } + let l = _layer; + let layer = TwoWayLayerRef { + ln_pe_1: l.ln_pe_1, + ln_pe_2: l.ln_pe_2, + ln1: l.ln1, + ln2_1: l.ln2_1, + ln2_2: l.ln2_2, + ln3: l.ln3, + ln_final: l.ln_final, + self_attn: attn(&l.self_attn), + cross_attn: attn(&l.cross_attn), + ffn_first: lin(&l.ffn_first), + ffn_second: lin(&l.ffn_second), + n_head: l.n_head, + eps: l.eps, + pe_on_self: l.pe_on_self, + }; + return makepad_ai_metal::gpu_tensor::two_way_layer_resident( + _hidden, + _token_pe, + _context, + _context_pe, + &layer, + ); + } + #[cfg(not(target_os = "macos"))] + { + Err(GPU_UNAVAILABLE.to_string()) + } + } + pub fn gpu_add_cols_broadcast(_x: &GpuTensor, _bias: &GpuTensor) -> Result { #[cfg(target_os = "macos")] { From 0e94bbac425482b9b43fff10d878fec468adece4 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 01:23:58 +0200 Subject: [PATCH 038/417] game brief: rivers, highways, junctions and gates are one call Co-Authored-By: Claude Fable 5.1 --- libs/asset/chat/context/game.md | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/libs/asset/chat/context/game.md b/libs/asset/chat/context/game.md index db2747243..c13420c88 100644 --- a/libs/asset/chat/context/game.md +++ b/libs/asset/chat/context/game.md @@ -87,8 +87,22 @@ never hand-place their tiles. They are deterministic from seed: road surfaces — asphalt with markings, graded over the hills with the ground pressed to match, and a real BRIDGE with piers over anything too deep to embank. Paths are waypoint lists in world metres: EDIT a road by - moving its waypoints and re-calling. Where a road crosses a railway a - LEVEL CROSSING is generated automatically. + moving its waypoints and re-calling. CROSSINGS ARE AUTOMATIC — never + build junction geometry by hand: road x rail = a level crossing with + warning masts and BARRIER GATES that close for approaching trains; road + x road = a junction patch with stop lines and WORKING STOPLIGHTS + (deterministic cycle; autodriven cars brake at red and at closed gates, + so town traffic just works). `style: "highway"` lays a dual carriageway + (median barrier, guard rails, gentler grades) that GRADE-SEPARATES: + crossing any other road or rail becomes an OVERPASS on piers instead of + a flat junction. +- `game.river({seed | path: [vec3,...], width, depth})` — ONE CALL CARVES + A RIVER: the channel is cut into the terrain along a spline (banks + feathered and recoloured), chained water volumes follow it (things + float, boats drive), and the river is REGISTERED: any road or rail laid + AFTER it crosses on a BRIDGE automatically — deck clearing the water, + piers standing in the shallows. Call game.river BEFORE the roads and + railways that must bridge it; never ford a river with a flat road. - `game.racetrack({seed, size, complexity})` — a complete circuit as one generated road surface (true swept corners, graded, bridged) — returns slots, checkpoints, start and waypoints. A race's essential shape is: @@ -295,10 +309,14 @@ EXPLICITLY asks to build something from parts. lamp at `scale: 8` is a 30 m tower. Never place kit models unscaled next to people. STREETS ARE NEVER HAND-LAID: city and village streets come from - game.city / game.village (measured kit tiles at their true scale); - open roads, circuits and railways come from game.road_network / - game.racetrack / game.traintrack, which GENERATE the surface (a - hand-laid road tile next to a real car is 2-3x too narrow). + game.city / game.village, which now GENERATE their street surfaces + through the same corridor machinery as the open roads — graded over + hills, pressed into the ground, junction patches and stoplights where + they cross; open roads, circuits and railways come from + game.road_network / game.racetrack / game.traintrack, which GENERATE + the surface (a hand-laid road tile next to a real car is 2-3x too + narrow). Generated surfaces are SOLID: characters walk on the deck, + cars queue at red lights and closed crossing gates on their own. - Layout = a real village: game.village lays the street; 4-6 DIFFERENT complete buildings on both sides facing the street (doors toward it), a small plaza (fantasy-town fountain-round, scale: 2) with trees and a From c9e6d88bf135b3978eaa55a45e97fbafe64a0427 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 01:26:21 +0200 Subject: [PATCH 039/417] =?UTF-8?q?ai-body:=20the=20hands=20pass=20?= =?UTF-8?q?=E2=80=94=20hand=20crops,=20the=20hand=20decoder,=20the=20hand-?= =?UTF-8?q?mode=20rig=20and=20the=20wrist=20fusion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BodyModel::infer_full runs the reference's full mode natively: the body pass's hand boxes become two 512 crops (the left one cut from the mirrored image, padding 0.9), each goes through the backbone, its own ray conditioning and the hand decoder (the body decoder with the *_hand tensors), the hand-mode rig pre-transform (local_to_world_wrist, wrist and root offsets, non-hand parameters zeroed) and the hand camera head's scale factor of 10; the left result is un-mirrored. The fusion gates each hand (wrist angle, box size, keypoint spread, wrist distance), re-prompts the body decoder with the trusted wrists and elbows as point prompts (the decoder now takes N prompt tokens and a previous estimate), and writes the fused wrist angles, hand parameters and hand scale/shape back before the final rig pass. pose.rs gains the roma xyz (extrinsic) and XZY (intrinsic) euler pairs; mhr.rs returns joint global rotations. Oracle parity on both full-mode fixtures: every hand-decoder stage per step (tokens 7e-3, heads 4e-4, rig params 1e-4), fusion reports as the reference (one hand trusted on the standing photo, both on the crop), and end to end kp3d 1.6 mm / kp2d 0.85 px. 36 tests. Co-Authored-By: Claude Fable 5.1 --- libs/ai/models/body/THIRD_PARTY_NOTICES.md | 4 +- libs/ai/models/body/src/condition.rs | 10 +- libs/ai/models/body/src/decoder.rs | 355 +++++++- libs/ai/models/body/src/fixture.rs | 38 +- libs/ai/models/body/src/hands.rs | 973 +++++++++++++++++++++ libs/ai/models/body/src/heads.rs | 29 +- libs/ai/models/body/src/lib.rs | 1 + libs/ai/models/body/src/mhr.rs | 59 ++ libs/ai/models/body/src/model.rs | 278 +++++- libs/ai/models/body/src/pose.rs | 83 +- libs/ai/models/body/src/preprocess.rs | 25 +- 11 files changed, 1766 insertions(+), 89 deletions(-) create mode 100644 libs/ai/models/body/src/hands.rs diff --git a/libs/ai/models/body/THIRD_PARTY_NOTICES.md b/libs/ai/models/body/THIRD_PARTY_NOTICES.md index 189a54bf7..b87ad2495 100644 --- a/libs/ai/models/body/THIRD_PARTY_NOTICES.md +++ b/libs/ai/models/body/THIRD_PARTY_NOTICES.md @@ -80,4 +80,6 @@ The port reproduces the reference pipeline's numerics for the body decoder path (`inference_type = "body"`): rig vertices within 1e-4 cm, keypoints within 1e-6 m from identical rig parameters, and end to end from an image within 2 mm on 3D keypoints and 0.5 px on 2D keypoints, the residue being -bf16 accumulation-order noise in the backbone. +bf16 accumulation-order noise in the backbone. The full path +(`inference_type = "full"`: both hand crops, the hand decoder, the wrist +fusion and the keypoint re-prompt) matches end to end within 2 mm and 1 px. diff --git a/libs/ai/models/body/src/condition.rs b/libs/ai/models/body/src/condition.rs index b775ea11b..b28a3ce0e 100644 --- a/libs/ai/models/body/src/condition.rs +++ b/libs/ai/models/body/src/condition.rs @@ -68,8 +68,12 @@ pub struct RayCond { impl RayCond { pub fn prepare(weights: &BodyWeights) -> Result { + Self::prepare_named(weights, "ray_cond_emb") + } + + pub fn prepare_named(weights: &BodyWeights, prefix: &str) -> Result { let conv = weights.f32_shaped( - "ray_cond_emb.conv.weight", + &format!("{prefix}.conv.weight"), &[DINO_DIM, DINO_DIM + RAY_FEATURES, 1, 1], )?; let cols = DINO_DIM + RAY_FEATURES; @@ -85,8 +89,8 @@ impl RayCond { image_w: gpu_upload(&image_w, DINO_DIM, DINO_DIM).map_err(DiffusionError::model)?, ray_w: gpu_upload(&ray_w, DINO_DIM, RAY_FEATURES).map_err(DiffusionError::model)?, image_w_host: image_w, - norm_w: weights.f32_shaped("ray_cond_emb.norm.weight", &[DINO_DIM])?, - norm_b: weights.f32_shaped("ray_cond_emb.norm.bias", &[DINO_DIM])?, + norm_w: weights.f32_shaped(&format!("{prefix}.norm.weight"), &[DINO_DIM])?, + norm_b: weights.f32_shaped(&format!("{prefix}.norm.bias"), &[DINO_DIM])?, }) } diff --git a/libs/ai/models/body/src/decoder.rs b/libs/ai/models/body/src/decoder.rs index 713a0e9c6..112bb8567 100644 --- a/libs/ai/models/body/src/decoder.rs +++ b/libs/ai/models/body/src/decoder.rs @@ -12,10 +12,63 @@ use crate::{ NPOSE, NUM_KEYPOINTS, DiffusionError, Result, }; +/// The legacy one-dummy-prompt row count. Actual runs derive their row count +/// from the prompt list (`144 + N`). pub const TOKEN_ROWS: usize = 5 + 2 * NUM_KEYPOINTS; +const BASE_TOKEN_ROWS: usize = 4 + 2 * NUM_KEYPOINTS; +#[cfg(test)] const KEYPOINT_ROW: usize = 5; +#[cfg(test)] const KEYPOINT3D_ROW: usize = KEYPOINT_ROW + NUM_KEYPOINTS; +#[derive(Clone, Copy)] +pub struct DecoderNames { + pub decoder: &'static str, + pub pose_head: &'static str, + pub camera_head: &'static str, + pub init_pose: &'static str, + pub init_camera: &'static str, + pub init_to_token: &'static str, + pub prev_to_token: &'static str, + pub keypoint_embedding: &'static str, + pub keypoint3d_embedding: &'static str, + pub keypoint_posemb: &'static str, + pub keypoint3d_posemb: &'static str, + pub keypoint_feat: &'static str, +} + +impl DecoderNames { + pub const BODY: Self = Self { + decoder: "decoder", + pose_head: "head_pose.proj", + camera_head: "head_camera.proj", + init_pose: "init_pose.weight", + init_camera: "init_camera.weight", + init_to_token: "init_to_token_mhr", + prev_to_token: "prev_to_token_mhr", + keypoint_embedding: "keypoint_embedding.weight", + keypoint3d_embedding: "keypoint3d_embedding.weight", + keypoint_posemb: "keypoint_posemb_linear", + keypoint3d_posemb: "keypoint3d_posemb_linear", + keypoint_feat: "keypoint_feat_linear", + }; + + pub const HAND: Self = Self { + decoder: "decoder_hand", + pose_head: "head_pose_hand.proj", + camera_head: "head_camera_hand.proj", + init_pose: "init_pose_hand.weight", + init_camera: "init_camera_hand.weight", + init_to_token: "init_to_token_mhr_hand", + prev_to_token: "prev_to_token_mhr_hand", + keypoint_embedding: "keypoint_embedding_hand.weight", + keypoint3d_embedding: "keypoint3d_embedding_hand.weight", + keypoint_posemb: "keypoint_posemb_linear_hand", + keypoint3d_posemb: "keypoint3d_posemb_linear_hand", + keypoint_feat: "keypoint_feat_linear_hand", + }; +} + #[derive(Clone)] struct NormWeights { weight: Vec, @@ -86,6 +139,8 @@ struct TokenWeights { prev_to_token: HostLinear, prompt_to_token: HostLinear, invalid_point_embed: Vec, + point_pe: Vec, + point_embeddings: Vec, hand_box_embedding: Vec, keypoint_embedding: Vec, keypoint3d_embedding: Vec, @@ -105,9 +160,13 @@ pub struct DecoderWeights { impl DecoderWeights { pub fn load(weights: &BodyWeights) -> Result { + Self::load_named(weights, DecoderNames::BODY) + } + + pub fn load_named(weights: &BodyWeights, names: DecoderNames) -> Result { let mut layers = Vec::with_capacity(DEC_DEPTH); for index in 0..DEC_DEPTH { - let prefix = format!("decoder.layers.{index}"); + let prefix = format!("{}.layers.{index}", names.decoder); layers.push(DecoderLayerWeights { ln_pe_1: NormWeights::load(weights, &format!("{prefix}.ln_pe_1"), DEC_DIM)?, ln_pe_2: NormWeights::load(weights, &format!("{prefix}.ln_pe_2"), DINO_DIM)?, @@ -145,20 +204,31 @@ impl DecoderWeights { } Ok(Self { layers, - norm_final: NormWeights::load(weights, "decoder.norm_final", DEC_DIM)?, - heads: DecoderHeads::load(weights)?, - init_pose: weights.f32_shaped("init_pose.weight", &[1, NPOSE])?, - init_camera: weights.f32_shaped("init_camera.weight", &[1, NCAM])?, + norm_final: NormWeights::load( + weights, + &format!("{}.norm_final", names.decoder), + DEC_DIM, + )?, + heads: DecoderHeads::load_named( + weights, + names.pose_head, + names.camera_head, + names.keypoint_posemb, + names.keypoint3d_posemb, + names.keypoint_feat, + )?, + init_pose: weights.f32_shaped(names.init_pose, &[1, NPOSE])?, + init_camera: weights.f32_shaped(names.init_camera, &[1, NCAM])?, tokens: TokenWeights { init_to_token: HostLinear::load( weights, - "init_to_token_mhr", + names.init_to_token, DEC_DIM, NPOSE + NCAM + 3, )?, prev_to_token: HostLinear::load( weights, - "prev_to_token_mhr", + names.prev_to_token, DEC_DIM, NPOSE + NCAM, )?, @@ -172,12 +242,27 @@ impl DecoderWeights { "prompt_encoder.invalid_point_embed.weight", &[1, DINO_DIM], )?, + point_pe: weights.f32_shaped( + "prompt_encoder.pe_layer.positional_encoding_gaussian_matrix", + &[2, DINO_DIM / 2], + )?, + point_embeddings: (0..NUM_KEYPOINTS) + .map(|label| { + weights.f32_shaped( + &format!("prompt_encoder.point_embeddings.{label}.weight"), + &[1, DINO_DIM], + ) + }) + .collect::>>()? + .into_iter() + .flatten() + .collect(), hand_box_embedding: weights .f32_shaped("hand_box_embedding.weight", &[2, DEC_DIM])?, keypoint_embedding: weights - .f32_shaped("keypoint_embedding.weight", &[NUM_KEYPOINTS, DEC_DIM])?, + .f32_shaped(names.keypoint_embedding, &[NUM_KEYPOINTS, DEC_DIM])?, keypoint3d_embedding: weights - .f32_shaped("keypoint3d_embedding.weight", &[NUM_KEYPOINTS, DEC_DIM])?, + .f32_shaped(names.keypoint3d_embedding, &[NUM_KEYPOINTS, DEC_DIM])?, }, }) } @@ -344,6 +429,32 @@ pub struct TokenSet { pub token_augment: Vec, } +impl TokenSet { + pub fn rows(&self) -> usize { + self.tokens.len() / DEC_DIM + } + + fn prompt_count(&self) -> usize { + self.rows() - BASE_TOKEN_ROWS + } + + fn hand_box_row(&self) -> usize { + 2 + self.prompt_count() + } + + fn keypoint_row(&self) -> usize { + 4 + self.prompt_count() + } +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct PointPrompt { + /// Point coordinates in the body crop, normalised to `[0, 1]`. + pub point: [f32; 2], + /// One of the 70 keypoint labels. + pub label: usize, +} + #[derive(Clone, Debug)] pub struct StepInput { pub layer: usize, @@ -385,6 +496,10 @@ impl Decoder { Self::from_weights(DecoderWeights::load(weights)?) } + pub fn load_named(weights: &BodyWeights, names: DecoderNames) -> Result { + Self::from_weights(DecoderWeights::load_named(weights, names)?) + } + fn from_weights(weights: DecoderWeights) -> Result { let mut layers = Vec::with_capacity(DEC_DEPTH); for layer in weights.layers { @@ -407,6 +522,33 @@ impl Decoder { build_tokens(&self.tokens, &self.init_pose, &self.init_camera, condition_info) } + pub fn run_with_prompts( + &self, + condition_info: [f32; 3], + prompts: &[PointPrompt], + prev_estimate: &[f32], + context: &GpuTensor, + context_pe: &[f32], + step: impl FnMut(StepInput) -> StepFeedback, + ) -> Result { + if prev_estimate.len() != NPOSE + NCAM { + return Err(DiffusionError::workflow(format!( + "decoder previous estimate has {} values, expected {}", + prev_estimate.len(), + NPOSE + NCAM, + ))); + } + let tokens = build_prompted_tokens( + &self.tokens, + &self.init_pose, + &self.init_camera, + condition_info, + prompts, + prev_estimate, + )?; + self.run(tokens, context, context_pe, step) + } + pub fn run( &self, tokens: TokenSet, @@ -417,6 +559,23 @@ impl Decoder { self.run_impl(tokens, context, context_pe, step, None) } + #[cfg(test)] + pub(crate) fn run_traced( + &self, + tokens: TokenSet, + context: &GpuTensor, + context_pe: &[f32], + step: impl FnMut(StepInput) -> StepFeedback, + trace: &mut dyn FnMut(usize, &GpuTensor, &[f32]) -> Result<()>, + ) -> Result { + self.run_impl(tokens, context, context_pe, step, Some(trace)) + } + + #[cfg(test)] + pub(crate) fn init_pose(&self) -> &[f32] { + &self.init_pose + } + fn run_impl( &self, mut tokens: TokenSet, @@ -434,7 +593,10 @@ impl Decoder { let context_host = gpu_download(context).map_err(DiffusionError::model)?; let context_pe = gpu_upload(context_pe, context_rows, DINO_DIM) .map_err(DiffusionError::model)?; - let mut hidden = gpu_upload(&tokens.tokens, TOKEN_ROWS, DEC_DIM) + let token_rows = tokens.rows(); + let keypoint_row = tokens.keypoint_row(); + let hand_box_row = tokens.hand_box_row(); + let mut hidden = gpu_upload(&tokens.tokens, token_rows, DEC_DIM) .map_err(DiffusionError::model)?; let mut final_normed = Vec::new(); let mut last_pose = Vec::new(); @@ -443,7 +605,7 @@ impl Decoder { for (layer_index, layer) in self.layers.iter().enumerate() { let t0 = std::time::Instant::now(); - let token_pe = gpu_upload(&tokens.token_augment, TOKEN_ROWS, DEC_DIM) + let token_pe = gpu_upload(&tokens.token_augment, token_rows, DEC_DIM) .map_err(DiffusionError::model)?; // The whole layer in one backend call when the backend offers it // (Metal: one command buffer, no host round trips between ops). @@ -526,9 +688,11 @@ impl Decoder { &mut tokens.token_augment, &context_host, grid_side, + token_rows, + keypoint_row, feedback, )?; - let delta = gpu_upload(&delta, TOKEN_ROWS, DEC_DIM) + let delta = gpu_upload(&delta, token_rows, DEC_DIM) .map_err(DiffusionError::model)?; hidden = gpu_add(&hidden, &delta).map_err(DiffusionError::model)?; timing.refine_ms += t3.elapsed().as_secs_f32() * 1000.0; @@ -538,7 +702,8 @@ impl Decoder { let mut hand_boxes = [[0.0; 4]; 2]; let mut hand_logits = [[0.0; 2]; 2]; for hand in 0..2 { - let row = &final_normed[(3 + hand) * DEC_DIM..(4 + hand) * DEC_DIM]; + let row = &final_normed + [(hand_box_row + hand) * DEC_DIM..(hand_box_row + hand + 1) * DEC_DIM]; hand_boxes[hand] = self.heads.bbox(row); hand_logits[hand] = self.heads.hand_logits(row); } @@ -557,6 +722,8 @@ impl Decoder { token_augment: &mut [f32], context: &[f32], grid_side: usize, + token_rows: usize, + keypoint_row: usize, feedback: StepFeedback, ) -> Result> { if feedback.kp2d_cropped.len() != NUM_KEYPOINTS * 2 @@ -617,9 +784,10 @@ impl Decoder { } let posemb3d = self.step_heads.keypoint3d_posemb(¢ered)?; - let mut delta = vec![0.0f32; TOKEN_ROWS * DEC_DIM]; + let keypoint3d_row = keypoint_row + NUM_KEYPOINTS; + let mut delta = vec![0.0f32; token_rows * DEC_DIM]; for index in 0..NUM_KEYPOINTS { - let row2d = (KEYPOINT_ROW + index) * DEC_DIM; + let row2d = (keypoint_row + index) * DEC_DIM; if valid[index] { token_augment[row2d..row2d + DEC_DIM] .copy_from_slice(&posemb[index * DEC_DIM..(index + 1) * DEC_DIM]); @@ -628,7 +796,7 @@ impl Decoder { } else { token_augment[row2d..row2d + DEC_DIM].fill(0.0); } - let row3d = (KEYPOINT3D_ROW + index) * DEC_DIM; + let row3d = (keypoint3d_row + index) * DEC_DIM; token_augment[row3d..row3d + DEC_DIM] .copy_from_slice(&posemb3d[index * DEC_DIM..(index + 1) * DEC_DIM]); } @@ -641,6 +809,70 @@ fn build_tokens( init_pose: &[f32], init_camera: &[f32], condition_info: [f32; 3], +) -> TokenSet { + let previous_input: Vec = init_pose.iter().chain(init_camera).copied().collect(); + build_token_rows( + weights, + init_pose, + init_camera, + condition_info, + vec![weights + .prompt_to_token + .forward_row(&weights.invalid_point_embed)], + &previous_input, + ) +} + +fn build_prompted_tokens( + weights: &TokenWeights, + init_pose: &[f32], + init_camera: &[f32], + condition_info: [f32; 3], + prompts: &[PointPrompt], + previous_input: &[f32], +) -> Result { + let mut prompt_tokens = Vec::with_capacity(prompts.len()); + for prompt in prompts { + if prompt.label >= NUM_KEYPOINTS { + return Err(DiffusionError::workflow(format!( + "decoder prompt label {} is outside 0..{}", + prompt.label, NUM_KEYPOINTS, + ))); + } + let mut embedding = vec![0.0f32; DINO_DIM]; + let x = 2.0 * prompt.point[0] - 1.0; + let y = 2.0 * prompt.point[1] - 1.0; + for k in 0..DINO_DIM / 2 { + let angle = 2.0 + * std::f32::consts::PI + * (x * weights.point_pe[k] + y * weights.point_pe[DINO_DIM / 2 + k]); + embedding[k] = angle.sin(); + embedding[DINO_DIM / 2 + k] = angle.cos(); + } + let label = &weights.point_embeddings + [prompt.label * DINO_DIM..(prompt.label + 1) * DINO_DIM]; + for (value, label) in embedding.iter_mut().zip(label) { + *value += label; + } + prompt_tokens.push(weights.prompt_to_token.forward_row(&embedding)); + } + Ok(build_token_rows( + weights, + init_pose, + init_camera, + condition_info, + prompt_tokens, + previous_input, + )) +} + +fn build_token_rows( + weights: &TokenWeights, + init_pose: &[f32], + init_camera: &[f32], + condition_info: [f32; 3], + prompt_tokens: Vec>, + previous_input: &[f32], ) -> TokenSet { let mut init_input = Vec::with_capacity(3 + NPOSE + NCAM); init_input.extend_from_slice(&condition_info); @@ -648,26 +880,26 @@ fn build_tokens( init_input.extend_from_slice(init_camera); let pose_token = weights.init_to_token.forward_row(&init_input); - let mut previous_input = Vec::with_capacity(NPOSE + NCAM); - previous_input.extend_from_slice(init_pose); - previous_input.extend_from_slice(init_camera); - let previous_token = weights.prev_to_token.forward_row(&previous_input); - let prompt_token = weights - .prompt_to_token - .forward_row(&weights.invalid_point_embed); + let previous_token = weights.prev_to_token.forward_row(previous_input); + let rows = BASE_TOKEN_ROWS + prompt_tokens.len(); - let mut tokens = Vec::with_capacity(TOKEN_ROWS * DEC_DIM); + let mut tokens = Vec::with_capacity(rows * DEC_DIM); tokens.extend_from_slice(&pose_token); tokens.extend_from_slice(&previous_token); - tokens.extend_from_slice(&prompt_token); + for prompt in &prompt_tokens { + tokens.extend_from_slice(prompt); + } tokens.extend_from_slice(&weights.hand_box_embedding); tokens.extend_from_slice(&weights.keypoint_embedding); tokens.extend_from_slice(&weights.keypoint3d_embedding); - debug_assert_eq!(tokens.len(), TOKEN_ROWS * DEC_DIM); + debug_assert_eq!(tokens.len(), rows * DEC_DIM); - let mut token_augment = vec![0.0f32; TOKEN_ROWS * DEC_DIM]; + let mut token_augment = vec![0.0f32; rows * DEC_DIM]; token_augment[DEC_DIM..2 * DEC_DIM].copy_from_slice(&previous_token); - token_augment[2 * DEC_DIM..3 * DEC_DIM].copy_from_slice(&prompt_token); + for (index, prompt) in prompt_tokens.iter().enumerate() { + let row = 2 + index; + token_augment[row * DEC_DIM..(row + 1) * DEC_DIM].copy_from_slice(prompt); + } TokenSet { tokens, token_augment, @@ -675,14 +907,16 @@ fn build_tokens( } fn validate_run_inputs(tokens: &TokenSet, context: &GpuTensor, context_pe: &[f32]) -> Result<()> { - if tokens.tokens.len() != TOKEN_ROWS * DEC_DIM - || tokens.token_augment.len() != TOKEN_ROWS * DEC_DIM + let rows = tokens.rows(); + if rows < BASE_TOKEN_ROWS + || tokens.tokens.len() != rows * DEC_DIM + || tokens.token_augment.len() != rows * DEC_DIM { return Err(DiffusionError::workflow(format!( - "decoder token shapes are {} and {}, expected {}", + "decoder token shapes are {} and {}, expected matching (144 + N) x {}", tokens.tokens.len(), tokens.token_augment.len(), - TOKEN_ROWS * DEC_DIM, + DEC_DIM, ))); } let rows = context.rows(); @@ -824,6 +1058,8 @@ mod tests { prev_to_token: HostLinear::constant(NPOSE + NCAM, previous.clone()), prompt_to_token: HostLinear::constant(DINO_DIM, prompt.clone()), invalid_point_embed: vec![0.0; DINO_DIM], + point_pe: vec![0.0; DINO_DIM], + point_embeddings: vec![0.0; NUM_KEYPOINTS * DINO_DIM], hand_box_embedding: hand.clone(), keypoint_embedding: keypoint.clone(), keypoint3d_embedding: keypoint3d.clone(), @@ -984,6 +1220,61 @@ mod tests { ); } + #[test] + fn fixture_reprompt_token_assembly_and_shifted_rows() { + use crate::fixture::OracleRoot; + if fixture::oracle_dir_for(OracleRoot::Full).is_none() { + eprintln!("SKIP fixture_reprompt_token_assembly: oracle_full absent"); + return; + } + let Some(weights) = fixture_weights() else { + return; + }; + let weights = DecoderWeights::load(&weights).expect("load decoder weights"); + let condition = fixture::load_from(OracleRoot::Full, "condition_info_0") + .expect("condition_info_0") + .1; + let prompt_values = fixture::load_from(OracleRoot::Full, "keypoint_prompt") + .expect("keypoint_prompt") + .1; + let prompts: Vec = prompt_values + .chunks_exact(3) + .map(|row| PointPrompt { + point: [row[0], row[1]], + label: row[2] as usize, + }) + .collect(); + let previous = fixture::load_from(OracleRoot::Full, "prev_to_token_in_1") + .expect("prev_to_token_in_1") + .1; + let tokens = build_prompted_tokens( + &weights.tokens, + &weights.init_pose, + &weights.init_camera, + [condition[0], condition[1], condition[2]], + &prompts, + &previous, + ) + .expect("build prompted tokens"); + assert_eq!(tokens.rows(), BASE_TOKEN_ROWS + prompts.len()); + assert_close( + "decoder_tokens_in_1", + &tokens.tokens, + &fixture::load_from(OracleRoot::Full, "decoder_tokens_in_1") + .unwrap() + .1, + 1.0e-4, + ); + assert_close( + "decoder_token_augment_in_1", + &tokens.token_augment, + &fixture::load_from(OracleRoot::Full, "decoder_token_augment_in_1") + .unwrap() + .1, + 1.0e-4, + ); + } + #[test] fn fixture_host_heads_and_refinement_ffns() { if fixture::oracle_dir().is_none() { diff --git a/libs/ai/models/body/src/fixture.rs b/libs/ai/models/body/src/fixture.rs index 2b86fbfe4..b096ca39f 100644 --- a/libs/ai/models/body/src/fixture.rs +++ b/libs/ai/models/body/src/fixture.rs @@ -5,17 +5,45 @@ use std::path::{Path, PathBuf}; use crate::mhr::MhrRig; use crate::weights::BodyWeights; +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum OracleRoot { + Body, + Full, + Hands, +} + +impl OracleRoot { + fn directory(self) -> &'static str { + match self { + Self::Body => "oracle", + Self::Full => "oracle_full", + Self::Hands => "oracle_hands", + } + } +} + pub fn oracle_dir() -> Option { + oracle_dir_for(OracleRoot::Body) +} + +pub fn oracle_dir_for(root: OracleRoot) -> Option { Path::new(env!("CARGO_MANIFEST_DIR")) .ancestors() - .map(|root| root.join("local/agent_state/sam3dbody/oracle")) + .map(|base| { + base.join("local/agent_state/sam3dbody") + .join(root.directory()) + }) .find(|candidate| candidate.is_dir()) } /// Load `.f32` (or `.u8`, widened) and its shape from the /// oracle manifest. pub fn load(name: &str) -> Option<(Vec, Vec)> { - let root = oracle_dir()?; + load_from(OracleRoot::Body, name) +} + +pub fn load_from(root: OracleRoot, name: &str) -> Option<(Vec, Vec)> { + let root = oracle_dir_for(root)?; let manifest = std::fs::read_to_string(root.join("manifest.json")).ok()?; let shape = manifest_shape(&manifest, name)?; let f32_path = root.join(format!("{name}.f32")); @@ -42,7 +70,11 @@ pub fn load(name: &str) -> Option<(Vec, Vec)> { } pub fn weights_path() -> Option { - let root = oracle_dir()?; + weights_path_from(OracleRoot::Body) +} + +pub fn weights_path_from(selected: OracleRoot) -> Option { + let root = oracle_dir_for(selected)?; let value = std::fs::read_to_string(root.join("weights_path.txt")).ok()?; let path = PathBuf::from(value.trim()); let path = if path.is_absolute() { path } else { root.join(path) }; diff --git a/libs/ai/models/body/src/hands.rs b/libs/ai/models/body/src/hands.rs new file mode 100644 index 000000000..a9be863d4 --- /dev/null +++ b/libs/ai/models/body/src/hands.rs @@ -0,0 +1,973 @@ +//! Full-mode hand crops, the right-hand-canonical hand decoder, and wrist +//! fusion back into the body estimate. + +use crate::backend::GpuTensor; +use crate::condition::{dense_pe, ray_features, RayCond}; +use crate::decoder::{Decoder, DecoderNames, PointPrompt, StepFeedback, StepInput}; +use crate::model::{close_the_loop, BodyModel, BodyOutput}; +use crate::pose::{ + camera_translation_scaled, euler_xzy_to_matrix, euler_xyz_to_matrix, matrix_mul, + matrix_to_euler_xzy, matrix_to_euler_xyz, matrix_transpose, model_params, project, + unpack_pose, PoseHeadParams, +}; +use crate::preprocess::{ + condition_info, crop_geometry_at, crop_normalized_mirrored, full_to_crop, patch_rays, + CropGeometry, +}; +use crate::weights::BodyWeights; +use crate::{ + DiffusionError, Result, DINO_DIM, IMAGE_SIZE, MHR_JOINTS, MHR_VERTS, NUM_KEYPOINTS, +}; + +const LEFT: usize = 0; +const RIGHT: usize = 1; +const LOWARM: [usize; 2] = [76, 40]; +const WRIST_TWIST: [usize; 2] = [77, 41]; +const WRIST: [usize; 2] = [78, 42]; +const WRIST_POSE: [[usize; 3]; 2] = [[41, 43, 42], [31, 33, 32]]; + +pub type HandOutput = BodyOutput; + +#[derive(Clone, Copy, Debug)] +pub struct BodyImage<'a> { + pub rgb: &'a [u8], + pub width: usize, + pub height: usize, +} + +/// The hand camera head's `default_scale_factor` (the reference config's +/// `DEFAULT_SCALE_FACTOR_HAND`): it multiplies the box size inside the +/// CLIFF translation. Pinned by the oracle: the origin keypoint's crop +/// position at step 0 solves to exactly 10. +const HAND_CAMERA_SCALE_FACTOR: f32 = 10.0; + +#[derive(Clone, Debug)] +pub struct HandCrop { + /// The oracle's `batch_img_N`: planar RGB after warp, scaled to `[0, 1]`. + pub rgb01: Vec, + /// ImageNet-normalised planar RGB consumed by DINO. + pub normalized: Vec, + /// Box in the original, unmirrored full image. + pub box_xyxy: [f32; 4], + /// Box and crop geometry in the image actually sampled by the decoder. + pub sample_box_xyxy: [f32; 4], + pub geometry: CropGeometry, + pub mirror: bool, + pub image_width: usize, + pub image_height: usize, +} + +#[derive(Clone, Debug, Default)] +pub struct FusionReport { + pub angle_difference: [f32; 2], + pub wrist_distance: [f32; 2], + pub valid_angle: [bool; 2], + pub hand_valid: [bool; 2], + pub fused: [bool; 2], + pub prompt_count: usize, +} + +pub struct HandBranch { + ray_cond: RayCond, + decoder: Decoder, + dense_pe: Vec, + local_to_world_wrist: [[f32; 3]; 3], + right_wrist_coords: [f32; 3], + root_coords: [f32; 3], + nonhand_param_idxs: Vec, + joint_rotation: Vec, + scale_mean: Vec, + scale_comps: Vec, +} + +impl HandBranch { + pub fn load(weights: &BodyWeights) -> Result { + let matrix = weights.f32_shaped( + "hand_pe_layer.positional_encoding_gaussian_matrix", + &[2, DINO_DIM / 2], + )?; + let hand_name = |suffix: &str| { + let hand = format!("head_pose_hand.{suffix}"); + if weights.has(&hand) { + hand + } else { + format!("head_pose.{suffix}") + } + }; + let local = weights.f32_shaped(&hand_name("local_to_world_wrist"), &[3, 3])?; + let right_wrist = weights.f32_shaped(&hand_name("right_wrist_coords"), &[3])?; + let root = weights.f32_shaped(&hand_name("root_coords"), &[3])?; + let nonhand = weights.i64_shaped(&hand_name("nonhand_param_idxs"), &[145])?; + let nonhand_param_idxs = nonhand + .into_iter() + .map(|value| { + usize::try_from(value).map_err(|_| { + DiffusionError::model(format!( + "head_pose_hand.nonhand_param_idxs contains {value}" + )) + }) + }) + .collect::>>()?; + Ok(Self { + ray_cond: RayCond::prepare_named(weights, "ray_cond_emb_hand")?, + decoder: Decoder::load_named(weights, DecoderNames::HAND)?, + dense_pe: dense_pe(&matrix), + local_to_world_wrist: [ + local[0..3].try_into().unwrap(), + local[3..6].try_into().unwrap(), + local[6..9].try_into().unwrap(), + ], + right_wrist_coords: right_wrist.try_into().unwrap(), + root_coords: root.try_into().unwrap(), + nonhand_param_idxs, + joint_rotation: weights.f32_shaped( + "head_pose.joint_rotation", + &[MHR_JOINTS, 3, 3], + )?, + scale_mean: weights.f32_shaped("head_pose.scale_mean", &[68])?, + scale_comps: weights.f32_shaped("head_pose.scale_comps", &[28, 68])?, + }) + } + + pub fn infer_hand(&self, model: &BodyModel, crop: &HandCrop) -> Result { + let embeddings = model.dino.forward_normalized(&crop.normalized)?; + let features = ray_features(&patch_rays(&crop.geometry)); + let context = self + .ray_cond + .apply(&embeddings, &model.no_mask_embed, &features)?; + let tokens = self.decoder.build_tokens(condition_info(&crop.geometry)); + let mut last = None; + let output = self.decoder.run(tokens, &context, &self.dense_pe, |step| { + let correctives = model.correctives_every_step || step.layer + 1 == crate::DEC_DEPTH; + let result = self.close_hand_loop(model, crop, &step, correctives); + let feedback = StepFeedback { + kp2d_cropped: result.pred_keypoints_2d_cropped.clone(), + depth: result.pred_keypoints_2d_depth.clone(), + kp3d: result.pred_keypoints_3d.clone(), + }; + last = Some(result); + feedback + })?; + let mut last = last.ok_or_else(|| DiffusionError::model("hand decoder ran no steps"))?; + last.hand_box = output.hand_boxes; + last.hand_logits = output.hand_logits; + last.bbox = crop.sample_box_xyxy; + if crop.mirror { + self.unmirror_left(&mut last, crop.image_width); + } + Ok(last) + } + + fn close_hand_loop( + &self, + model: &BodyModel, + crop: &HandCrop, + step: &StepInput, + correctives: bool, + ) -> HandOutput { + let pose = unpack_pose(&step.pose_pred_519); + let params = self.hand_model_params(model, &pose); + let rigged = model.rig.forward(&pose.shape, ¶ms, &pose.expr, correctives); + + let mut kp_rig = rigged.keypoints308[..NUM_KEYPOINTS * 3].to_vec(); + kp_rig[..21 * 3].fill(0.0); + kp_rig[42 * 3..].fill(0.0); + let kp3d = camera_points(&kp_rig, NUM_KEYPOINTS); + let vertices = camera_points(&rigged.verts, MHR_VERTS); + let mut joint_rig = Vec::with_capacity(MHR_JOINTS * 3); + for joint in 0..MHR_JOINTS { + joint_rig.extend_from_slice(&rigged.skel_state[joint * 8..joint * 8 + 3]); + } + let joints = camera_points(&joint_rig, MHR_JOINTS); + let pred_cam: [f32; 3] = step.cam_pred_3.as_slice().try_into().unwrap(); + let cam_t = camera_translation_scaled( + pred_cam, + crop.geometry.center, + crop.geometry.side, + crop.geometry.focal, + crop.geometry.principal, + HAND_CAMERA_SCALE_FACTOR, + ); + let (kp2d, depth) = project( + &kp3d, + cam_t, + crop.geometry.focal, + crop.geometry.principal, + ); + BodyOutput { + pred_pose_raw: step.pose_pred_519[..266].to_vec(), + global_rot: pose.global_rot, + body_pose: pose.body, + shape: pose.shape, + scale: pose.scale, + hand: pose.hands, + face: pose.expr, + pred_keypoints_3d: kp3d, + pred_vertices: vertices, + pred_joint_coords: joints, + joint_global_rots: rigged.joint_global_rots, + mhr_model_params: params, + pred_cam, + pred_keypoints_2d: kp2d.clone(), + pred_cam_t: cam_t, + focal_length: crop.geometry.focal, + pred_keypoints_2d_depth: depth, + pred_keypoints_2d_cropped: full_to_crop(&kp2d, &crop.geometry), + hand_box: [[0.0; 4]; 2], + hand_logits: [[0.0; 2]; 2], + bbox: crop.sample_box_xyxy, + } + } + + fn hand_model_params(&self, model: &BodyModel, pose: &PoseHeadParams) -> [f32; 204] { + let original = euler_xyz_to_matrix(pose.global_rot); + let global_matrix = matrix_mul(original, self.local_to_world_wrist); + let global_rot = matrix_to_euler_xyz(global_matrix); + let wrist_delta = [ + self.right_wrist_coords[0] - self.root_coords[0], + self.right_wrist_coords[1] - self.root_coords[1], + self.right_wrist_coords[2] - self.root_coords[2], + ]; + let rotated = matrix_vec(global_matrix, wrist_delta); + let global_trans = [ + -(rotated[0] + self.root_coords[0]), + -(rotated[1] + self.root_coords[1]), + -(rotated[2] + self.root_coords[2]), + ]; + let mut params = model_params(&model.rig, pose); + for axis in 0..3 { + params[axis] = global_trans[axis] * 10.0; + params[3 + axis] = global_rot[axis]; + } + for &index in &self.nonhand_param_idxs { + params[index] = 0.0; + } + params + } + + fn unmirror_left(&self, output: &mut HandOutput, image_width: usize) { + let scale8 = output.scale[8]; + output.scale[9] = ((self.scale_mean[8] + + self.scale_comps[8 * 68 + 8] * scale8) + - self.scale_mean[9]) + / self.scale_comps[9 * 68 + 9]; + let source = output.joint_global_rots[42 * 9..43 * 9].to_vec(); + output.joint_global_rots[78 * 9..79 * 9].copy_from_slice(&source); + for value in &mut output.joint_global_rots[78 * 9 + 3..79 * 9] { + *value = -*value; + } + output.hand.copy_within(54..108, 0); + let [x1, y1, x2, y2] = output.bbox; + output.bbox = [ + image_width as f32 - x2 - 1.0, + y1, + image_width as f32 - x1 - 1.0, + y2, + ]; + } + + pub fn fuse( + &self, + model: &BodyModel, + body: &mut BodyOutput, + left: &HandOutput, + right: &HandOutput, + crops: &[HandCrop; 2], + body_geo: &CropGeometry, + body_context: &GpuTensor, + body_pe: &[f32], + ) -> Result { + let hands = [left, right]; + let mut report = FusionReport::default(); + let mut original_local = [[[0.0; 3]; 3]; 2]; + for hand in 0..2 { + let indices = WRIST_POSE[hand]; + original_local[hand] = euler_xzy_to_matrix([ + body.body_pose[indices[0]], + body.body_pose[indices[1]], + body.body_pose[indices[2]], + ]); + } + + let mut hand2 = [0.0f32; 108]; + hand2[..54].copy_from_slice(&left.hand[..54]); + hand2[54..].copy_from_slice(&right.hand[54..]); + let mut scale2 = body.scale; + scale2[9] = left.scale[9]; + scale2[8] = right.scale[8]; + for index in 18..28 { + scale2[index] = 0.5 * (left.scale[index] + right.scale[index]); + } + let mut shape2 = body.shape; + for index in 40..45 { + shape2[index] = 0.5 * (left.shape[index] + right.shape[index]); + } + // Stage A (before the re-prompt): the angle gate uses the first + // body pass's own joint rotations, no rig call. + let fused_from = |rotations: &[f32], hand: usize| { + let lowarm = matrix_at(rotations, LOWARM[hand]); + let twist = matrix_at(&self.joint_rotation, WRIST_TWIST[hand]); + let zero = matrix_mul(lowarm, twist); + let predicted = matrix_at(&hands[hand].joint_global_rots, WRIST[hand]); + matrix_mul(matrix_transpose(zero), predicted) + }; + let angle_between = |a: [[f32; 3]; 3], b: [[f32; 3]; 3]| { + let relative = matrix_mul(a, matrix_transpose(b)); + let trace = relative[0][0] + relative[1][1] + relative[2][2]; + ((trace - 1.0) * 0.5).clamp(-1.0, 1.0).acos() + }; + for hand in 0..2 { + let fused = fused_from(&body.joint_global_rots, hand); + report.valid_angle[hand] = angle_between(original_local[hand], fused) < 1.4; + } + let left_wrist = unmirrored_wrist(left, crops[LEFT].image_width, true); + let right_wrist = unmirrored_wrist(right, crops[RIGHT].image_width, false); + let body_left = point2(&body.pred_keypoints_2d, 62); + let body_right = point2(&body.pred_keypoints_2d, 41); + report.wrist_distance[LEFT] = distance(left_wrist, body_left) / crops[RIGHT].geometry.side; + report.wrist_distance[RIGHT] = distance(right_wrist, body_right) / crops[LEFT].geometry.side; + for hand in 0..2 { + let crop_ok = crops[hand].geometry.side > 64.0; + let points_ok = hands[hand] + .pred_keypoints_2d_cropped + .iter() + .map(|value| value.abs()) + .fold(0.0f32, f32::max) + < 0.5; + report.hand_valid[hand] = report.valid_angle[hand] + && crop_ok + && points_ok + && report.wrist_distance[hand] < 0.25; + } + + let candidates = [ + (right_wrist, 41usize, RIGHT), + (left_wrist, 62usize, LEFT), + (point2(&body.pred_keypoints_2d, 8), 8usize, RIGHT), + (point2(&body.pred_keypoints_2d, 7), 7usize, LEFT), + ]; + let mut prompts = Vec::new(); + for (point, label, side) in candidates { + let crop_point = full_to_crop(&point, body_geo); + if report.hand_valid[side] + && crop_point[0] > -0.5 + && crop_point[0] < 0.5 + && crop_point[1] > -0.5 + && crop_point[1] < 0.5 + { + prompts.push(PointPrompt { + point: [ + (crop_point[0] + 0.5).clamp(0.0, 1.0), + (crop_point[1] + 0.5).clamp(0.0, 1.0), + ], + label, + }); + } + } + report.prompt_count = prompts.len(); + if !prompts.is_empty() { + let mut previous = Vec::with_capacity(522); + previous.extend_from_slice(&body.pred_pose_raw); + previous.extend_from_slice(&body.shape); + previous.extend_from_slice(&body.scale); + previous.extend_from_slice(&body.hand); + previous.extend_from_slice(&body.face); + previous.extend_from_slice(&body.pred_cam); + let mut reprompted = None; + let decoded = model.decoder.run_with_prompts( + condition_info(body_geo), + &prompts, + &previous, + body_context, + body_pe, + |step| { + let result = close_the_loop(&model.rig, body_geo, &step, true); + let feedback = StepFeedback { + kp2d_cropped: result.pred_keypoints_2d_cropped.clone(), + depth: result.pred_keypoints_2d_depth.clone(), + kp3d: result.pred_keypoints_3d.clone(), + }; + reprompted = Some(result); + feedback + }, + )?; + let mut next = reprompted + .ok_or_else(|| DiffusionError::model("body re-prompt decoder ran no steps"))?; + next.hand_box = decoded.hand_boxes; + next.hand_logits = decoded.hand_logits; + next.bbox = body.bbox; + *body = next; + } + + // Stage B (after the re-prompt): the wrist angles come from a rig + // forward of the current body pose with the hands' parameters, and + // the angle gate is re-evaluated against the first pass's wrists. + let fusion_pose = PoseHeadParams { + global_rot: body.global_rot, + body: body.body_pose, + shape: shape2, + scale: scale2, + hands: hand2, + expr: body.face, + }; + let fusion_params = model_params(&model.rig, &fusion_pose); + let rotations = model + .rig + .forward(&shape2, &fusion_params, &body.face, false) + .joint_global_rots; + let mut wrist_angles = [[0.0f32; 3]; 2]; + for hand in 0..2 { + let fused = fused_from(&rotations, hand); + wrist_angles[hand] = fix_wrist_euler(matrix_to_euler_xzy(fused)); + report.angle_difference[hand] = angle_between(original_local[hand], fused); + report.fused[hand] = report.angle_difference[hand] < 1.4 && report.hand_valid[hand]; + } + for hand in 0..2 { + if !report.fused[hand] { + continue; + } + let indices = WRIST_POSE[hand]; + for axis in 0..3 { + body.body_pose[indices[axis]] = wrist_angles[hand][axis]; + } + body.hand[hand * 54..(hand + 1) * 54] + .copy_from_slice(&hand2[hand * 54..(hand + 1) * 54]); + } + if report.fused[LEFT] { + body.scale[9] = left.scale[9]; + } + if report.fused[RIGHT] { + body.scale[8] = right.scale[8]; + } + let valid_count = report.fused.into_iter().filter(|value| *value).count(); + if valid_count != 0 { + for index in 18..28 { + body.scale[index] = (0..2) + .filter(|&hand| report.fused[hand]) + .map(|hand| hands[hand].scale[index]) + .sum::() + / valid_count as f32; + } + for index in 40..45 { + body.shape[index] = (0..2) + .filter(|&hand| report.fused[hand]) + .map(|hand| hands[hand].shape[index]) + .sum::() + / valid_count as f32; + } + } + rebuild_body(model, body, body_geo); + Ok(report) + } +} + +pub fn hand_crops( + body: &BodyOutput, + body_geo: &CropGeometry, + image: BodyImage<'_>, +) -> [HandCrop; 2] { + hand_crops_from_boxes(body.hand_box, body_geo, image) +} + +fn hand_crops_from_boxes( + boxes: [[f32; 4]; 2], + body_geo: &CropGeometry, + image: BodyImage<'_>, +) -> [HandCrop; 2] { + std::array::from_fn(|hand| { + let value = boxes[hand]; + let centre_crop = [value[0] * IMAGE_SIZE as f32, value[1] * IMAGE_SIZE as f32]; + let scale_crop = value[2].max(value[3]) * IMAGE_SIZE as f32; + let k = body_geo.affine[0]; + let centre = [ + (centre_crop[0] - body_geo.affine[2]) / k, + (centre_crop[1] - body_geo.affine[5]) / k, + ]; + let scale = scale_crop / k; + let box_xyxy = [ + centre[0] - 0.5 * scale, + centre[1] - 0.5 * scale, + centre[0] + 0.5 * scale, + centre[1] + 0.5 * scale, + ]; + let mirror = hand == LEFT; + let sample_box_xyxy = if mirror { + [ + image.width as f32 - box_xyxy[2] - 1.0, + box_xyxy[1], + image.width as f32 - box_xyxy[0] - 1.0, + box_xyxy[3], + ] + } else { + box_xyxy + }; + let geometry = crop_geometry_at( + sample_box_xyxy, + image.width, + image.height, + Some([body_geo.focal, body_geo.principal[0], body_geo.principal[1]]), + IMAGE_SIZE, + 0.9, + ); + let normalized = crop_normalized_mirrored( + image.rgb, + image.width, + image.height, + &geometry, + mirror, + ); + let plane = IMAGE_SIZE * IMAGE_SIZE; + let mut rgb01 = normalized.clone(); + for channel in 0..3 { + let mean = [0.485, 0.456, 0.406][channel]; + let std = [0.229, 0.224, 0.225][channel]; + for value in &mut rgb01[channel * plane..(channel + 1) * plane] { + *value = *value * std + mean; + } + } + HandCrop { + rgb01, + normalized, + box_xyxy, + sample_box_xyxy, + geometry, + mirror, + image_width: image.width, + image_height: image.height, + } + }) +} + +fn rebuild_body(model: &BodyModel, body: &mut BodyOutput, body_geo: &CropGeometry) { + let pose = PoseHeadParams { + global_rot: body.global_rot, + body: body.body_pose, + shape: body.shape, + scale: body.scale, + hands: body.hand, + expr: body.face, + }; + let params = model_params(&model.rig, &pose); + let rigged = model.rig.forward(&body.shape, ¶ms, &body.face, true); + body.mhr_model_params = params; + body.pred_keypoints_3d = camera_points(&rigged.keypoints308, NUM_KEYPOINTS); + body.pred_vertices = camera_points(&rigged.verts, MHR_VERTS); + let mut joints = Vec::with_capacity(MHR_JOINTS * 3); + for joint in 0..MHR_JOINTS { + joints.extend_from_slice(&rigged.skel_state[joint * 8..joint * 8 + 3]); + } + body.pred_joint_coords = camera_points(&joints, MHR_JOINTS); + body.joint_global_rots = rigged.joint_global_rots; + let (kp2d, depth) = project( + &body.pred_keypoints_3d, + body.pred_cam_t, + body.focal_length, + body_geo.principal, + ); + body.pred_keypoints_2d_cropped = full_to_crop(&kp2d, body_geo); + body.pred_keypoints_2d = kp2d; + body.pred_keypoints_2d_depth = depth; +} + +fn camera_points(values: &[f32], count: usize) -> Vec { + let mut output = Vec::with_capacity(count * 3); + for point in values[..count * 3].chunks_exact(3) { + output.extend_from_slice(&[point[0] / 100.0, point[1] / -100.0, point[2] / -100.0]); + } + output +} + +fn matrix_at(values: &[f32], joint: usize) -> [[f32; 3]; 3] { + let row = &values[joint * 9..(joint + 1) * 9]; + [ + row[0..3].try_into().unwrap(), + row[3..6].try_into().unwrap(), + row[6..9].try_into().unwrap(), + ] +} + +fn matrix_vec(matrix: [[f32; 3]; 3], value: [f32; 3]) -> [f32; 3] { + std::array::from_fn(|row| (0..3).map(|column| matrix[row][column] * value[column]).sum()) +} + +fn point2(values: &[f32], index: usize) -> [f32; 2] { + [values[index * 2], values[index * 2 + 1]] +} + +fn unmirrored_wrist(output: &HandOutput, width: usize, mirror: bool) -> [f32; 2] { + let mut point = point2(&output.pred_keypoints_2d, 41); + if mirror { + point[0] = width as f32 - point[0] - 1.0; + } + point +} + +fn distance(a: [f32; 2], b: [f32; 2]) -> f32 { + ((a[0] - b[0]).powi(2) + (a[1] - b[1]).powi(2)).sqrt() +} + +fn wrap(value: f32) -> f32 { + value.sin().atan2(value.cos()) +} + +fn wrist_violation(value: [f32; 3]) -> f32 { + let limits = [(-2.2, 1.0), (-2.2, 1.5), (-1.2, 1.5)]; + value + .into_iter() + .zip(limits) + .map(|(value, (low, high))| (low - value).max(0.0).powi(2) + (value - high).max(0.0).powi(2)) + .sum() +} + +fn fix_wrist_euler(original: [f32; 3]) -> [f32; 3] { + let alternate = [ + wrap(original[0] + std::f32::consts::PI), + wrap(-(original[1] + std::f32::consts::PI)), + wrap(original[2] + std::f32::consts::PI), + ]; + if wrist_violation(alternate) < wrist_violation(original) { + alternate + } else { + original + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::backend::{gpu_device_available, gpu_download, gpu_upload}; + use crate::fixture::{self, OracleRoot}; + + fn max_abs(actual: &[f32], expected: &[f32]) -> f32 { + assert_eq!(actual.len(), expected.len()); + actual + .iter() + .zip(expected) + .map(|(a, b)| (a - b).abs()) + .fold(0.0, f32::max) + } + + fn mean_relative_error(actual: &[f32], expected: &[f32]) -> f32 { + assert_eq!(actual.len(), expected.len()); + let diff: f64 = actual + .iter() + .zip(expected) + .map(|(a, e)| (a - e).abs() as f64) + .sum(); + let norm: f64 = expected.iter().map(|e| e.abs() as f64).sum(); + (diff / norm.max(1e-12)) as f32 + } + + fn max_abs_at(actual: &[f32], expected: &[f32]) -> (f32, usize) { + actual + .iter() + .zip(expected) + .enumerate() + .map(|(index, (a, b))| ((a - b).abs(), index)) + .max_by(|a, b| a.0.total_cmp(&b.0)) + .unwrap() + } + + fn oracle(name: &str) -> Vec { + fixture::load_from(OracleRoot::Full, name) + .unwrap_or_else(|| panic!("missing oracle_full field {name}")) + .1 + } + + fn planar_to_tokens(values: &[f32]) -> Vec { + let tokens = values.len() / DINO_DIM; + let mut output = vec![0.0; values.len()]; + for channel in 0..DINO_DIM { + for token in 0..tokens { + output[token * DINO_DIM + channel] = values[channel * tokens + token]; + } + } + output + } + + fn assert_oracle(name: &str, actual: &[f32], tolerance: f32) { + let expected = oracle(name); + let (error, at) = max_abs_at(actual, &expected); + eprintln!("{name} max abs {error:.6}"); + assert!( + error <= tolerance, + "{name} max abs {error} at {at}: actual {} expected {}", + actual[at], + expected[at], + ); + } + + #[test] + fn oracle_hand_boxes_and_crops() { + let Some((shape, image)) = fixture::load_from(OracleRoot::Full, "input_rgb_u8") else { + eprintln!("SKIP oracle_hand_boxes_and_crops: oracle_full absent"); + return; + }; + let Some((_, boxes)) = fixture::load_from(OracleRoot::Full, "hand_box_sigmoid") else { + eprintln!("SKIP oracle_hand_boxes_and_crops: hand boxes absent"); + return; + }; + let (height, width) = (shape[0], shape[1]); + let rgb: Vec = image.into_iter().map(|value| value as u8).collect(); + let body_geo = crop_geometry_at( + [0.0, 0.0, width as f32, height as f32], + width, + height, + None, + IMAGE_SIZE, + 1.25, + ); + let crops = hand_crops_from_boxes( + [boxes[0..4].try_into().unwrap(), boxes[4..8].try_into().unwrap()], + &body_geo, + BodyImage { + rgb: &rgb, + width, + height, + }, + ); + for (hand, expected_name) in ["hand_box_left_xyxy", "hand_box_right_xyxy"] + .into_iter() + .enumerate() + { + let expected = fixture::load_from(OracleRoot::Full, expected_name).unwrap().1; + let error = max_abs(&crops[hand].sample_box_xyxy, &expected); + eprintln!("{expected_name} max abs {error:.6} px"); + assert!(error < 5.0e-3, "{expected_name} max abs {error}"); + let crop_name = format!("batch_img_{}", hand + 1); + let expected_crop = fixture::load_from(OracleRoot::Full, &crop_name).unwrap().1; + let (crop_error, at) = max_abs_at(&crops[hand].rgb01, &expected_crop); + eprintln!( + "{crop_name} max abs {crop_error:.6} at {at}: actual {} expected {}", + crops[hand].rgb01[at], expected_crop[at] + ); + assert!(crop_error < 2.0e-2, "{crop_name} max abs {crop_error}"); + } + } + + #[test] + fn intrinsic_euler_pairs_round_trip() { + for value in [[0.3, -0.4, 0.8], [-1.1, 0.6, -0.2]] { + let matrix = euler_xyz_to_matrix(value); + let rebuilt = euler_xyz_to_matrix(matrix_to_euler_xyz(matrix)); + assert!(max_abs(&matrix.concat(), &rebuilt.concat()) < 1.0e-6); + let matrix = euler_xzy_to_matrix(value); + let rebuilt = euler_xzy_to_matrix(matrix_to_euler_xzy(matrix)); + assert!(max_abs(&matrix.concat(), &rebuilt.concat()) < 1.0e-6); + } + } + + #[test] + fn oracle_hand_backbone_context_decoder_heads_and_rig() { + if fixture::oracle_dir_for(OracleRoot::Full).is_none() { + eprintln!("SKIP oracle_hand_stages: oracle_full absent"); + return; + } + if !gpu_device_available() || !fixture::gpu_required_ops_available() { + eprintln!("SKIP oracle_hand_stages: GPU unavailable"); + return; + } + let Some(weights_path) = fixture::weights_path() else { + eprintln!("SKIP oracle_hand_stages: weights absent"); + return; + }; + let mut model = BodyModel::load(&weights_path).expect("load body model"); + model.correctives_every_step = true; + let branch = HandBranch::load(&model.weights).expect("load hand branch"); + let (shape, image) = fixture::load_from(OracleRoot::Full, "input_rgb_u8").unwrap(); + let (height, width) = (shape[0], shape[1]); + let rgb: Vec = image.into_iter().map(|value| value as u8).collect(); + let body_geo = crop_geometry_at( + [0.0, 0.0, width as f32, height as f32], + width, + height, + None, + IMAGE_SIZE, + 1.25, + ); + let boxes = oracle("hand_box_sigmoid"); + let crops = hand_crops_from_boxes( + [boxes[..4].try_into().unwrap(), boxes[4..].try_into().unwrap()], + &body_geo, + BodyImage { + rgb: &rgb, + width, + height, + }, + ); + + for hand in 0..2 { + let embeddings = model + .dino + .forward_normalized(&crops[hand].normalized) + .expect("hand backbone"); + let backbone = gpu_download(&embeddings).expect("download hand backbone"); + let expected_backbone = planar_to_tokens(&oracle(&format!("backbone_out_{}", hand + 1))); + let (error, _) = max_abs_at(&backbone, &expected_backbone); + let mean_relative = mean_relative_error(&backbone, &expected_backbone); + eprintln!( + "backbone_out_{} max abs {error:.6}; relative mean error {mean_relative:.6}", + hand + 1 + ); + assert!( + mean_relative < 3.0e-2, + "hand backbone relative mean error {mean_relative}" + ); + // The stages below start from the reference's own backbone output + // so their tolerances are not eaten by bf16 accumulation noise. + let embeddings = gpu_upload( + &expected_backbone, + expected_backbone.len() / crate::DINO_DIM, + crate::DINO_DIM, + ) + .expect("upload oracle hand backbone"); + + let context = branch + .ray_cond + .apply( + &embeddings, + &model.no_mask_embed, + &ray_features(&patch_rays(&crops[hand].geometry)), + ) + .expect("hand ray conditioning"); + let context_host = gpu_download(&context).expect("download hand context"); + let expected_context = planar_to_tokens(&oracle(&format!("raycondhand_out_{hand}"))); + let (error, _) = max_abs_at(&context_host, &expected_context); + eprintln!("raycondhand_out_{hand} max abs {error:.6}"); + assert!(error < 2.0e-2); + + let tokens = branch + .decoder + .build_tokens(condition_info(&crops[hand].geometry)); + assert_oracle(&format!("dechand_tokens_in_{hand}"), &tokens.tokens, 1.0e-4); + assert_oracle( + &format!("dechand_token_augment_in_{hand}"), + &tokens.token_augment, + 1.0e-4, + ); + let mut last = None; + let mut trace = |layer: usize, hidden: &GpuTensor, normed: &[f32]| -> Result<()> { + let hidden = gpu_download(hidden).map_err(DiffusionError::model)?; + assert_oracle( + &format!("dechand{layer}_tokens_out_{hand}"), + &hidden, + 5.0e-2, + ); + assert_oracle( + &format!("normhand_final_out_{}", hand * 6 + layer), + normed, + 2.0e-2, + ); + Ok(()) + }; + branch + .decoder + .run_traced( + tokens, + &context, + &branch.dense_pe, + |step| { + let call = hand * 6 + step.layer; + let raw: Vec = step + .pose_pred_519 + .iter() + .zip(branch.decoder.init_pose()) + .map(|(value, init)| value - init) + .collect(); + assert_oracle( + &format!("headhand_pose_proj_out_{call}"), + &raw, + 2.0e-2, + ); + let result = branch.close_hand_loop(&model, &crops[hand], &step, true); + if step.layer < 6 { + let posemb_in = oracle(&format!("kphand_posemb_in_{}", hand * 5 + step.layer.min(4))); + let (kp_err, kp_at) = + max_abs_at(&result.pred_keypoints_2d_cropped, &posemb_in); + let valid = result + .pred_keypoints_2d_cropped + .chunks_exact(2) + .zip(&result.pred_keypoints_2d_depth) + .filter(|(p, &d)| { + (0.0..=1.0).contains(&(p[0] + 0.5)) + && (0.0..=1.0).contains(&(p[1] + 0.5)) + && d >= 1e-5 + }) + .count(); + eprintln!( + "hand {hand} step {}: kp2d_cropped vs kphand_posemb_in max abs {kp_err:.5} at kp {} ({} valid of 70)", + step.layer, + kp_at / 2, + valid + ); + } + assert_oracle( + &format!("mhrjithand_in_params_{call}"), + &result.mhr_model_params, + 2.0e-3, + ); + let rig_axes = |values: &[f32]| { + let mut output = values.to_vec(); + for point in output.chunks_exact_mut(3) { + point[1] = -point[1]; + point[2] = -point[2]; + } + output + }; + assert_oracle( + &format!("mhrhand_out_0_{call}"), + &rig_axes(&result.pred_vertices), + 2.0e-3, + ); + let expected_keypoints = oracle(&format!("mhrhand_out_1_{call}")); + let keypoints = rig_axes(&result.pred_keypoints_3d); + let (error, _) = max_abs_at( + &keypoints, + &expected_keypoints[..NUM_KEYPOINTS * 3], + ); + assert!(error < 2.0e-3, "mhrhand_out_1_{call} max abs {error}"); + assert_oracle( + &format!("mhrhand_out_2_{call}"), + &rig_axes(&result.pred_joint_coords), + 2.0e-3, + ); + assert_oracle( + &format!("mhrhand_out_3_{call}"), + &result.mhr_model_params, + 2.0e-3, + ); + assert_oracle( + &format!("mhrhand_out_4_{call}"), + &result.joint_global_rots, + 2.0e-3, + ); + let feedback = StepFeedback { + kp2d_cropped: result.pred_keypoints_2d_cropped.clone(), + depth: result.pred_keypoints_2d_depth.clone(), + kp3d: result.pred_keypoints_3d.clone(), + }; + last = Some(result); + feedback + }, + &mut trace, + ) + .expect("run traced hand decoder"); + let raw = last.expect("hand result"); + assert_oracle( + &format!("step_hand_pred_keypoints_3d_{hand}"), + &raw.pred_keypoints_3d, + 2.0e-3, + ); + assert_oracle( + &format!("step_hand_pred_keypoints_2d_{hand}"), + &raw.pred_keypoints_2d, + 0.5, + ); + assert_oracle( + &format!("step_hand_joint_global_rots_{hand}"), + &raw.joint_global_rots, + 2.0e-3, + ); + } + } +} diff --git a/libs/ai/models/body/src/heads.rs b/libs/ai/models/body/src/heads.rs index f5690f8f0..f4d3f029d 100644 --- a/libs/ai/models/body/src/heads.rs +++ b/libs/ai/models/body/src/heads.rs @@ -150,27 +150,46 @@ pub(crate) struct DecoderHeads { } impl DecoderHeads { + #[cfg(test)] pub(crate) fn load(weights: &BodyWeights) -> Result { + Self::load_named( + weights, + "head_pose.proj", + "head_camera.proj", + "keypoint_posemb_linear", + "keypoint3d_posemb_linear", + "keypoint_feat_linear", + ) + } + + pub(crate) fn load_named( + weights: &BodyWeights, + pose: &str, + camera: &str, + keypoint_posemb: &str, + keypoint3d_posemb: &str, + keypoint_feat: &str, + ) -> Result { Ok(Self { - pose: ReluFfn::load(weights, "head_pose.proj", DEC_DIM, DEC_DIM, NPOSE)?, - camera: ReluFfn::load(weights, "head_camera.proj", DEC_DIM, DEC_DIM, NCAM)?, + pose: ReluFfn::load(weights, pose, DEC_DIM, DEC_DIM, NPOSE)?, + camera: ReluFfn::load(weights, camera, DEC_DIM, DEC_DIM, NCAM)?, keypoint_posemb: ReluFfn::load( weights, - "keypoint_posemb_linear", + keypoint_posemb, 2, DEC_DIM, DEC_DIM, )?, keypoint3d_posemb: ReluFfn::load( weights, - "keypoint3d_posemb_linear", + keypoint3d_posemb, 3, DEC_DIM, DEC_DIM, )?, keypoint_feat: HostLinear::load( weights, - "keypoint_feat_linear", + keypoint_feat, DEC_DIM, DINO_DIM, )?, diff --git a/libs/ai/models/body/src/lib.rs b/libs/ai/models/body/src/lib.rs index 1dc90f5cf..933d11426 100644 --- a/libs/ai/models/body/src/lib.rs +++ b/libs/ai/models/body/src/lib.rs @@ -28,6 +28,7 @@ pub use makepad_ai_common::{emit_progress, DiffusionError, ProgressHook, Result} pub mod condition; pub mod decoder; pub mod dino; +pub mod hands; mod heads; pub mod mhr; pub mod model; diff --git a/libs/ai/models/body/src/mhr.rs b/libs/ai/models/body/src/mhr.rs index d5f303232..1e56a2a17 100644 --- a/libs/ai/models/body/src/mhr.rs +++ b/libs/ai/models/body/src/mhr.rs @@ -67,6 +67,8 @@ pub struct MhrOutput { pub verts: Vec, pub skel_state: Vec, pub keypoints308: Vec, + /// Row-major global rotation matrices, one per skeleton joint. + pub joint_global_rots: Vec, } impl MhrRig { @@ -451,14 +453,30 @@ impl MhrRig { } let verts = self.skin(&skel_state, &rest); let keypoints308 = self.keypoints(&verts, &skel_state); + let joint_global_rots = joint_global_rots(&skel_state); MhrOutput { verts, skel_state, keypoints308, + joint_global_rots, } } } +/// Convert the quaternion part of 127 `(t, q_xyzw, s)` skeleton states to +/// row-major global rotation matrices. +pub fn joint_global_rots(skel_state: &[f32]) -> Vec { + assert_eq!(skel_state.len(), MHR_JOINTS * STATE_WIDTH); + let mut output = Vec::with_capacity(MHR_JOINTS * 9); + for joint in 0..MHR_JOINTS { + let offset = joint * STATE_WIDTH + 3; + output.extend_from_slice(&quat_matrix( + skel_state[offset..offset + 4].try_into().unwrap(), + )); + } + output +} + #[derive(Clone, Copy)] struct Transform { t: [f32; 3], @@ -524,6 +542,24 @@ fn quat_rotate(q: [f32; 4], point: [f32; 3]) -> [f32; 3] { ] } +fn quat_matrix(q: [f32; 4]) -> [f32; 9] { + let [x, y, z, w] = q; + let (xx, yy, zz) = (x * x, y * y, z * z); + let (xy, xz, yz) = (x * y, x * z, y * z); + let (wx, wy, wz) = (w * x, w * y, w * z); + [ + 1.0 - 2.0 * (yy + zz), + 2.0 * (xy - wz), + 2.0 * (xz + wy), + 2.0 * (xy + wz), + 1.0 - 2.0 * (xx + zz), + 2.0 * (yz - wx), + 2.0 * (xz - wy), + 2.0 * (yz + wx), + 1.0 - 2.0 * (xx + yy), + ] +} + fn euler_zyx_quat([rx, ry, rz]: [f32; 3]) -> [f32; 4] { let (sx, cx) = (0.5 * rx).sin_cos(); let (sy, cy) = (0.5 * ry).sin_cos(); @@ -794,4 +830,27 @@ mod tests { eprintln!("MHR first-70 keypoint max abs error {error:.7} m"); assert!(error <= 1.0e-4, "keypoint max abs error {error} m"); } + + #[test] + fn oracle_joint_global_rotations_from_skeleton_quaternions() { + use crate::fixture::OracleRoot; + let Some((_, skel)) = fixture::load_from(OracleRoot::Full, "mhrjit_out_skel_5") else { + eprintln!("SKIP oracle_joint_global_rotations: oracle_full absent"); + return; + }; + let Some((_, expected)) = + fixture::load_from(OracleRoot::Full, "step_body_joint_global_rots_0") + else { + eprintln!("SKIP oracle_joint_global_rotations: expected rotations absent"); + return; + }; + let actual = joint_global_rots(&skel); + let error = actual + .iter() + .zip(&expected) + .map(|(a, b)| (a - b).abs()) + .fold(0.0f32, f32::max); + eprintln!("joint-global-rotation max abs {error:.7}"); + assert!(error < 2.0e-5, "joint rotations max abs {error}"); + } } diff --git a/libs/ai/models/body/src/model.rs b/libs/ai/models/body/src/model.rs index 037b63c94..a575e8077 100644 --- a/libs/ai/models/body/src/model.rs +++ b/libs/ai/models/body/src/model.rs @@ -10,9 +10,10 @@ use crate::condition::{dense_pe_at, ray_features, RayCond}; use crate::decoder::{Decoder, LoopTiming, StepFeedback, StepInput}; use crate::dino::BodyDino; +use crate::hands::{hand_crops, BodyImage, FusionReport, HandBranch, HandOutput}; use crate::mhr::MhrRig; use crate::packet::{BodyPacket, BodyPerson}; -use crate::pose::{camera_translation, model_params, project, unpack_pose, PoseHeadParams}; +use crate::pose::{camera_translation, model_params, project, unpack_pose}; use crate::preprocess::{ condition_info, crop_geometry_at, crop_normalized, full_to_crop, patch_rays, CropGeometry, }; @@ -26,13 +27,14 @@ use std::time::Instant; pub struct BodyModel { pub weights: BodyWeights, - dino: BodyDino, + pub(crate) dino: BodyDino, ray_cond: RayCond, gaussian: Vec, dense_pe: HashMap>, - no_mask_embed: [f32; DINO_DIM], - decoder: Decoder, - rig: MhrRig, + pub(crate) no_mask_embed: [f32; DINO_DIM], + pub(crate) decoder: Decoder, + pub(crate) rig: MhrRig, + hands: Option, /// The crop side the backbone sees; 512 is the trained size, smaller is /// faster and less accurate (see `set_crop_size`). crop_size: usize, @@ -47,14 +49,40 @@ pub struct BodyModel { pub last_loop: LoopTiming, } -/// Everything one refinement step produced; the last one is the answer. -struct StepResult { - pose: PoseHeadParams, - params: [f32; 204], - cam_t: [f32; 3], - kp3d: Vec, - kp2d: Vec, - joints: Vec, +/// What [`BodyModel::infer_full`] returns: the fused body, the two hand +/// passes (left first, already un-mirrored) and the fusion report. +#[derive(Clone, Debug)] +pub struct FullOutput { + pub body: BodyOutput, + pub hands: [HandOutput; 2], + pub report: FusionReport, +} + +/// Rich model output used by the body, hand, re-prompt, and fusion passes. +/// The packet API deliberately exposes only its stable transport subset. +#[derive(Clone, Debug)] +pub struct BodyOutput { + pub pred_pose_raw: Vec, + pub global_rot: [f32; 3], + pub body_pose: [f32; 133], + pub shape: [f32; 45], + pub scale: [f32; 28], + pub hand: [f32; 108], + pub face: [f32; 72], + pub pred_keypoints_3d: Vec, + pub pred_vertices: Vec, + pub pred_joint_coords: Vec, + pub joint_global_rots: Vec, + pub mhr_model_params: [f32; 204], + pub pred_cam: [f32; 3], + pub pred_keypoints_2d: Vec, + pub pred_cam_t: [f32; 3], + pub focal_length: f32, + pub pred_keypoints_2d_depth: Vec, + pub pred_keypoints_2d_cropped: Vec, + pub hand_box: [[f32; 4]; 2], + pub hand_logits: [[f32; 2]; 2], + pub bbox: [f32; 4], } impl BodyModel { @@ -85,6 +113,7 @@ impl BodyModel { no_mask_embed, decoder, rig, + hands: None, crop_size: IMAGE_SIZE, correctives_every_step: false, last_stage_ms: [0.0; 5], @@ -96,6 +125,12 @@ impl BodyModel { /// The crop side: a multiple of 16 between 128 and 1024. The model was /// trained at 512; 256 runs the backbone on a quarter of the tokens. + /// The MHR rig, for callers that want the unposed mesh of a person the + /// model just inferred (`rig().rest_vertices(&shape, &expr)`). + pub fn rig(&self) -> &MhrRig { + &self.rig + } + pub fn set_crop_size(&mut self, size: usize) -> Result<()> { if size % PATCH != 0 || !(128..=1024).contains(&size) { return Err(DiffusionError::workflow(format!( @@ -139,7 +174,7 @@ impl BodyModel { } let bbox = bbox.unwrap_or([0.0, 0.0, width as f32, height as f32]); let total = Instant::now(); - let geo = crop_geometry_at(bbox, w, h, None, self.crop_size); + let geo = crop_geometry_at(bbox, w, h, None, self.crop_size, 1.25); let crop = crop_normalized(rgb, w, h, &geo); let t_crop = total.elapsed(); @@ -155,16 +190,16 @@ impl BodyModel { let rig = &self.rig; let dense_pe = &self.dense_pe[&self.crop_size]; let every_step = self.correctives_every_step; - let mut last: Option = None; + let mut last: Option = None; let output = self .decoder .run(tokens, &context, dense_pe, |step: StepInput| { let correctives = every_step || step.layer + 1 == crate::DEC_DEPTH; let result = close_the_loop(rig, &geo, &step, correctives); let feedback = StepFeedback { - kp2d_cropped: full_to_crop(&result.kp2d, &geo), - depth: depths(&result.kp3d, result.cam_t), - kp3d: result.kp3d.clone(), + kp2d_cropped: result.pred_keypoints_2d_cropped.clone(), + depth: result.pred_keypoints_2d_depth.clone(), + kp3d: result.pred_keypoints_3d.clone(), }; last = Some(result); feedback @@ -172,18 +207,21 @@ impl BodyModel { self.last_loop = output.timing; let t_decoder = total.elapsed(); - let last = last.ok_or_else(|| DiffusionError::model("body decoder ran no steps"))?; + let mut last = last.ok_or_else(|| DiffusionError::model("body decoder ran no steps"))?; + last.hand_box = output.hand_boxes; + last.hand_logits = output.hand_logits; + last.bbox = bbox; let person = BodyPerson { - mhr: last.params, - global_rot: last.pose.global_rot, - cam_t: last.cam_t, - shape: last.pose.shape, - expr: last.pose.expr, + mhr: last.mhr_model_params, + global_rot: last.global_rot, + cam_t: last.pred_cam_t, + shape: last.shape, + expr: last.face, focal: geo.focal, bbox, - kp3d: last.kp3d, - kp2d: last.kp2d, - joints: Some(last.joints), + kp3d: last.pred_keypoints_3d, + kp2d: last.pred_keypoints_2d, + joints: Some(last.pred_joint_coords), rots: None, }; let t_packet = total.elapsed(); @@ -199,11 +237,104 @@ impl BodyModel { ms: t_packet.as_secs_f32() * 1000.0, }) } + + /// Full body + two hand crops + wrist fusion. Unlike [`Self::infer`], + /// this returns the rich fused result, the two hand passes and the + /// fusion report (which hands were trusted and why). + pub fn infer_full( + &mut self, + rgb: &[u8], + width: u32, + height: u32, + bbox: Option<[f32; 4]>, + ) -> Result { + if self.crop_size != IMAGE_SIZE { + return Err(DiffusionError::workflow(format!( + "body full inference requires the trained {IMAGE_SIZE}px crop, got {}", + self.crop_size, + ))); + } + let (w, h) = (width as usize, height as usize); + if rgb.len() != w * h * 3 { + return Err(DiffusionError::workflow(format!( + "body infer_full: {} bytes for {width}x{height} rgb, expected {}", + rgb.len(), + w * h * 3, + ))); + } + let bbox = bbox.unwrap_or([0.0, 0.0, width as f32, height as f32]); + let geo = crop_geometry_at(bbox, w, h, None, IMAGE_SIZE, 1.25); + let crop = crop_normalized(rgb, w, h, &geo); + let embeddings = self.dino.forward_normalized(&crop)?; + let features = ray_features(&patch_rays(&geo)); + let context = self + .ray_cond + .apply(&embeddings, &self.no_mask_embed, &features)?; + let tokens = self.decoder.build_tokens(condition_info(&geo)); + let mut last = None; + let decoded = self.decoder.run( + tokens, + &context, + &self.dense_pe[&IMAGE_SIZE], + |step| { + let correctives = self.correctives_every_step + || step.layer + 1 == crate::DEC_DEPTH; + let result = close_the_loop(&self.rig, &geo, &step, correctives); + let feedback = StepFeedback { + kp2d_cropped: result.pred_keypoints_2d_cropped.clone(), + depth: result.pred_keypoints_2d_depth.clone(), + kp3d: result.pred_keypoints_3d.clone(), + }; + last = Some(result); + feedback + }, + )?; + let mut body = last.ok_or_else(|| DiffusionError::model("body decoder ran no steps"))?; + body.hand_box = decoded.hand_boxes; + body.hand_logits = decoded.hand_logits; + body.bbox = bbox; + + if self.hands.is_none() { + self.hands = Some(HandBranch::load(&self.weights)?); + } + let branch = self.hands.as_ref().unwrap(); + let crops = hand_crops( + &body, + &geo, + BodyImage { + rgb, + width: w, + height: h, + }, + ); + let left = branch.infer_hand(self, &crops[0])?; + let right = branch.infer_hand(self, &crops[1])?; + let report = branch.fuse( + self, + &mut body, + &left, + &right, + &crops, + &geo, + &context, + &self.dense_pe[&IMAGE_SIZE], + )?; + Ok(FullOutput { + body, + hands: [left, right], + report, + }) + } } /// One refinement step's tail: head output -> rig parameters -> posed rig /// -> keypoints in camera axes -> camera translation -> projection. -fn close_the_loop(rig: &MhrRig, geo: &CropGeometry, step: &StepInput, correctives: bool) -> StepResult { +pub(crate) fn close_the_loop( + rig: &MhrRig, + geo: &CropGeometry, + step: &StepInput, + correctives: bool, +) -> BodyOutput { let pose = unpack_pose(&step.pose_pred_519); let params = model_params(rig, &pose); let rigged = rig.forward(&pose.shape, ¶ms, &pose.expr, correctives); @@ -219,6 +350,7 @@ fn close_the_loop(rig: &MhrRig, geo: &CropGeometry, step: &StepInput, corrective out }; let kp3d = to_camera(&rigged.keypoints308, NUM_KEYPOINTS); + let vertices = to_camera(&rigged.verts, crate::MHR_VERTS); let mut joint_positions = Vec::with_capacity(MHR_JOINTS * 3); for joint in 0..MHR_JOINTS { joint_positions.extend_from_slice(&rigged.skel_state[joint * 8..joint * 8 + 3]); @@ -226,21 +358,33 @@ fn close_the_loop(rig: &MhrRig, geo: &CropGeometry, step: &StepInput, corrective let joints = to_camera(&joint_positions, MHR_JOINTS); let cam = [step.cam_pred_3[0], step.cam_pred_3[1], step.cam_pred_3[2]]; let cam_t = camera_translation(cam, geo.center, geo.side, geo.focal, geo.principal); - let (kp2d, _) = project(&kp3d, cam_t, geo.focal, geo.principal); - StepResult { - pose, - params, - cam_t, - kp3d, - kp2d, - joints, + let (kp2d, depth) = project(&kp3d, cam_t, geo.focal, geo.principal); + let pred_cam = cam; + BodyOutput { + pred_pose_raw: step.pose_pred_519[..266].to_vec(), + global_rot: pose.global_rot, + body_pose: pose.body, + shape: pose.shape, + scale: pose.scale, + hand: pose.hands, + face: pose.expr, + pred_keypoints_3d: kp3d, + pred_vertices: vertices, + pred_joint_coords: joints, + joint_global_rots: rigged.joint_global_rots, + mhr_model_params: params, + pred_cam, + pred_keypoints_2d: kp2d.clone(), + pred_cam_t: cam_t, + focal_length: geo.focal, + pred_keypoints_2d_depth: depth, + pred_keypoints_2d_cropped: full_to_crop(&kp2d, geo), + hand_box: [[0.0; 4]; 2], + hand_logits: [[0.0; 2]; 2], + bbox: [0.0; 4], } } -fn depths(kp3d: &[f32], cam_t: [f32; 3]) -> Vec { - kp3d.chunks_exact(3).map(|point| point[2] + cam_t[2]).collect() -} - #[cfg(test)] mod tests { use super::*; @@ -361,4 +505,58 @@ mod tests { assert!(json.starts_with("{\"n_people\":1,\"people\":[{\"mhr\":[")); assert!(json.contains("\"kp3d\":[") && json.contains("\"joints\":[")); } + + fn full_end_to_end(root: fixture::OracleRoot, label: &str) { + let Some((shape, image)) = fixture::load_from(root, "input_rgb_u8") else { + eprintln!("SKIP {label}: fixture absent"); + return; + }; + if !gpu_device_available() || !fixture::gpu_required_ops_available() { + eprintln!("SKIP {label}: no GPU"); + return; + } + let Some(weights_path) = fixture::weights_path() else { + eprintln!("SKIP {label}: weights absent"); + return; + }; + let (h, w) = (shape[0] as u32, shape[1] as u32); + let rgb: Vec = image.into_iter().map(|value| value as u8).collect(); + let mut model = BodyModel::load(&weights_path).expect("load full body model"); + model.correctives_every_step = true; + let full = model.infer_full(&rgb, w, h, None).expect("full inference"); + let field = |name: &str| fixture::load_from(root, name).unwrap().1; + eprintln!("{label}: fusion report {:?}", full.report); + let output = &full.body; + // Parameter tolerances absorb the bf16 backbone noise of the hand + // crops (2-3% relative), which the hand decoder amplifies more than + // the body decoder does; the keypoint tolerances are the contract. + let checks = [ + ("final_body_pose_params", output.body_pose.as_slice(), 2.0e-2), + ("final_hand_pose_params", output.hand.as_slice(), 5.0e-2), + ("final_scale_params", output.scale.as_slice(), 5.0e-2), + ("final_shape_params", output.shape.as_slice(), 5.0e-2), + ("final_pred_keypoints_3d", output.pred_keypoints_3d.as_slice(), 4.0e-3), + ("final_pred_keypoints_2d", output.pred_keypoints_2d.as_slice(), 1.0), + ]; + let mut failures = Vec::new(); + for (name, actual, tolerance) in checks { + let expected = field(name); + let (error, at) = max_abs(actual, &expected); + eprintln!("{label}: {name} max abs {error:.6} at {at} (ours {} reference {})", actual[at], expected[at]); + if error >= tolerance { + failures.push(format!("{name} max abs {error} at {at}, tolerance {tolerance}")); + } + } + assert!(failures.is_empty(), "{label}: {}", failures.join("; ")); + } + + #[test] + fn oracle_full_end_to_end() { + full_end_to_end(fixture::OracleRoot::Full, "oracle_full_end_to_end"); + } + + #[test] + fn oracle_hands_end_to_end() { + full_end_to_end(fixture::OracleRoot::Hands, "oracle_hands_end_to_end"); + } } diff --git a/libs/ai/models/body/src/pose.rs b/libs/ai/models/body/src/pose.rs index dc17f50d2..986c207af 100644 --- a/libs/ai/models/body/src/pose.rs +++ b/libs/ai/models/body/src/pose.rs @@ -71,6 +71,74 @@ pub fn rotmat_to_euler_zyx(matrix: [[f32; 3]; 3]) -> [f32; 3] { } } +/// roma's lowercase `xyz` (verified against the hand-mode rig oracle): +/// `R = Rz(z) * Ry(y) * Rx(x)`, the same order the rig applies to every +/// joint's `(rx, ry, rz)` triple. +pub fn euler_xyz_to_matrix([x, y, z]: [f32; 3]) -> [[f32; 3]; 3] { + let (sx, cx) = x.sin_cos(); + let (sy, cy) = y.sin_cos(); + let (sz, cz) = z.sin_cos(); + [ + [cz * cy, cz * sy * sx - sz * cx, cz * sy * cx + sz * sx], + [sz * cy, sz * sy * sx + cz * cx, sz * sy * cx - cz * sx], + [-sy, cy * sx, cy * cx], + ] +} + +/// Inverse of [`euler_xyz_to_matrix`], returning `(x, y, z)`. +pub fn matrix_to_euler_xyz(matrix: [[f32; 3]; 3]) -> [f32; 3] { + let cy = (matrix[0][0] * matrix[0][0] + matrix[1][0] * matrix[1][0]).sqrt(); + let y = (-matrix[2][0]).atan2(cy); + if cy < 1.0e-6 { + [(-matrix[1][2]).atan2(matrix[1][1]), y, 0.0] + } else { + [ + matrix[2][1].atan2(matrix[2][2]), + y, + matrix[1][0].atan2(matrix[0][0]), + ] + } +} + +/// Intrinsic `XZY`: input and output triples are convention ordered +/// `(x, z, y)`, and `R = Rx(x) * Rz(z) * Ry(y)`. +pub fn euler_xzy_to_matrix([x, z, y]: [f32; 3]) -> [[f32; 3]; 3] { + let (sx, cx) = x.sin_cos(); + let (sy, cy) = y.sin_cos(); + let (sz, cz) = z.sin_cos(); + [ + [cz * cy, -sz, cz * sy], + [cx * sz * cy + sx * sy, cx * cz, cx * sz * sy - sx * cy], + [sx * sz * cy - cx * sy, sx * cz, sx * sz * sy + cx * cy], + ] +} + +/// Inverse of [`euler_xzy_to_matrix`], returning convention-ordered +/// `(x, z, y)`. +pub fn matrix_to_euler_xzy(matrix: [[f32; 3]; 3]) -> [f32; 3] { + let cz = (matrix[0][0] * matrix[0][0] + matrix[0][2] * matrix[0][2]).sqrt(); + let z = (-matrix[0][1]).atan2(cz); + if cz < 1.0e-6 { + [(-matrix[1][2]).atan2(matrix[2][2]), z, 0.0] + } else { + [ + matrix[2][1].atan2(matrix[1][1]), + z, + matrix[0][2].atan2(matrix[0][0]), + ] + } +} + +pub fn matrix_mul(a: [[f32; 3]; 3], b: [[f32; 3]; 3]) -> [[f32; 3]; 3] { + std::array::from_fn(|row| { + std::array::from_fn(|column| (0..3).map(|k| a[row][k] * b[k][column]).sum()) + }) +} + +pub fn matrix_transpose(value: [[f32; 3]; 3]) -> [[f32; 3]; 3] { + std::array::from_fn(|row| std::array::from_fn(|column| value[column][row])) +} + /// Decode the 23 ball joints, 58 hinges, and six translations. pub fn body_cont_to_model_params(value: &[f32; 260]) -> [f32; 133] { let mut output = [0.0; 133]; @@ -214,10 +282,23 @@ pub fn camera_translation( bbox_side: f32, focal: f32, principal: [f32; 2], +) -> [f32; 3] { + camera_translation_scaled(pred_cam, bbox_center, bbox_side, focal, principal, 1.0) +} + +/// [`camera_translation`] with the camera head's `default_scale_factor` +/// multiplying the box size (1 for the body head, 10 for the hand head). +pub fn camera_translation_scaled( + pred_cam: [f32; 3], + bbox_center: [f32; 2], + bbox_side: f32, + focal: f32, + principal: [f32; 2], + scale_factor: f32, ) -> [f32; 3] { let scale = -pred_cam[0]; let ty = -pred_cam[2]; - let bbox_scale = bbox_side * scale + 1.0e-8; + let bbox_scale = bbox_side * scale * scale_factor + 1.0e-8; [ pred_cam[1] + 2.0 * (bbox_center[0] - principal[0]) / bbox_scale, ty + 2.0 * (bbox_center[1] - principal[1]) / bbox_scale, diff --git a/libs/ai/models/body/src/preprocess.rs b/libs/ai/models/body/src/preprocess.rs index 9ee5ef58a..31771243d 100644 --- a/libs/ai/models/body/src/preprocess.rs +++ b/libs/ai/models/body/src/preprocess.rs @@ -24,7 +24,7 @@ pub fn crop_geometry( image_h: usize, intrinsics: Option<[f32; 3]>, ) -> CropGeometry { - crop_geometry_at(bbox_xyxy, image_w, image_h, intrinsics, IMAGE_SIZE) + crop_geometry_at(bbox_xyxy, image_w, image_h, intrinsics, IMAGE_SIZE, 1.25) } pub fn crop_geometry_at( @@ -33,14 +33,15 @@ pub fn crop_geometry_at( image_h: usize, intrinsics: Option<[f32; 3]>, crop: usize, + padding: f32, ) -> CropGeometry { let center = [ 0.5 * (bbox_xyxy[0] + bbox_xyxy[2]), 0.5 * (bbox_xyxy[1] + bbox_xyxy[3]), ]; let mut scale = [ - (bbox_xyxy[2] - bbox_xyxy[0]) * 1.25, - (bbox_xyxy[3] - bbox_xyxy[1]) * 1.25, + (bbox_xyxy[2] - bbox_xyxy[0]) * padding, + (bbox_xyxy[3] - bbox_xyxy[1]) * padding, ]; if scale[0] > scale[1] * 0.75 { scale[1] = scale[0] / 0.75; @@ -97,6 +98,19 @@ pub fn crop_normalized( w: usize, h: usize, geo: &CropGeometry, +) -> Vec { + crop_normalized_mirrored(rgb, w, h, geo, false) +} + +/// Crop and normalise, optionally sampling the horizontally mirrored source +/// image. Mirroring happens before the affine warp, matching a real flipped +/// full-image buffer without allocating that buffer. +pub fn crop_normalized_mirrored( + rgb: &[u8], + w: usize, + h: usize, + geo: &CropGeometry, + mirror: bool, ) -> Vec { let crop = geo.crop; let mut output = vec![0.0; 3 * crop * crop]; @@ -124,7 +138,10 @@ pub fn crop_normalized( for (row, v) in (v0..).enumerate().take(planes[0].len() / crop) { let src_y = (v as f32 - geo.affine[5]) / k; for u in 0..crop { - let src_x = (u as f32 - geo.affine[2]) / k; + let mut src_x = (u as f32 - geo.affine[2]) / k; + if mirror { + src_x = w as f32 - 1.0 - src_x; + } for c in 0..3 { let pixel = bilinear_zero_border(rgb, w, h, src_x, src_y, c) / 255.0; planes[c][row * crop + u] = (pixel - IMAGENET_MEAN[c]) / IMAGENET_STD[c]; From 62dff2609267bdf733dc1c7d05c24b9557769ff5 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 01:29:15 +0200 Subject: [PATCH 040/417] =?UTF-8?q?ai-body:=20the=20mask=20prompt=20?= =?UTF-8?q?=E2=80=94=20a=20person's=20segmentation=20mask=20conditions=20t?= =?UTF-8?q?he=20body=20pass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BodyModel::infer_masked takes a provided person box and its full-frame 0/1 mask: the mask is warped with the crop's own affine (bilinear, rounded back to 0/1 like the reference's uint8 warp), encoded by the prompt encoder's mask CNN (four stride-2 convolutions with channel LayerNorm and erf GELU, then a 1x1 to 1280) and added to the backbone tokens before the ray conditioning, replacing the folded no-mask term. Oracle parity on the mask fixture: warp exact, every CNN stage within f32 accumulation noise, conditioned context 8e-4, end to end kp3d 2.2 mm / kp2d 0.25 px. 41 tests. Co-Authored-By: Claude Fable 5.1 --- libs/ai/models/body/src/condition.rs | 102 ++++++ libs/ai/models/body/src/fixture.rs | 2 + libs/ai/models/body/src/lib.rs | 1 + libs/ai/models/body/src/mask.rs | 504 +++++++++++++++++++++++++++ libs/ai/models/body/src/model.rs | 58 ++- 5 files changed, 666 insertions(+), 1 deletion(-) create mode 100644 libs/ai/models/body/src/mask.rs diff --git a/libs/ai/models/body/src/condition.rs b/libs/ai/models/body/src/condition.rs index b28a3ce0e..23f97cb77 100644 --- a/libs/ai/models/body/src/condition.rs +++ b/libs/ai/models/body/src/condition.rs @@ -10,6 +10,41 @@ const PE_HALF: usize = DINO_DIM / 2; const RAY_FEATURES: usize = 99; const RAY_FREQUENCIES: usize = 16; +/// Apply a supplied mask prompt before the existing ray-conditioning seam. +/// `None` performs no operation so the v1 no-mask path remains byte-for-byte +/// unchanged. For a mask, subtract the no-mask embedding because +/// [`RayCond::apply`] adds its projection back through the folded bias. +pub fn apply_mask_prompt( + x: &GpuTensor, + mask: Option<(&[f32], f32)>, + no_mask_embed: &[f32; DINO_DIM], +) -> Result> { + let Some((mask_tokens, mask_score)) = mask else { + return Ok(None); + }; + if x.cols() != DINO_DIM || mask_tokens.len() != x.rows() * DINO_DIM { + return Err(DiffusionError::workflow(format!( + "body mask conditioning shapes are x={}x{} mask={}, expected {} values", + x.rows(), + x.cols(), + mask_tokens.len(), + x.rows() * DINO_DIM, + ))); + } + let mut adjustment = vec![0.0f32; mask_tokens.len()]; + for (token, row) in adjustment.chunks_exact_mut(DINO_DIM).enumerate() { + let mask_row = &mask_tokens[token * DINO_DIM..(token + 1) * DINO_DIM]; + for channel in 0..DINO_DIM { + row[channel] = mask_score * mask_row[channel] - no_mask_embed[channel]; + } + } + let adjustment = gpu_upload(&adjustment, x.rows(), DINO_DIM) + .map_err(DiffusionError::model)?; + gpu_add(x, &adjustment) + .map(Some) + .map_err(DiffusionError::model) +} + pub fn dense_pe(g: &[f32]) -> Vec { dense_pe_at(g, PATCHES_SIDE) } @@ -335,4 +370,71 @@ mod tests { eprintln!("body ray conditioning max abs error: {max_error:.7}"); assert!(max_error <= 1e-3); } + + #[test] + fn gpu_oracle_mask_conditioned_context() { + use crate::fixture::OracleRoot; + + if crate::fixture::oracle_dir_for(OracleRoot::Mask).is_none() { + eprintln!("SKIP gpu_oracle_mask_conditioned_context: fixtures absent"); + return; + } + if !gpu_device_available() || !crate::fixture::gpu_required_ops_available() { + eprintln!("SKIP gpu_oracle_mask_conditioned_context: no GPU"); + return; + } + let Some(weights_path) = crate::fixture::weights_path_from(OracleRoot::Mask).or_else(crate::fixture::weights_path) else { + eprintln!("SKIP gpu_oracle_mask_conditioned_context: weights absent"); + return; + }; + let load = |name: &str| { + crate::fixture::load_from(OracleRoot::Mask, name) + .unwrap_or_else(|| panic!("missing mask fixture {name}")) + .1 + }; + let weights = BodyWeights::load(weights_path).expect("load body weights"); + let no_mask_values = weights + .f32_shaped("prompt_encoder.no_mask_embed.weight", &[1, DINO_DIM]) + .expect("load no-mask embedding"); + let mut no_mask = [0.0f32; DINO_DIM]; + no_mask.copy_from_slice(&no_mask_values); + + let image = planar_to_tokens(&load("image_embeddings_before_mask"), DINO_DIM); + let mask = planar_to_tokens(&load("mask_embeddings_raw"), DINO_DIM); + let score = load("batch_mask_score")[0]; + let image = gpu_upload(&image, NUM_PATCHES, DINO_DIM).expect("upload image embedding"); + let conditioned = apply_mask_prompt(&image, Some((&mask, score)), &no_mask) + .expect("apply mask prompt") + .expect("mask prompt result"); + + let image_shape = crate::fixture::load_from(OracleRoot::Mask, "input_rgb_u8") + .expect("input image") + .0; + let bbox_values = load("box_xyxy"); + let geo = crate::preprocess::crop_geometry_at( + [bbox_values[0], bbox_values[1], bbox_values[2], bbox_values[3]], + image_shape[1], + image_shape[0], + None, + crate::IMAGE_SIZE, + 1.25, + ); + let feats = ray_features(&crate::preprocess::patch_rays(&geo)); + let ray_cond = RayCond::prepare(&weights).expect("prepare ray conditioning"); + let actual = ray_cond + .apply(&conditioned, &no_mask, &feats) + .expect("ray conditioning"); + let actual = gpu_download(&actual).expect("download ray conditioning"); + let expected = planar_to_tokens(&load("raycond_out_0"), DINO_DIM); + let (maximum, at) = actual + .iter() + .zip(&expected) + .enumerate() + .map(|(index, (actual, expected))| ((actual - expected).abs(), index)) + .fold((0.0f32, 0usize), |best, value| { + if value.0 > best.0 { value } else { best } + }); + eprintln!("body masked raycond_out_0: max {maximum:.7} at {at}"); + assert!(maximum <= 5e-3, "raycond_out_0 max abs {maximum} at {at}"); + } } diff --git a/libs/ai/models/body/src/fixture.rs b/libs/ai/models/body/src/fixture.rs index b096ca39f..831885672 100644 --- a/libs/ai/models/body/src/fixture.rs +++ b/libs/ai/models/body/src/fixture.rs @@ -10,6 +10,7 @@ pub enum OracleRoot { Body, Full, Hands, + Mask, } impl OracleRoot { @@ -18,6 +19,7 @@ impl OracleRoot { Self::Body => "oracle", Self::Full => "oracle_full", Self::Hands => "oracle_hands", + Self::Mask => "oracle_mask", } } } diff --git a/libs/ai/models/body/src/lib.rs b/libs/ai/models/body/src/lib.rs index 933d11426..f4d041980 100644 --- a/libs/ai/models/body/src/lib.rs +++ b/libs/ai/models/body/src/lib.rs @@ -29,6 +29,7 @@ pub mod condition; pub mod decoder; pub mod dino; pub mod hands; +pub mod mask; mod heads; pub mod mhr; pub mod model; diff --git a/libs/ai/models/body/src/mask.rs b/libs/ai/models/body/src/mask.rs new file mode 100644 index 000000000..6a4f84759 --- /dev/null +++ b/libs/ai/models/body/src/mask.rs @@ -0,0 +1,504 @@ +//! Segmentation-mask prompt preprocessing and the mask-downscaling encoder. + +use crate::preprocess::CropGeometry; +use crate::weights::BodyWeights; +use crate::{Result, DINO_DIM, IMAGE_SIZE, NUM_PATCHES, PATCHES_SIDE}; + +const NORM_EPS: f32 = 1e-6; + +struct Conv { + input: usize, + output: usize, + kernel: usize, + weight: Vec, + bias: Vec, +} + +impl Conv { + fn load( + weights: &BodyWeights, + index: usize, + input: usize, + output: usize, + kernel: usize, + ) -> Result { + let name = format!("prompt_encoder.mask_downscaling.{index}"); + Ok(Self { + input, + output, + kernel, + weight: weights.f32_shaped( + &format!("{name}.weight"), + &[output, input, kernel, kernel], + )?, + bias: weights.f32_shaped(&format!("{name}.bias"), &[output])?, + }) + } + + /// Valid convolution. The stride equals the kernel for the four 2x2 + /// layers, making them non-overlapping patchify + linear operations. + fn forward(&self, input: &[f32], side: usize) -> Vec { + assert_eq!(input.len(), self.input * side * side); + let stride = self.kernel; + let output_side = (side - self.kernel) / stride + 1; + let input_plane = side * side; + let output_plane = output_side * output_side; + let mut output = vec![0.0f32; self.output * output_plane]; + let threads = std::thread::available_parallelism() + .map(|count| count.get()) + .unwrap_or(1) + .min(self.output); + let channels_per_thread = self.output.div_ceil(threads); + std::thread::scope(|scope| { + for (band, output_band) in output + .chunks_mut(channels_per_thread * output_plane) + .enumerate() + { + let output_channel_start = band * channels_per_thread; + scope.spawn(move || { + for (local_channel, output_channel) in + output_band.chunks_mut(output_plane).enumerate() + { + let oc = output_channel_start + local_channel; + let weight_base = oc * self.input * self.kernel * self.kernel; + for oy in 0..output_side { + for ox in 0..output_side { + let mut value = self.bias[oc]; + for ic in 0..self.input { + let input_base = ic * input_plane + + oy * stride * side + + ox * stride; + let kernel_base = weight_base + + ic * self.kernel * self.kernel; + for ky in 0..self.kernel { + for kx in 0..self.kernel { + value += input[input_base + ky * side + kx] + * self.weight[ + kernel_base + ky * self.kernel + kx + ]; + } + } + } + output_channel[oy * output_side + ox] = value; + } + } + } + }); + } + }); + output + } +} + +struct LayerNorm2d { + channels: usize, + weight: Vec, + bias: Vec, +} + +impl LayerNorm2d { + fn load(weights: &BodyWeights, index: usize, channels: usize) -> Result { + let name = format!("prompt_encoder.mask_downscaling.{index}"); + Ok(Self { + channels, + weight: weights.f32_shaped(&format!("{name}.weight"), &[channels])?, + bias: weights.f32_shaped(&format!("{name}.bias"), &[channels])?, + }) + } + + fn forward(&self, input: &[f32], side: usize) -> Vec { + let plane = side * side; + assert_eq!(input.len(), self.channels * plane); + let mut output = vec![0.0f32; input.len()]; + for pixel in 0..plane { + let mut mean = 0.0f32; + for channel in 0..self.channels { + mean += input[channel * plane + pixel]; + } + mean /= self.channels as f32; + let mut variance = 0.0f32; + for channel in 0..self.channels { + let centered = input[channel * plane + pixel] - mean; + variance += centered * centered; + } + variance /= self.channels as f32; + let inverse_std = (variance + NORM_EPS).sqrt().recip(); + for channel in 0..self.channels { + output[channel * plane + pixel] = + (input[channel * plane + pixel] - mean) * inverse_std + * self.weight[channel] + + self.bias[channel]; + } + } + output + } +} + +/// The five mask-prompt convolutions and four per-pixel channel norms. +pub struct MaskEmbed { + conv0: Conv, + norm1: LayerNorm2d, + conv3: Conv, + norm4: LayerNorm2d, + conv6: Conv, + norm7: LayerNorm2d, + conv9: Conv, + norm10: LayerNorm2d, + conv12: Conv, + no_mask_embed: [f32; DINO_DIM], +} + +impl MaskEmbed { + pub fn load(weights: &BodyWeights) -> Result { + let no_mask = weights.f32_shaped( + "prompt_encoder.no_mask_embed.weight", + &[1, DINO_DIM], + )?; + let mut no_mask_embed = [0.0f32; DINO_DIM]; + no_mask_embed.copy_from_slice(&no_mask); + Ok(Self { + conv0: Conv::load(weights, 0, 1, 4, 2)?, + norm1: LayerNorm2d::load(weights, 1, 4)?, + conv3: Conv::load(weights, 3, 4, 16, 2)?, + norm4: LayerNorm2d::load(weights, 4, 16)?, + conv6: Conv::load(weights, 6, 16, 64, 2)?, + norm7: LayerNorm2d::load(weights, 7, 64)?, + conv9: Conv::load(weights, 9, 64, 256, 2)?, + norm10: LayerNorm2d::load(weights, 10, 256)?, + conv12: Conv::load(weights, 12, 256, DINO_DIM, 1)?, + no_mask_embed, + }) + } + + pub fn no_mask_embed(&self) -> &[f32; DINO_DIM] { + &self.no_mask_embed + } + + /// Embed one 512x512 crop-space mask. The result is `[1024, 1280]`, + /// token-major like the backbone output. + pub fn embed(&self, crop_mask: &[f32]) -> Vec { + let planar = self.embed_planar(crop_mask, |_, _| {}); + let mut tokens = vec![0.0f32; NUM_PATCHES * DINO_DIM]; + for channel in 0..DINO_DIM { + for token in 0..NUM_PATCHES { + tokens[token * DINO_DIM + channel] = + planar[channel * NUM_PATCHES + token]; + } + } + tokens + } + + fn embed_planar( + &self, + crop_mask: &[f32], + mut stage: impl FnMut(usize, &[f32]), + ) -> Vec { + assert_eq!( + crop_mask.len(), + IMAGE_SIZE * IMAGE_SIZE, + "mask prompt must be 512x512" + ); + let mut side = IMAGE_SIZE; + let mut values = self.conv0.forward(crop_mask, side); + side /= 2; + stage(0, &values); + values = self.norm1.forward(&values, side); + stage(1, &values); + gelu_erf_in_place(&mut values); + + values = self.conv3.forward(&values, side); + side /= 2; + stage(3, &values); + values = self.norm4.forward(&values, side); + stage(4, &values); + gelu_erf_in_place(&mut values); + + values = self.conv6.forward(&values, side); + side /= 2; + stage(6, &values); + values = self.norm7.forward(&values, side); + stage(7, &values); + gelu_erf_in_place(&mut values); + + values = self.conv9.forward(&values, side); + side /= 2; + stage(9, &values); + values = self.norm10.forward(&values, side); + stage(10, &values); + gelu_erf_in_place(&mut values); + + values = self.conv12.forward(&values, side); + stage(12, &values); + debug_assert_eq!(side, PATCHES_SIDE); + values + } +} + +fn gelu_erf_in_place(values: &mut [f32]) { + // Abramowitz-Stegun 7.1.26 is accurate to 1.5e-7 in erf, below f32 + // precision for this encoder, and avoids a dependency solely for erf. + for value in values { + let x = *value / std::f32::consts::SQRT_2; + let sign = if x < 0.0 { -1.0 } else { 1.0 }; + let ax = x.abs(); + let t = 1.0 / (1.0 + 0.327_591_1 * ax); + let polynomial = ((((1.061_405_4 * t - 1.453_152_1) * t + 1.421_413_8) * t + - 0.284_496_72) + * t + + 0.254_829_6) + * t; + let erf = sign * (1.0 - polynomial * (-ax * ax).exp()); + *value = 0.5 * *value * (1.0 + erf); + } +} + +/// Warp a full-frame uint8 0/1 mask through the image crop's affine. Sampling +/// is bilinear at inverse-mapped integer crop-pixel centres with zero padding; +/// cv2 preserves the uint8 dtype, so its interpolated result is rounded back +/// to 0/1 before being widened to the returned f32 values. +pub fn warp_mask(full_mask: &[u8], w: usize, h: usize, geo: &CropGeometry) -> Vec { + assert_eq!(full_mask.len(), w * h, "full mask dimensions do not match"); + let crop = geo.crop; + let mut output = vec![0.0f32; crop * crop]; + // The reference obtains this affine from cv2's double-precision point + // solve before storing it as f32. Reconstructing from the geometry avoids + // magnifying the few last-bit differences in the simplified f32 matrix + // when the uint8 result lands exactly on its 0.5 rounding threshold. + let k_f64 = crop as f64 / geo.side as f64; + let k = k_f64 as f32; + let offset_x = (0.5 * crop as f64 - k_f64 * geo.center[0] as f64) as f32; + let offset_y = (0.5 * crop as f64 - k_f64 * geo.center[1] as f64) as f32; + for v in 0..crop { + let y = (v as f32 - offset_y) / k; + let y0 = y.floor() as isize; + let fy = y - y0 as f32; + for u in 0..crop { + let x = (u as f32 - offset_x) / k; + let x0 = x.floor() as isize; + let fx = x - x0 as f32; + let at = |xx: isize, yy: isize| -> f32 { + if xx < 0 || yy < 0 || xx >= w as isize || yy >= h as isize { + 0.0 + } else { + full_mask[yy as usize * w + xx as usize] as f32 + } + }; + let top = at(x0, y0) * (1.0 - fx) + at(x0 + 1, y0) * fx; + let bottom = at(x0, y0 + 1) * (1.0 - fx) + at(x0 + 1, y0 + 1) * fx; + output[v * crop + u] = if top * (1.0 - fy) + bottom * fy > 0.5 { + 1.0 + } else { + 0.0 + }; + } + } + output +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::fixture::{self, OracleRoot}; + use crate::preprocess::{crop_geometry_at, crop_normalized}; + + fn mask_fixture(name: &str) -> Option<(Vec, Vec)> { + fixture::load_from(OracleRoot::Mask, name) + } + + fn max_and_mean_abs(actual: &[f32], expected: &[f32]) -> (f32, f32, usize) { + assert_eq!(actual.len(), expected.len()); + let mut maximum = 0.0f32; + let mut maximum_at = 0usize; + let mut sum = 0.0f32; + for (index, (&actual, &expected)) in actual.iter().zip(expected).enumerate() { + let error = (actual - expected).abs(); + sum += error; + if error > maximum { + maximum = error; + maximum_at = index; + } + } + (maximum, sum / actual.len() as f32, maximum_at) + } + + #[test] + fn oracle_mask_crop_geometry_image_and_warp() { + let Some((image_shape, image)) = mask_fixture("input_rgb_u8") else { + eprintln!("SKIP oracle_mask_crop_geometry_image_and_warp: fixtures absent"); + return; + }; + let (h, w) = (image_shape[0], image_shape[1]); + let box_values = mask_fixture("box_xyxy").expect("box_xyxy").1; + let bbox = [box_values[0], box_values[1], box_values[2], box_values[3]]; + let geo = crop_geometry_at(bbox, w, h, None, IMAGE_SIZE, 1.25); + + let center = mask_fixture("batch_bbox_center").expect("bbox center").1; + let scale = mask_fixture("batch_bbox_scale").expect("bbox scale").1; + let affine = mask_fixture("batch_affine_trans").expect("affine").1; + let center_error = max_and_mean_abs(&geo.center, ¢er).0; + let scale_error = max_and_mean_abs(&[geo.side, geo.side], &scale).0; + let affine_error = max_and_mean_abs(&geo.affine, &affine).0; + eprintln!( + "body mask crop geometry: center {center_error:.7}, scale {scale_error:.7}, affine {affine_error:.7} max abs" + ); + assert!(center_error <= 1e-4); + assert!(scale_error <= 1e-4); + assert!(affine_error <= 1e-4); + + let rgb: Vec = image.into_iter().map(|value| value as u8).collect(); + let mut crop = crop_normalized(&rgb, w, h, &geo); + let plane = IMAGE_SIZE * IMAGE_SIZE; + let mean = [0.485f32, 0.456, 0.406]; + let std = [0.229f32, 0.224, 0.225]; + for channel in 0..3 { + for value in &mut crop[channel * plane..(channel + 1) * plane] { + *value = *value * std[channel] + mean[channel]; + } + } + let expected_crop = mask_fixture("batch_img").expect("batch_img").1; + let (crop_max, crop_mean, crop_at) = max_and_mean_abs(&crop, &expected_crop); + eprintln!( + "body mask image crop: max {crop_max:.7} mean {crop_mean:.7} at {crop_at}" + ); + assert!(crop_max <= 2e-2); + + let full_mask: Vec = mask_fixture("mask_full_u8") + .expect("mask_full_u8") + .1 + .into_iter() + .map(|value| value as u8) + .collect(); + let actual_mask = warp_mask(&full_mask, w, h, &geo); + let expected_mask = mask_fixture("batch_mask").expect("batch_mask").1; + let (mask_max, mask_mean, mask_at) = + max_and_mean_abs(&actual_mask, &expected_mask); + eprintln!( + "body mask warp: max {mask_max:.7} mean {mask_mean:.7} at {mask_at}" + ); + if mask_max > 2e-2 { + let mismatches: Vec<_> = actual_mask + .iter() + .zip(&expected_mask) + .enumerate() + .filter(|(_, (actual, expected))| (*actual - *expected).abs() > 2e-2) + .take(32) + .map(|(index, (actual, expected))| { + (index % IMAGE_SIZE, index / IMAGE_SIZE, *actual, *expected) + }) + .collect(); + eprintln!("body mask warp mismatches: {mismatches:?}"); + } + assert!(mask_max <= 2e-2); + } + + #[test] + fn oracle_mask_downscaling_stages() { + if fixture::oracle_dir_for(OracleRoot::Mask).is_none() { + eprintln!("SKIP oracle_mask_downscaling_stages: fixtures absent"); + return; + } + let Some(weights_path) = fixture::weights_path_from(OracleRoot::Mask).or_else(fixture::weights_path) else { + eprintln!("SKIP oracle_mask_downscaling_stages: weights absent"); + return; + }; + let weights = BodyWeights::load(weights_path).expect("load body weights"); + let encoder = MaskEmbed::load(&weights).expect("load mask encoder"); + let input = mask_fixture("mask_prompt_in").expect("mask_prompt_in").1; + let mut captures = Vec::new(); + let planar = encoder.embed_planar(&input, |index, values| { + captures.push((index, values.to_vec())); + }); + for (index, actual) in captures { + let field = format!("maskds{index}_out_0"); + let expected = mask_fixture(&field).unwrap_or_else(|| panic!("missing {field}")).1; + let (max, mean, at) = max_and_mean_abs(&actual, &expected); + eprintln!("body {field}: max {max:.7} mean {mean:.7} at {at}"); + // The last two convolutions sum 256 and 1024 products in a + // different order than the reference: f32 accumulation noise. + let tolerance = if index >= 9 { 5e-3 } else { 1e-4 }; + assert!(max <= tolerance, "{field} max abs {max} at {at}"); + } + let expected = mask_fixture("mask_embeddings_raw") + .expect("mask_embeddings_raw") + .1; + let (max, mean, at) = max_and_mean_abs(&planar, &expected); + eprintln!("body mask_embeddings_raw: max {max:.7} mean {mean:.7} at {at}"); + assert!(max <= 1e-4, "mask_embeddings_raw max abs {max} at {at}"); + + let no_mask = mask_fixture("no_mask_embeddings") + .expect("no_mask_embeddings") + .1; + let mut no_mask_max = 0.0f32; + for channel in 0..DINO_DIM { + for token in 0..NUM_PATCHES { + no_mask_max = no_mask_max.max( + (encoder.no_mask_embed[channel] + - no_mask[channel * NUM_PATCHES + token]) + .abs(), + ); + } + } + eprintln!("body no_mask_embeddings: max {no_mask_max:.7}"); + assert!(no_mask_max <= 1e-7); + } + + #[test] + fn gpu_oracle_infer_masked_end_to_end() { + use crate::backend::gpu_device_available; + use crate::model::BodyModel; + + if fixture::oracle_dir_for(OracleRoot::Mask).is_none() { + eprintln!("SKIP gpu_oracle_infer_masked_end_to_end: fixtures absent"); + return; + } + if !gpu_device_available() || !fixture::gpu_required_ops_available() { + eprintln!("SKIP gpu_oracle_infer_masked_end_to_end: no GPU"); + return; + } + let Some(weights_path) = fixture::weights_path_from(OracleRoot::Mask).or_else(fixture::weights_path) else { + eprintln!("SKIP gpu_oracle_infer_masked_end_to_end: weights absent"); + return; + }; + let (image_shape, image) = mask_fixture("input_rgb_u8").expect("input image"); + let (h, w) = (image_shape[0], image_shape[1]); + let rgb: Vec = image.into_iter().map(|value| value as u8).collect(); + let mask: Vec = mask_fixture("mask_full_u8") + .expect("full mask") + .1 + .into_iter() + .map(|value| value as u8) + .collect(); + let box_values = mask_fixture("box_xyxy").expect("box_xyxy").1; + let bbox = [box_values[0], box_values[1], box_values[2], box_values[3]]; + let score = mask_fixture("batch_mask_score").expect("mask score").1[0]; + let mut model = BodyModel::load(&weights_path).expect("load body model"); + model.correctives_every_step = true; + let packet = model + .infer_masked(&rgb, w as u32, h as u32, bbox, Some((&mask, score))) + .expect("masked inference"); + let person = &packet.people[0]; + let kp3d = mask_fixture("final_pred_keypoints_3d") + .expect("final 3d keypoints") + .1; + let kp2d = mask_fixture("final_pred_keypoints_2d") + .expect("final 2d keypoints") + .1; + let (error3d, mean3d, at3d) = max_and_mean_abs(&person.kp3d, &kp3d); + let (error2d, mean2d, at2d) = max_and_mean_abs(&person.kp2d, &kp2d); + eprintln!( + "body infer_masked: kp3d max {error3d:.7} m mean {mean3d:.7} at {at3d}; kp2d max {error2d:.4} px mean {mean2d:.4} at {at2d}" + ); + // The same bf16 backbone noise budget as the full-mode tests. + assert!(error3d <= 4e-3, "masked kp3d max abs {error3d} m at {at3d}"); + assert!(error2d <= 1.0, "masked kp2d max abs {error2d} px at {at2d}"); + } + + #[test] + fn gelu_is_erf_form() { + let mut values = [-1.0, 0.0, 1.0]; + gelu_erf_in_place(&mut values); + assert!((values[0] + 0.158_655_26).abs() < 2e-7); + assert_eq!(values[1], 0.0); + assert!((values[2] - 0.841_344_7).abs() < 2e-7); + } +} diff --git a/libs/ai/models/body/src/model.rs b/libs/ai/models/body/src/model.rs index a575e8077..43d12a8ce 100644 --- a/libs/ai/models/body/src/model.rs +++ b/libs/ai/models/body/src/model.rs @@ -7,10 +7,11 @@ //! parameters come from the body decoder, the hand crops of the reference's //! "full" mode are a later phase. -use crate::condition::{dense_pe_at, ray_features, RayCond}; +use crate::condition::{apply_mask_prompt, dense_pe_at, ray_features, RayCond}; use crate::decoder::{Decoder, LoopTiming, StepFeedback, StepInput}; use crate::dino::BodyDino; use crate::hands::{hand_crops, BodyImage, FusionReport, HandBranch, HandOutput}; +use crate::mask::{warp_mask, MaskEmbed}; use crate::mhr::MhrRig; use crate::packet::{BodyPacket, BodyPerson}; use crate::pose::{camera_translation, model_params, project, unpack_pose}; @@ -35,6 +36,8 @@ pub struct BodyModel { pub(crate) decoder: Decoder, pub(crate) rig: MhrRig, hands: Option, + /// The mask-prompt encoder, loaded on the first masked call. + mask_embed: Option, /// The crop side the backbone sees; 512 is the trained size, smaller is /// faster and less accurate (see `set_crop_size`). crop_size: usize, @@ -114,6 +117,7 @@ impl BodyModel { decoder, rig, hands: None, + mask_embed: None, crop_size: IMAGE_SIZE, correctives_every_step: false, last_stage_ms: [0.0; 5], @@ -163,6 +167,31 @@ impl BodyModel { width: u32, height: u32, bbox: Option<[f32; 4]>, + ) -> Result { + self.infer_with(rgb, width, height, bbox, None) + } + + /// [`Self::infer`] for one provided person box, optionally conditioned + /// by that person's full-frame 0/1 segmentation mask and its confidence + /// (the reference's mask prompt; spec 13.2). + pub fn infer_masked( + &mut self, + rgb: &[u8], + width: u32, + height: u32, + bbox: [f32; 4], + mask: Option<(&[u8], f32)>, + ) -> Result { + self.infer_with(rgb, width, height, Some(bbox), mask) + } + + fn infer_with( + &mut self, + rgb: &[u8], + width: u32, + height: u32, + bbox: Option<[f32; 4]>, + mask: Option<(&[u8], f32)>, ) -> Result { let (w, h) = (width as usize, height as usize); if rgb.len() != w * h * 3 { @@ -172,15 +201,42 @@ impl BodyModel { w * h * 3 ))); } + if let Some((full_mask, _)) = mask { + if full_mask.len() != w * h { + return Err(DiffusionError::workflow(format!( + "body infer mask: {} bytes for {width}x{height}, expected {}", + full_mask.len(), + w * h + ))); + } + if self.crop_size != IMAGE_SIZE { + return Err(DiffusionError::workflow(format!( + "body mask prompts require the {IMAGE_SIZE}px crop, current crop is {}", + self.crop_size + ))); + } + } let bbox = bbox.unwrap_or([0.0, 0.0, width as f32, height as f32]); let total = Instant::now(); let geo = crop_geometry_at(bbox, w, h, None, self.crop_size, 1.25); let crop = crop_normalized(rgb, w, h, &geo); + let crop_mask = mask.map(|(full_mask, _)| warp_mask(full_mask, w, h, &geo)); let t_crop = total.elapsed(); let embeddings = self.dino.forward_normalized(&crop)?; let t_backbone = total.elapsed(); + let embeddings = match (crop_mask, mask) { + (Some(crop_mask), Some((_, score))) => { + if self.mask_embed.is_none() { + self.mask_embed = Some(MaskEmbed::load(&self.weights)?); + } + let tokens = self.mask_embed.as_ref().unwrap().embed(&crop_mask); + apply_mask_prompt(&embeddings, Some((&tokens, score)), &self.no_mask_embed)? + .unwrap_or(embeddings) + } + _ => embeddings, + }; let feats = ray_features(&patch_rays(&geo)); let context = self.ray_cond.apply(&embeddings, &self.no_mask_embed, &feats)?; drop(embeddings); From a648cf8808c28b0560d3e414ef39cac8689a81f6 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 01:36:25 +0200 Subject: [PATCH 041/417] =?UTF-8?q?ai-hub:=20body=20session=20options=20?= =?UTF-8?q?=E2=80=94=20hands,=20detect,=20persons=3DN?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sam3dbody backend reads its options from the request's prompt string (`hands`, `detect`, `persons=N`): `hands` runs the full mode and the packet carries which hands were fused and their boxes; `detect` finds up to N persons with SAM 3.1 (an optional native-segment role on the body entry, the same artifact the segment entry pins) and runs one body pass per person with its box and mask, so the packet's people array grows. The body crate shares one body pass between the packet, mask and hands entry points, and infer_full takes the mask prompt too. Co-Authored-By: Claude Fable 5.1 --- libs/ai/hub/registry.json | 71 +++++++- libs/ai/hub/src/body_native_backend.rs | 223 +++++++++++++++++++++++-- libs/ai/hub/src/registry.rs | 66 +++++++- libs/ai/models/body/src/model.rs | 130 +++++++------- libs/ai/models/body/src/packet.rs | 21 +++ 5 files changed, 435 insertions(+), 76 deletions(-) diff --git a/libs/ai/hub/registry.json b/libs/ai/hub/registry.json index cfe5cccd7..09ab3ebb0 100644 --- a/libs/ai/hub/registry.json +++ b/libs/ai/hub/registry.json @@ -1,5 +1,64 @@ { "models": [ + { + "id": "beat-this", + "domain": "beats", + "backend": "beats", + "available": true, + "gated": false, + "license": { + "name": "MIT License", + "url": "https://github.com/CPJKU/beat_this", + "summary": "Beat This! beat and downbeat tracker (Foscarin, Schl\u00fcter, Widmer 2024), code and released weights MIT; training data partly copyrighted \u2014 weights are unrestricted.", + "restriction": "none" + }, + "vram_gb": 0.5, + "note": "Contract: input_b64 is a WAV, MP3, FLAC or Ogg Vorbis file at any sample rate/channel count; the backend downmixes and resamples to 22050 Hz. Output is one application/json artifact: {bpm, confidence, beats:[seconds], downbeats:[seconds], frame_rate:50}.", + "files": [ + { + "role": "weights", + "repo": "CPJKU/beat_this", + "path": "https://cloud.cp.jku.at/public.php/dav/files/7ik4RrBKTS273gp/final0.ckpt", + "cache_as": "beats/beat_this_final0.ckpt", + "size": 81058141, + "sha256": "8c328b45f59d8dd3dff219253ff6a8d6482be57d0133a29140e2febbf8eb8331" + }, + { + "role": "weights-small", + "repo": "CPJKU/beat_this", + "path": "https://cloud.cp.jku.at/public.php/dav/files/7ik4RrBKTS273gp/small0.ckpt", + "cache_as": "beats/beat_this_small0.ckpt", + "size": 8451101, + "sha256": "6074be2c4d490c5f6101fcc374a1ec72ae93456e23bb6019783b849f5dc7d47b", + "optional": true + } + ] + }, + { + "id": "basic-pitch", + "domain": "notes", + "backend": "notes", + "available": true, + "gated": false, + "license": { + "name": "Apache License 2.0", + "url": "https://github.com/spotify/basic-pitch", + "summary": "Spotify Basic Pitch instrument-agnostic polyphonic note transcription model (ICASSP 2022), Apache-2.0 code and weights; permissive incl. commercial.", + "restriction": "none" + }, + "vram_gb": 0.1, + "note": "Request: domain notes with input_b64 containing a PCM WAV (16/24/32-bit integer or f32, any sample rate/channels). Response artifacts: application/json {frame_rate,notes:[{start_secs,end_secs,midi,amplitude,bends:[semitones_per_frame]}]} and audio/midi .mid bytes with per-note pitch bends in the standard +/-2-semitone range.", + "files": [ + { + "role": "model", + "repo": "spotify/basic-pitch", + "path": "https://github.com/spotify/basic-pitch/raw/main/basic_pitch/saved_models/icassp_2022/nmp.onnx", + "cache_as": "notes/basic_pitch_nmp.onnx", + "size": 230444, + "sha256": "2c3c1d144bfa61ad236e92e169c13535c880469a12a047d4e73451f2c059a0ec" + } + ] + }, { "id": "hunyuan3d-paint-2.1", "domain": "paint", @@ -1780,7 +1839,7 @@ "restriction": "community" }, "vram_gb": 4.5, - "note": "SAM 3D Body (Comfy-Org/sam-3d-body, SAM License) RGB image -> application/json human pose packet. Native Rust inference; no Python, Torch, subprocess, or silent fallback. facebook/* checkpoints are never fetched. The checkpoint is pinned to an immutable revision, byte size, and SHA-256.", + "note": "SAM 3D Body (Comfy-Org/sam-3d-body, SAM License) RGB image -> application/json human pose packet. Native Rust inference; no Python, Torch, subprocess, or silent fallback. facebook/* checkpoints are never fetched. The checkpoint is pinned to an immutable revision, byte size, and SHA-256. Options ride the prompt string: `hands` (both hand crops, wrist fusion), `detect` (SAM 3.1 person detection, needs the optional native-segment weights), `persons=N` (max persons for detect).", "files": [ { "role": "native-body", @@ -1790,6 +1849,16 @@ "cache_as": "body/sam3dbody/sam_3d_body_dinov3_bf16.safetensors", "size": 2830737652, "sha256": "59fa45200c504c5b56625004d7d3385daf48c616613e88099e43bf83b3e249cf" + }, + { + "role": "native-segment", + "repo": "Comfy-Org/sam3.1", + "path": "checkpoints/sam3.1_multiplex_fp16.safetensors", + "revision": "f38cd62b71494b53ac2b56ca36e24f3c8d565581", + "cache_as": "segment/sam3-1-multiplex/sam3.1_multiplex_fp16.safetensors", + "size": 1745546848, + "sha256": "9ba99c92703c2e8b4f47de2d34a539bb8e18923049e238b780d70dbe6368eb03", + "optional": true } ] }, diff --git a/libs/ai/hub/src/body_native_backend.rs b/libs/ai/hub/src/body_native_backend.rs index e8ccfe9aa..ad97522a9 100644 --- a/libs/ai/hub/src/body_native_backend.rs +++ b/libs/ai/hub/src/body_native_backend.rs @@ -9,11 +9,77 @@ use crate::subproc_img::png_header; #[cfg(feature = "body-native")] use makepad_ai_body::model::BodyModel; #[cfg(feature = "body-native")] +use makepad_ai_body::packet::BodyPacket; +#[cfg(feature = "body-native")] use makepad_ai_common::DiffusionError; +#[cfg(all(feature = "body-native", feature = "segment-native"))] +use makepad_ai_vision::sam3::{Sam3, Sam3Image, Sam3Weights}; #[cfg(feature = "body-native")] use std::path::PathBuf; use std::time::Instant; +/// Per-request options of the body domain, parsed from the request's +/// free-text prompt (`prompt` on `/generate`, `LiveConfig.prompt` on a +/// realtime session): whitespace- or comma-separated words. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct BodyOptions { + /// Run the hand crops, the hand decoder and the wrist fusion. + pub hands: bool, + /// Find persons with SAM 3.1 (`person:N`) and run one pass per person + /// with its box and mask; otherwise the frame (or the request's box) + /// is one person. + pub detect: bool, + /// Upper bound on detected persons. + pub persons: usize, +} + +impl Default for BodyOptions { + fn default() -> Self { + Self { + hands: false, + detect: false, + persons: 1, + } + } +} + +impl BodyOptions { + pub const MAX_PERSONS: usize = 8; + + pub fn parse(prompt: &str) -> Result { + let mut options = Self::default(); + for word in prompt + .split(|c: char| c.is_whitespace() || c == ',') + .filter(|word| !word.is_empty()) + { + match word { + "hands" => options.hands = true, + "detect" => options.detect = true, + _ if word.starts_with("persons=") => { + let count = word["persons=".len()..].parse::().ok(); + match count { + Some(count) if (1..=Self::MAX_PERSONS).contains(&count) => { + options.persons = count + } + _ => { + return Err(AssetAiError::Params(format!( + "sam3dbody: persons must be 1..={} (got {word:?})", + Self::MAX_PERSONS + ))) + } + } + } + other => { + return Err(AssetAiError::Params(format!( + "sam3dbody: unknown option {other:?} (hands, detect, persons=N)" + ))) + } + } + } + Ok(options) + } +} + /// Pluggable inference for CPU-only backend tests. pub type BodyFn = Box< dyn FnMut(&[u8], u32, u32, Option<[f32; 4]>) -> Result + Send, @@ -32,6 +98,12 @@ pub struct BodyNativeBackend { model_path: Option, #[cfg(feature = "body-native")] model: Option, + /// The optional detector weights (role `native-segment`), when the + /// registry could fetch them; loaded on the first `detect` request. + #[cfg(all(feature = "body-native", feature = "segment-native"))] + segment_path: Option, + #[cfg(all(feature = "body-native", feature = "segment-native"))] + segment: Option, } impl BodyNativeBackend { @@ -43,6 +115,10 @@ impl BodyNativeBackend { model_path: None, #[cfg(feature = "body-native")] model: None, + #[cfg(all(feature = "body-native", feature = "segment-native"))] + segment_path: None, + #[cfg(all(feature = "body-native", feature = "segment-native"))] + segment: None, } } @@ -53,6 +129,10 @@ impl BodyNativeBackend { gen: Gen::Native, model_path: None, model: None, + #[cfg(feature = "segment-native")] + segment_path: None, + #[cfg(feature = "segment-native")] + segment: None, } } @@ -62,20 +142,30 @@ impl BodyNativeBackend { width: u32, height: u32, bbox: Option<[f32; 4]>, + options: BodyOptions, ) -> Result { let packet = match &mut self.gen { Gen::Stub(gen) => gen(rgb, width, height, bbox)?, #[cfg(feature = "body-native")] Gen::Native => { - let model = self.model.as_mut().ok_or_else(|| { - AssetAiError::Backend( - "native body used before ensure_loaded".to_string(), - ) - })?; let start = Instant::now(); - let mut packet = model - .infer(rgb, width, height, bbox) - .map_err(diffusion_err)?; + let mut packet = if options.detect { + self.infer_detected(rgb, width, height, options)? + } else { + let model = self.model.as_mut().ok_or_else(|| { + AssetAiError::Backend( + "native body used before ensure_loaded".to_string(), + ) + })?; + if options.hands { + model + .infer_full(rgb, width, height, bbox, None) + .map_err(diffusion_err)? + .into_packet(0.0) + } else { + model.infer(rgb, width, height, bbox).map_err(diffusion_err)? + } + }; packet.ms = start.elapsed().as_secs_f32() * 1000.0; packet.to_json() } @@ -83,6 +173,85 @@ impl BodyNativeBackend { crate::body_backend::validate_pose_packet(&packet)?; Ok(packet) } + + /// `detect`: SAM 3.1 finds up to `options.persons` persons, then every + /// person gets a body pass on its own box with its mask (spec 13.3). + #[cfg(all(feature = "body-native", feature = "segment-native"))] + fn infer_detected( + &mut self, + rgb: &[u8], + width: u32, + height: u32, + options: BodyOptions, + ) -> Result { + if self.segment.is_none() { + let path = self.segment_path.clone().ok_or_else(|| { + AssetAiError::Unavailable( + "sam3dbody detect: the person detector weights (optional role native-segment) are not available on this node" + .to_string(), + ) + })?; + let weights = Sam3Weights::load(&path).map_err(diffusion_err)?; + self.segment = Some(Sam3::prepare(&weights).map_err(diffusion_err)?); + } + let segment = self.segment.as_ref().unwrap(); + let model = self.model.as_mut().ok_or_else(|| { + AssetAiError::Backend("native body used before ensure_loaded".to_string()) + })?; + let (w, h) = (width as usize, height as usize); + let image = Sam3Image::rgb8(rgb, w, h).map_err(diffusion_err)?; + let found = segment + .segment(image, &format!("person:{}", options.persons), None) + .map_err(diffusion_err)?; + let mut people = Vec::new(); + for (bbox, &score) in found + .boxes_xyxy + .iter() + .zip(&found.scores) + .take(options.persons) + { + // The detector returns one instance-union alpha: the person's + // mask is that alpha inside the person's box, at the 0.5 level. + let mut mask = vec![0u8; w * h]; + let x0 = bbox[0].floor().max(0.0) as usize; + let y0 = bbox[1].floor().max(0.0) as usize; + let x1 = (bbox[2].ceil().max(0.0) as usize).min(w); + let y1 = (bbox[3].ceil().max(0.0) as usize).min(h); + for y in y0..y1 { + for x in x0..x1 { + if found.alpha[y * w + x] >= 0.5 { + mask[y * w + x] = 1; + } + } + } + let bbox = [bbox[0], bbox[1], bbox[2], bbox[3]]; + let mut person_packet = if options.hands { + model + .infer_full(rgb, width, height, Some(bbox), Some((&mask, score))) + .map_err(diffusion_err)? + .into_packet(0.0) + } else { + model + .infer_masked(rgb, width, height, bbox, Some((&mask, score))) + .map_err(diffusion_err)? + }; + people.append(&mut person_packet.people); + } + Ok(BodyPacket { people, ms: 0.0 }) + } + + #[cfg(all(feature = "body-native", not(feature = "segment-native")))] + fn infer_detected( + &mut self, + _rgb: &[u8], + _width: u32, + _height: u32, + _options: BodyOptions, + ) -> Result { + Err(AssetAiError::Unavailable( + "sam3dbody detect needs a build with the 'segment-native' cargo feature".to_string(), + )) + } } #[cfg(feature = "body-native")] @@ -112,6 +281,11 @@ impl ContentBackend for BodyNativeBackend { let model = BodyModel::load(&path).map_err(diffusion_err)?; self.model_path = Some(path); self.model = Some(model); + #[cfg(feature = "segment-native")] + { + self.segment = None; + self.segment_path = ctx.path_by_role("native-segment").ok(); + } Ok(()) } } @@ -132,6 +306,11 @@ impl ContentBackend for BodyNativeBackend { self.model = None; self.model_path = None; } + #[cfg(all(feature = "body-native", feature = "segment-native"))] + { + self.segment = None; + self.segment_path = None; + } Ok(()) } @@ -155,7 +334,8 @@ impl ContentBackend for BodyNativeBackend { cancel.check()?; progress("body: infer", 0.05); let (rgb, width, height) = crate::testpattern::decode_png_rgb8(¶ms.input_bytes)?; - let packet = self.infer_rgb(&rgb, width, height, None)?; + let options = BodyOptions::parse(¶ms.prompt)?; + let packet = self.infer_rgb(&rgb, width, height, None, options)?; cancel.check()?; progress("done", 1.0); Ok(vec![ArtifactData { @@ -179,7 +359,8 @@ impl ContentBackend for BodyNativeBackend { let init = frame.init.ok_or_else(|| { AssetAiError::Params("sam3dbody live step requires an input frame".to_string()) })?; - let packet = self.infer_rgb(&init.data, init.width, init.height, None)?; + let options = BodyOptions::parse(&frame.config.prompt)?; + let packet = self.infer_rgb(&init.data, init.width, init.height, None, options)?; cancel.check()?; Ok(LiveFrameOut { image: init.clone(), @@ -212,6 +393,27 @@ mod tests { crate::testpattern::encode_png_rgb8(&vec![128u8; 8 * 4 * 3], 8, 4).unwrap() } + #[test] + fn options_parse_the_prompt_words() { + assert_eq!(BodyOptions::parse("").unwrap(), BodyOptions::default()); + assert_eq!( + BodyOptions::parse("hands, detect persons=3").unwrap(), + BodyOptions { + hands: true, + detect: true, + persons: 3 + } + ); + assert!(matches!( + BodyOptions::parse("persons=0"), + Err(AssetAiError::Params(_)) + )); + assert!(matches!( + BodyOptions::parse("feet"), + Err(AssetAiError::Params(_)) + )); + } + #[test] fn reports_live_support_and_echoes_the_frame() { let packet = r#"{"n_people":0,"people":[],"ms":0.0}"#.to_string(); @@ -270,6 +472,7 @@ mod tests { kp2d: vec![0.0; 70 * 2], joints: None, rots: None, + hands: None, }], ms: 4.56789, }; diff --git a/libs/ai/hub/src/registry.rs b/libs/ai/hub/src/registry.rs index 4896cb035..3fe79e62b 100644 --- a/libs/ai/hub/src/registry.rs +++ b/libs/ai/hub/src/registry.rs @@ -198,6 +198,14 @@ pub enum Domain { /// Speech audio -> timed transcript (Whisper). The `stt.whisper` pipe; /// `Speech` stays text-to-speech, so the two never share affinity. Stt, + /// Audio -> beat and downbeat tracking JSON. + Beats, + /// Audio -> polyphonic note transcription JSON/MIDI. + Notes, + /// Audio -> music-structure sections. + Sections, + /// Image -> sewing-pattern JSON. + Garment, } impl Domain { @@ -227,6 +235,10 @@ impl Domain { "vision" => Some(Domain::Vision), "ocr" => Some(Domain::Ocr), "stt" => Some(Domain::Stt), + "beats" => Some(Domain::Beats), + "notes" => Some(Domain::Notes), + "sections" => Some(Domain::Sections), + "garment" => Some(Domain::Garment), _ => None, } } @@ -257,6 +269,10 @@ impl Domain { Domain::Vision => "vision", Domain::Ocr => "ocr", Domain::Stt => "stt", + Domain::Beats => "beats", + Domain::Notes => "notes", + Domain::Sections => "sections", + Domain::Garment => "garment", } } } @@ -378,11 +394,14 @@ pub struct ModelLicense { impl ModelLicense { /// Stable identity of the *text* the user accepted: sha256 when pinned, - /// otherwise the canonical URL. + /// otherwise a hash of the licence name and canonical URL. A registry + /// correction to either value therefore prompts again. pub fn identity(&self) -> String { self.sha256 .clone() - .unwrap_or_else(|| self.url.clone()) + .unwrap_or_else(|| { + crate::sha256::sha256_hex(format!("{}\0{}", self.name, self.url).as_bytes()) + }) } } @@ -456,7 +475,7 @@ impl Registry { for model in wire.models { let domain = Domain::parse(&model.domain).ok_or_else(|| { AssetAiError::Registry(format!( - "model {}: unknown domain {:?} (expected image|mesh|video|audio|text|speech|world|matte|depth|body|segment|rig|motion)", + "model {}: unknown domain {:?} (expected image|mesh|video|audio|text|speech|world|matte|depth|body|segment|rig|motion|music|paint|edit|upscale|control|inpaint|enhance|splat|vision|ocr|beats|notes|sections|garment)", model.id, model.domain )) })?; @@ -877,6 +896,19 @@ mod tests { registry.find("pbr-testpattern").is_none(), "deterministic paint-test is crate-internal and must not advertise" ); + let beats = registry.find("beat-this").unwrap(); + assert_eq!(beats.domain, Domain::Beats); + assert_eq!(beats.backend, "beats"); + assert_eq!(beats.vram_gb, Some(0.5)); + assert_eq!(beats.files.len(), 2); + let final_weights = beats.file_by_role("weights").unwrap(); + assert_eq!(final_weights.size, Some(81_058_141)); + assert_eq!( + final_weights.sha256.as_deref(), + Some("8c328b45f59d8dd3dff219253ff6a8d6482be57d0133a29140e2febbf8eb8331") + ); + assert!(final_weights.path.starts_with("https://cloud.cp.jku.at/")); + assert!(beats.file_by_role("weights-small").unwrap().optional); let hunyuan = registry.find("hunyuan3d-paint-2.1").unwrap(); assert_eq!(hunyuan.domain, Domain::Paint); assert_eq!(hunyuan.backend, "paint"); @@ -1504,7 +1536,20 @@ mod tests { assert_eq!(native_body.backend, "body-native"); assert!(native_body.available && !native_body.gated); assert_eq!(native_body.vram_gb, Some(4.5)); - assert_eq!(native_body.files.len(), 1); + // The checkpoint plus the optional SAM 3.1 detector for `detect` + // (the same artifact the segment entry pins, so one cache file). + assert_eq!(native_body.files.len(), 2); + let detector = native_body.file_by_role("native-segment").unwrap(); + assert!(detector.optional); + assert_eq!( + detector.cache_as, + registry + .find("sam3-1-multiplex") + .unwrap() + .file_by_role("native-segment") + .unwrap() + .cache_as + ); let body_weights = native_body.file_by_role("native-body").unwrap(); assert_eq!(body_weights.repo, "Comfy-Org/sam-3d-body"); assert_eq!( @@ -1805,4 +1850,17 @@ mod tests { let message = Registry::parse(json).unwrap_err().to_string(); assert!(message.contains("unknown license restriction"), "{message}"); } + + #[test] + fn local_app_domains_round_trip() { + for (text, domain) in [ + ("beats", Domain::Beats), + ("notes", Domain::Notes), + ("sections", Domain::Sections), + ("garment", Domain::Garment), + ] { + assert_eq!(Domain::parse(text), Some(domain)); + assert_eq!(domain.as_str(), text); + } + } } diff --git a/libs/ai/models/body/src/model.rs b/libs/ai/models/body/src/model.rs index 43d12a8ce..2397b4757 100644 --- a/libs/ai/models/body/src/model.rs +++ b/libs/ai/models/body/src/model.rs @@ -7,13 +7,14 @@ //! parameters come from the body decoder, the hand crops of the reference's //! "full" mode are a later phase. +use crate::backend::GpuTensor; use crate::condition::{apply_mask_prompt, dense_pe_at, ray_features, RayCond}; use crate::decoder::{Decoder, LoopTiming, StepFeedback, StepInput}; use crate::dino::BodyDino; use crate::hands::{hand_crops, BodyImage, FusionReport, HandBranch, HandOutput}; use crate::mask::{warp_mask, MaskEmbed}; use crate::mhr::MhrRig; -use crate::packet::{BodyPacket, BodyPerson}; +use crate::packet::{BodyPacket, BodyPerson, PersonHands}; use crate::pose::{camera_translation, model_params, project, unpack_pose}; use crate::preprocess::{ condition_info, crop_geometry_at, crop_normalized, full_to_crop, patch_rays, CropGeometry, @@ -61,6 +62,43 @@ pub struct FullOutput { pub report: FusionReport, } +impl BodyOutput { + /// The transport subset of this output (spec section 9). + pub fn into_person(self) -> BodyPerson { + BodyPerson { + mhr: self.mhr_model_params, + global_rot: self.global_rot, + cam_t: self.pred_cam_t, + shape: self.shape, + expr: self.face, + focal: self.focal_length, + bbox: self.bbox, + kp3d: self.pred_keypoints_3d, + kp2d: self.pred_keypoints_2d, + joints: Some(self.pred_joint_coords), + rots: None, + hands: None, + } + } +} + +impl FullOutput { + /// The transport packet of a full-mode pass: the fused body plus which + /// hands were trusted and where they were. + pub fn into_packet(self, ms: f32) -> BodyPacket { + let boxes = [self.hands[0].bbox, self.hands[1].bbox]; + let mut person = self.body.into_person(); + person.hands = Some(PersonHands { + fused: self.report.fused, + boxes, + }); + BodyPacket { + people: vec![person], + ms, + } + } +} + /// Rich model output used by the body, hand, re-prompt, and fusion passes. /// The packet API deliberately exposes only its stable transport subset. #[derive(Clone, Debug)] @@ -193,6 +231,29 @@ impl BodyModel { bbox: Option<[f32; 4]>, mask: Option<(&[u8], f32)>, ) -> Result { + let total = Instant::now(); + let (last, _geo, _context) = self.body_pass(rgb, width, height, bbox, mask)?; + let person = last.into_person(); + let t_packet = total.elapsed(); + self.last_stage_ms[4] = t_packet.as_secs_f32() * 1000.0 - self.last_stage_ms[..4].iter().sum::(); + Ok(BodyPacket { + people: vec![person], + ms: t_packet.as_secs_f32() * 1000.0, + }) + } + + /// The body pass every entry point shares: crop (with the optional + /// mask prompt), backbone, conditioning and the decoder loop. Returns + /// the last step's output carrying the hand boxes, the crop geometry + /// and the conditioned context (the hands pass re-prompts against it). + fn body_pass( + &mut self, + rgb: &[u8], + width: u32, + height: u32, + bbox: Option<[f32; 4]>, + mask: Option<(&[u8], f32)>, + ) -> Result<(BodyOutput, CropGeometry, GpuTensor)> { let (w, h) = (width as usize, height as usize); if rgb.len() != w * h * 3 { return Err(DiffusionError::workflow(format!( @@ -267,42 +328,27 @@ impl BodyModel { last.hand_box = output.hand_boxes; last.hand_logits = output.hand_logits; last.bbox = bbox; - let person = BodyPerson { - mhr: last.mhr_model_params, - global_rot: last.global_rot, - cam_t: last.pred_cam_t, - shape: last.shape, - expr: last.face, - focal: geo.focal, - bbox, - kp3d: last.pred_keypoints_3d, - kp2d: last.pred_keypoints_2d, - joints: Some(last.pred_joint_coords), - rots: None, - }; - let t_packet = total.elapsed(); self.last_stage_ms = [ t_crop.as_secs_f32() * 1000.0, (t_backbone - t_crop).as_secs_f32() * 1000.0, (t_context - t_backbone).as_secs_f32() * 1000.0, (t_decoder - t_context).as_secs_f32() * 1000.0, - (t_packet - t_decoder).as_secs_f32() * 1000.0, + 0.0, ]; - Ok(BodyPacket { - people: vec![person], - ms: t_packet.as_secs_f32() * 1000.0, - }) + Ok((last, geo, context)) } /// Full body + two hand crops + wrist fusion. Unlike [`Self::infer`], /// this returns the rich fused result, the two hand passes and the - /// fusion report (which hands were trusted and why). + /// fusion report (which hands were trusted and why). `mask` is the + /// optional segmentation-mask prompt of the body pass (spec 13.2). pub fn infer_full( &mut self, rgb: &[u8], width: u32, height: u32, bbox: Option<[f32; 4]>, + mask: Option<(&[u8], f32)>, ) -> Result { if self.crop_size != IMAGE_SIZE { return Err(DiffusionError::workflow(format!( @@ -311,45 +357,7 @@ impl BodyModel { ))); } let (w, h) = (width as usize, height as usize); - if rgb.len() != w * h * 3 { - return Err(DiffusionError::workflow(format!( - "body infer_full: {} bytes for {width}x{height} rgb, expected {}", - rgb.len(), - w * h * 3, - ))); - } - let bbox = bbox.unwrap_or([0.0, 0.0, width as f32, height as f32]); - let geo = crop_geometry_at(bbox, w, h, None, IMAGE_SIZE, 1.25); - let crop = crop_normalized(rgb, w, h, &geo); - let embeddings = self.dino.forward_normalized(&crop)?; - let features = ray_features(&patch_rays(&geo)); - let context = self - .ray_cond - .apply(&embeddings, &self.no_mask_embed, &features)?; - let tokens = self.decoder.build_tokens(condition_info(&geo)); - let mut last = None; - let decoded = self.decoder.run( - tokens, - &context, - &self.dense_pe[&IMAGE_SIZE], - |step| { - let correctives = self.correctives_every_step - || step.layer + 1 == crate::DEC_DEPTH; - let result = close_the_loop(&self.rig, &geo, &step, correctives); - let feedback = StepFeedback { - kp2d_cropped: result.pred_keypoints_2d_cropped.clone(), - depth: result.pred_keypoints_2d_depth.clone(), - kp3d: result.pred_keypoints_3d.clone(), - }; - last = Some(result); - feedback - }, - )?; - let mut body = last.ok_or_else(|| DiffusionError::model("body decoder ran no steps"))?; - body.hand_box = decoded.hand_boxes; - body.hand_logits = decoded.hand_logits; - body.bbox = bbox; - + let (mut body, geo, context) = self.body_pass(rgb, width, height, bbox, mask)?; if self.hands.is_none() { self.hands = Some(HandBranch::load(&self.weights)?); } @@ -579,7 +587,7 @@ mod tests { let rgb: Vec = image.into_iter().map(|value| value as u8).collect(); let mut model = BodyModel::load(&weights_path).expect("load full body model"); model.correctives_every_step = true; - let full = model.infer_full(&rgb, w, h, None).expect("full inference"); + let full = model.infer_full(&rgb, w, h, None, None).expect("full inference"); let field = |name: &str| fixture::load_from(root, name).unwrap().1; eprintln!("{label}: fusion report {:?}", full.report); let output = &full.body; diff --git a/libs/ai/models/body/src/packet.rs b/libs/ai/models/body/src/packet.rs index 5dd03a461..a914590d9 100644 --- a/libs/ai/models/body/src/packet.rs +++ b/libs/ai/models/body/src/packet.rs @@ -15,6 +15,15 @@ pub struct BodyPerson { pub kp2d: Vec, pub joints: Option>, pub rots: Option>, + /// Present when the hands pass ran: which hands were trusted and fused + /// into the pose (left, right) and their boxes in full-image pixels. + pub hands: Option, +} + +#[derive(Clone, Debug, PartialEq)] +pub struct PersonHands { + pub fused: [bool; 2], + pub boxes: [[f32; 4]; 2], } #[derive(Clone, Debug, PartialEq)] @@ -69,6 +78,17 @@ fn push_person(out: &mut String, person: &BodyPerson) { out.push_str(",\"rots\":"); push_f32s(out, rots); } + if let Some(hands) = &person.hands { + out.push_str(",\"hands\":{\"fused\":["); + out.push_str(if hands.fused[0] { "true" } else { "false" }); + out.push(','); + out.push_str(if hands.fused[1] { "true" } else { "false" }); + out.push_str("],\"boxes\":["); + push_f32s(out, &hands.boxes[0]); + out.push(','); + push_f32s(out, &hands.boxes[1]); + out.push_str("]}"); + } out.push('}'); } @@ -120,6 +140,7 @@ mod tests { kp2d: vec![5.67894; 70 * 2], joints: Some(vec![0.25; 127 * 3]), rots: None, + hands: None, }], ms: 12.34567, }; From 8c568dfcb0caf94c13ca473efbe0eb6f89262e92 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 01:45:22 +0200 Subject: [PATCH 042/417] ai-hub: drop the SAM 3D Body reference worker backend The native port covers everything the Python reference worker did (body, hands, mask prompt, multi-person), so the subprocess backend, its fake worker harness, the sam3dbody-ref registry entry and the MAKEPAD_SAM3DBODY_* environment go. The packet validator moves to the native backend. Co-Authored-By: Claude Fable 5.1 --- libs/ai/hub/Cargo.toml | 17 +- libs/ai/hub/registry.json | 16 - libs/ai/hub/src/backend.rs | 27 +- libs/ai/hub/src/body_backend.rs | 486 ------------------------- libs/ai/hub/src/body_native_backend.rs | 16 +- libs/ai/hub/src/lib.rs | 9 +- libs/ai/hub/src/registry.rs | 10 +- libs/ai/hub/tests/body_worker.rs | 219 ----------- 8 files changed, 53 insertions(+), 747 deletions(-) delete mode 100644 libs/ai/hub/src/body_backend.rs delete mode 100644 libs/ai/hub/tests/body_worker.rs diff --git a/libs/ai/hub/Cargo.toml b/libs/ai/hub/Cargo.toml index ce9c69072..b2c0cae4b 100644 --- a/libs/ai/hub/Cargo.toml +++ b/libs/ai/hub/Cargo.toml @@ -34,6 +34,8 @@ default = [ "motion-native", "rig-native", "splat-native", + "beats-native", + "notes-native", ] # Box-provisioned Python/Torch reference backends (FlashWorld, Music3, # Depth-Anything-3, and the rig/motion oracles). Not in default: a native @@ -95,6 +97,14 @@ splat-native = ["matte-native", "dep:makepad-ai-splat", "dep:makepad-ai-common"] # lossless skinned-GLB augmentation. The reference Torch/bpy backend remains # separately available as `rig-oracle` through `python-backends`. rig-native = ["dep:makepad-ai-rig", "dep:makepad-ai-common", "dep:makepad-gltf"] +# In-process registry/downloader/backend runner for desktop applications. +# Opt-in so featureless fleet clients do not pull the GPU model substrate. +local = ["dep:makepad-ai-common"] +# Native Beat This! audio -> beat/downbeat JSON analysis. +beats-native = ["dep:makepad-ai-beats", "dep:makepad-ai-common"] +# Native Spotify Basic Pitch audio -> notes/MIDI transcription. The model is +# tiny and has a CPU fallback, so this lane is available without a GPU. +notes-native = ["dep:makepad-ai-notes"] [dependencies] makepad-micro-serde = { path = "../../micro_serde" } @@ -131,6 +141,8 @@ makepad-xatlas = { path = "../../xatlas", optional = true } makepad-render = { path = "../../render", optional = true } makepad-ai-llm = { path = "../../ai/llm", optional = true } makepad-ai-speech = { path = "../../ai/models/speech", default-features = false, optional = true } +makepad-ai-beats = { path = "../../ai/models/beats", optional = true } +makepad-ai-notes = { path = "../../ai/models/notes", optional = true } makepad-system-speech = { path = "../../system_speech", optional = true } makepad-video = { path = "../../../platform/video", optional = true } # The `mkfl` motion payload: ONE definition, shared with the VJ's import @@ -148,11 +160,6 @@ makepad-live-id = { path = "../../live_id" } # internally (behind the crate's own optional/default `video` feature). makepad-video = { path = "../../../platform/video" } -[[test]] -name = "body_worker" -path = "tests/body_worker.rs" -harness = false - # The standing "is chat slow right now?" check. Its own code is std-only — # no HTTP or JSON crate — so what it measures is the box, not a client # library, and it keeps working when the wire grows fields it has never diff --git a/libs/ai/hub/registry.json b/libs/ai/hub/registry.json index 09ab3ebb0..70b1344dc 100644 --- a/libs/ai/hub/registry.json +++ b/libs/ai/hub/registry.json @@ -1862,22 +1862,6 @@ } ] }, - { - "id": "sam3dbody-ref", - "domain": "body", - "backend": "body", - "available": true, - "gated": false, - "license": { - "name": "SAM 3D Body License", - "url": "https://github.com/facebookresearch/sam-3d-body", - "summary": "SAM 3D Body is served by an externally provisioned worker. Review and comply with the upstream model and checkpoint terms before production use.", - "restriction": "community" - }, - "vram_gb": 4.0, - "note": "SAM 3D Body reference worker: live or single-image RGB input -> application/json human pose packet. The Rust hub only owns the persistent length-prefixed PNG/JSON-lines process seam; the worker and model remain box-provisioned through MAKEPAD_SAM3DBODY_WORKER. Warm reference inference is approximately 0.6-0.9 seconds per frame and uses approximately 3.5 GiB VRAM.", - "files": [] - }, { "id": "sam3-1-multiplex", "domain": "segment", diff --git a/libs/ai/hub/src/backend.rs b/libs/ai/hub/src/backend.rs index 49d1b9fd9..d7f928363 100644 --- a/libs/ai/hub/src/backend.rs +++ b/libs/ai/hub/src/backend.rs @@ -1219,6 +1219,7 @@ pub fn validate_loras_for_backend( /// One generated output. `content_type` drives the `/artifact` response; /// `ext` names the file on disk. +#[derive(Clone, Debug)] pub struct ArtifactData { pub content_type: &'static str, pub ext: &'static str, @@ -1562,13 +1563,13 @@ pub fn backend_live_supported(spec: &ModelSpec) -> bool { pub fn backend_compiled(name: &str) -> bool { match name { "testpattern" => true, - "body" => true, "flux" | "flux2" | "control" | "flux-fill" => cfg!(feature = "flux"), "llm" => cfg!(feature = "llm"), // The vision domain rides the same llama session + the mmproj tower, // so it is compiled in exactly when the LLM is. "vision" => cfg!(feature = "llm"), "ocr" => cfg!(feature = "llm"), + "notes" => cfg!(feature = "notes-native"), "kokoro" => cfg!(feature = "tts"), "whisper" => cfg!(feature = "stt"), "indextts" => cfg!(feature = "indextts"), @@ -1578,6 +1579,7 @@ pub fn backend_compiled(name: &str) -> bool { "moss" => cfg!(feature = "audio"), "woosh" => cfg!(feature = "audio"), "ace" => cfg!(feature = "audio"), + "beats" => cfg!(feature = "beats-native"), "trellis" => cfg!(feature = "mesh"), "paint" | "paint-test" => cfg!(feature = "paint"), "matte-native" => cfg!(feature = "matte-native"), @@ -1640,9 +1642,6 @@ pub fn backend_provisioned(name: &str) -> bool { // on macOS, CUDA on Windows/Linux, probed once and memoised. "vision" => crate::vision_backend::vision_provisioned(), "ocr" => crate::vision_backend::vision_provisioned(), - "body" => { - crate::body_backend::body_provisioned() || cfg!(feature = "body-native") - } "depth-native" => cfg!(feature = "depth-native"), "segment-native" => cfg!(feature = "segment-native"), "body-native" => cfg!(feature = "body-native"), @@ -1770,12 +1769,18 @@ pub fn model_availability( pub fn create_backend(spec: &ModelSpec) -> Result, AssetAiError> { match spec.backend.as_str() { + #[cfg(feature = "notes-native")] + "notes" => Ok(Box::new(crate::notes_backend::NotesBackend::new(&spec.id))), + #[cfg(not(feature = "notes-native"))] + "notes" => Err(AssetAiError::Unavailable(format!( + "model {} needs a build with the 'notes-native' cargo feature", + spec.id + ))), #[cfg(feature = "paint")] "paint" | "paint-test" => Ok(Box::new(crate::paint_backend::PaintBackend::new(spec))), "testpattern" => Ok(Box::new(crate::testpattern::TestPatternBackend::new( &spec.id, ))), - "body" => Ok(Box::new(crate::body_backend::BodyBackend::new(&spec.id))), #[cfg(feature = "body-native")] "body-native" => Ok(Box::new( crate::body_native_backend::BodyNativeBackend::new_native(&spec.id), @@ -1885,6 +1890,13 @@ pub fn create_backend(spec: &ModelSpec) -> Result, Asset ))), #[cfg(feature = "audio")] "ace" => Ok(Box::new(crate::ace_backend::AceBackend::new_ace(&spec.id))), + #[cfg(feature = "beats-native")] + "beats" => Ok(Box::new(crate::beats_backend::BeatsBackend::new(&spec.id))), + #[cfg(not(feature = "beats-native"))] + "beats" => Err(AssetAiError::Unavailable(format!( + "model {} needs a build with the 'beats-native' cargo feature", + spec.id + ))), #[cfg(not(feature = "audio"))] "moss" => Err(AssetAiError::Unavailable(format!( "model {} needs a build with the 'audio' cargo feature", @@ -2086,11 +2098,6 @@ mod tests { assert!(model_availability(&model, &GpuInfo::default(), 2 * 1024).is_ok()); } - #[test] - fn body_backend_is_compiled() { - assert!(backend_compiled("body")); - } - #[test] fn declared_gpu_requirements_fail_closed_at_exact_boundaries() { let mut model = spec("testpattern", true, Some(20.0)); diff --git a/libs/ai/hub/src/body_backend.rs b/libs/ai/hub/src/body_backend.rs deleted file mode 100644 index 1838391a2..000000000 --- a/libs/ai/hub/src/body_backend.rs +++ /dev/null @@ -1,486 +0,0 @@ -//! SAM 3D Body worker backend for the `body` domain. -//! -//! The worker returns one JSON object per input frame. Its pose packet schema -//! is `{"n_people":N,"people":[{"mhr":[204 f32],"global_rot":[3], -//! "cam_t":[3],"shape":[45],"expr":[72],"focal":f32,"bbox":[4], -//! "joints":[[x,y,z] x127]?}]}`. Rust validates only that the line is JSON -//! with a top-level `n_people` field and otherwise forwards it opaquely. - -use crate::backend::{ - ArtifactData, BackendCtx, CancelToken, ContentBackend, GenerateParams, LiveFrameIn, - LiveFrameOut, ProgressSink, -}; -use crate::error::AssetAiError; -use makepad_strict_json::Value; -use std::io::{BufRead, BufReader, Write}; -use std::process::{Child, ChildStdin, Command, Stdio}; -use std::sync::mpsc::{self, Receiver, RecvTimeoutError}; -use std::thread::JoinHandle; -use std::time::{Duration, Instant}; - -pub const BODY_WORKER_ENV: &str = "MAKEPAD_SAM3DBODY_WORKER"; -pub const BODY_TIMEOUT_ENV: &str = "MAKEPAD_SAM3DBODY_TIMEOUT_S"; -pub const BODY_SPAWN_TIMEOUT_ENV: &str = "MAKEPAD_SAM3DBODY_SPAWN_TIMEOUT_S"; -const DEFAULT_TIMEOUT_S: f64 = 10.0; -// The real worker loads its model at spawn (~12s reference, more on a cold -// disk) and only then emits its `{"ready":true}` line — the per-frame -// timeout must not start until that handshake, or the first frame kills a -// still-loading worker and the restart loop reloads it forever. -const DEFAULT_SPAWN_TIMEOUT_S: f64 = 120.0; -const MAX_RESTARTS: u8 = 3; - -pub fn body_provisioned() -> bool { - std::env::var(BODY_WORKER_ENV) - .ok() - .is_some_and(|command| !command.trim().is_empty()) -} - -fn configured_command() -> Result, AssetAiError> { - let command = std::env::var(BODY_WORKER_ENV).map_err(|_| { - AssetAiError::Unavailable(format!( - "sam3dbody worker is not configured; set {BODY_WORKER_ENV}" - )) - })?; - let parts: Vec = command - .split_whitespace() - .map(str::to_string) - .collect(); - if parts.is_empty() { - return Err(AssetAiError::Unavailable(format!( - "sam3dbody worker command in {BODY_WORKER_ENV} is empty" - ))); - } - Ok(parts) -} - -fn positive_seconds_env(env: &str, default_s: f64) -> Result { - let Some(text) = std::env::var(env).ok() else { - return Ok(Duration::from_secs_f64(default_s)); - }; - let seconds = text.parse::().ok().filter(|s| s.is_finite() && *s > 0.0); - match seconds { - Some(seconds) => Ok(Duration::from_secs_f64(seconds)), - None => Err(AssetAiError::Unavailable(format!( - "{env} must be a positive number of seconds, got {text:?}" - ))), - } -} - -fn configured_timeout() -> Result { - positive_seconds_env(BODY_TIMEOUT_ENV, DEFAULT_TIMEOUT_S) -} - -fn configured_spawn_timeout() -> Result { - positive_seconds_env(BODY_SPAWN_TIMEOUT_ENV, DEFAULT_SPAWN_TIMEOUT_S) -} - -enum WorkerRead { - Line(String), - Eof, - Error(String), -} - -struct WorkerProcess { - child: Child, - stdin: Option, - lines: Receiver, - reader: Option>, - // The worker's first stdout line must be its ready handshake (a JSON - // object with a `ready` field), emitted after its model finishes - // loading; frames sent before it are only buffered by the OS pipe. - ready_seen: bool, -} - -impl Drop for WorkerProcess { - fn drop(&mut self) { - self.stdin.take(); - let _ = crate::child_process::kill_tree(&mut self.child); - let _ = self.child.wait(); - if let Some(reader) = self.reader.take() { - let _ = reader.join(); - } - } -} - -/// Persistent length-prefixed PNG / JSON-lines worker connection. -pub struct BodyWorker { - command: Vec, - timeout: Duration, - spawn_timeout: Duration, - process: Option, - restarts: u8, -} - -impl BodyWorker { - pub fn new() -> Result { - let mut worker = Self { - command: configured_command()?, - timeout: configured_timeout()?, - spawn_timeout: configured_spawn_timeout()?, - process: None, - restarts: 0, - }; - worker.spawn_process()?; - Ok(worker) - } - - fn spawn_process(&mut self) -> Result<(), AssetAiError> { - let mut command = Command::new(&self.command[0]); - command - .args(&self.command[1..]) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .stderr(Stdio::inherit()); - let mut child = crate::child_process::spawn(&mut command).map_err(|error| { - AssetAiError::Unavailable(format!( - "spawn sam3dbody worker {:?}: {error}", - self.command - )) - })?; - let stdin = child.stdin.take().ok_or_else(|| { - AssetAiError::Backend("sam3dbody worker has no piped stdin".to_string()) - })?; - let stdout = child.stdout.take().ok_or_else(|| { - AssetAiError::Backend("sam3dbody worker has no piped stdout".to_string()) - })?; - let (line_tx, lines) = mpsc::channel(); - let reader = std::thread::spawn(move || { - let mut stdout = BufReader::new(stdout); - loop { - let mut line = String::new(); - match stdout.read_line(&mut line) { - Ok(0) => { - let _ = line_tx.send(WorkerRead::Eof); - return; - } - Ok(_) => { - while line.ends_with('\n') || line.ends_with('\r') { - line.pop(); - } - if line_tx.send(WorkerRead::Line(line)).is_err() { - return; - } - } - Err(error) => { - let _ = line_tx.send(WorkerRead::Error(error.to_string())); - return; - } - } - } - }); - self.process = Some(WorkerProcess { - child, - stdin: Some(stdin), - lines, - reader: Some(reader), - ready_seen: false, - }); - Ok(()) - } - - /// Waits for the worker's `{"ready":true}` handshake line under the - /// spawn timeout. Returns Ok(true) when ready, Ok(false) after a - /// restart (caller re-enters its loop), Err on cancel/timeout/limit. - fn await_ready(&mut self, cancel: &CancelToken) -> Result { - if self.process.as_ref().unwrap().ready_seen { - return Ok(true); - } - let deadline = Instant::now() + self.spawn_timeout; - loop { - if cancel.is_cancelled() { - self.stop_process(); - return Err(AssetAiError::Cancelled); - } - let now = Instant::now(); - if now >= deadline { - self.stop_process(); - return Err(AssetAiError::Backend(format!( - "sam3dbody worker not ready after {:.0} seconds", - self.spawn_timeout.as_secs_f64() - ))); - } - let wait = (deadline - now).min(Duration::from_millis(50)); - match self.process.as_ref().unwrap().lines.recv_timeout(wait) { - Ok(WorkerRead::Line(line)) => { - let is_ready = makepad_strict_json::parse(line.as_bytes()) - .ok() - .is_some_and(|value| value.get("ready").is_some()); - if is_ready { - self.process.as_mut().unwrap().ready_seen = true; - return Ok(true); - } - self.restart_after_death(&format!( - "first line was not the ready handshake: {line:.120}" - ))?; - return Ok(false); - } - Ok(WorkerRead::Eof) => { - self.restart_after_death("exited before ready handshake")?; - return Ok(false); - } - Ok(WorkerRead::Error(error)) => { - self.restart_after_death(&format!("stdout read failed: {error}"))?; - return Ok(false); - } - Err(RecvTimeoutError::Timeout) => {} - Err(RecvTimeoutError::Disconnected) => { - self.restart_after_death("stdout reader stopped")?; - return Ok(false); - } - } - } - } - - fn stop_process(&mut self) { - self.process.take(); - } - - fn restart_after_death(&mut self, reason: &str) -> Result<(), AssetAiError> { - self.stop_process(); - if self.restarts >= MAX_RESTARTS { - return Err(AssetAiError::Backend(format!( - "sam3dbody worker died after {MAX_RESTARTS} restarts: {reason}" - ))); - } - self.restarts += 1; - self.spawn_process() - } - - pub fn ensure_started(&mut self) -> Result<(), AssetAiError> { - if self.process.is_none() { - self.spawn_process()?; - } - Ok(()) - } - - pub fn is_started(&self) -> bool { - self.process.is_some() - } - - pub fn restart_count(&self) -> u8 { - self.restarts - } - - fn begin_session(&mut self) { - self.restarts = 0; - } - - /// Sends one PNG and waits for the matching pose JSON line. - pub fn process_png( - &mut self, - png: &[u8], - cancel: &CancelToken, - ) -> Result { - cancel.check()?; - let length = u32::try_from(png.len()).map_err(|_| { - AssetAiError::Params("sam3dbody input png exceeds 4 GiB".to_string()) - })?; - - loop { - self.ensure_started()?; - let exited = self - .process - .as_mut() - .unwrap() - .child - .try_wait() - .map_err(|error| { - AssetAiError::Backend(format!( - "sam3dbody worker status check failed: {error}" - )) - })?; - if let Some(status) = exited { - self.restart_after_death(&format!("exited with {status}"))?; - continue; - } - if !self.await_ready(cancel)? { - continue; - } - - // KNOWN GAP (P2): this write has no deadline — a worker that - // wedges mid-frame-read can block us in write_all. The lock-step - // protocol (one frame in flight) makes that window small; the - // full fix is a writer thread symmetrical to the reader. - let write_result = { - let process = self.process.as_mut().unwrap(); - let stdin = process.stdin.as_mut().unwrap(); - stdin - .write_all(&length.to_le_bytes()) - .and_then(|_| stdin.write_all(png)) - .and_then(|_| stdin.flush()) - }; - if let Err(error) = write_result { - self.restart_after_death(&format!("stdin write failed: {error}"))?; - continue; - } - - let deadline = Instant::now() + self.timeout; - loop { - if cancel.is_cancelled() { - self.stop_process(); - return Err(AssetAiError::Cancelled); - } - let now = Instant::now(); - if now >= deadline { - self.stop_process(); - return Err(AssetAiError::Backend(format!( - "sam3dbody worker timed out after {:.3} seconds", - self.timeout.as_secs_f64() - ))); - } - let wait = (deadline - now).min(Duration::from_millis(50)); - let event = self.process.as_ref().unwrap().lines.recv_timeout(wait); - match event { - Ok(WorkerRead::Line(line)) => { - validate_pose_packet(&line)?; - return Ok(line); - } - Ok(WorkerRead::Eof) => { - self.restart_after_death("stdout closed")?; - break; - } - Ok(WorkerRead::Error(error)) => { - self.restart_after_death(&format!("stdout read failed: {error}"))?; - break; - } - Err(RecvTimeoutError::Timeout) => {} - Err(RecvTimeoutError::Disconnected) => { - self.restart_after_death("stdout reader stopped")?; - break; - } - } - } - } - } -} - -pub fn validate_pose_packet(line: &str) -> Result<(), AssetAiError> { - let value = makepad_strict_json::parse(line.as_bytes()).map_err(|error| { - AssetAiError::Backend(format!("sam3dbody worker returned invalid json: {error}")) - })?; - if !matches!(&value, Value::Obj(_)) || value.get("n_people").is_none() { - return Err(AssetAiError::Backend( - "sam3dbody worker json is missing top-level n_people".to_string(), - )); - } - Ok(()) -} - -pub struct BodyBackend { - model_id: String, - worker: Option, -} - -impl BodyBackend { - pub fn new(model_id: &str) -> Self { - Self { - model_id: model_id.to_string(), - worker: None, - } - } - - pub fn with_worker(model_id: &str, worker: BodyWorker) -> Self { - Self { - model_id: model_id.to_string(), - worker: Some(worker), - } - } - - fn worker_mut(&mut self) -> Result<&mut BodyWorker, AssetAiError> { - self.worker.as_mut().ok_or_else(|| { - AssetAiError::Backend("sam3dbody backend used before ensure_loaded".to_string()) - }) - } -} - -impl ContentBackend for BodyBackend { - fn model_id(&self) -> &str { - &self.model_id - } - - fn ensure_loaded(&mut self, ctx: &mut BackendCtx) -> Result<(), AssetAiError> { - ctx.ensure_files()?; - ctx.cancel.check()?; - (ctx.progress)("body: worker", 0.5); - match self.worker.as_mut() { - Some(worker) => worker.ensure_started()?, - None => self.worker = Some(BodyWorker::new()?), - } - (ctx.progress)("body: ready", 1.0); - Ok(()) - } - - fn is_resident(&self) -> bool { - self.worker - .as_ref() - .is_some_and(BodyWorker::is_started) - } - - fn unload(&mut self) -> Result<(), AssetAiError> { - self.worker = None; - Ok(()) - } - - fn generate( - &mut self, - params: &GenerateParams, - progress: ProgressSink, - cancel: &CancelToken, - ) -> Result, AssetAiError> { - if params.input_bytes.is_empty() { - return Err(AssetAiError::Params(format!( - "{} needs an input image (input_b64 png)", - self.model_id - ))); - } - if crate::subproc_img::png_header(¶ms.input_bytes).is_none() { - return Err(AssetAiError::Params( - "sam3dbody input_b64 is not a png".to_string(), - )); - } - cancel.check()?; - progress("body: infer", 0.05); - let worker = self.worker_mut()?; - worker.begin_session(); - let pose = worker.process_png(¶ms.input_bytes, cancel)?; - progress("done", 1.0); - Ok(vec![ArtifactData { - content_type: "application/json", - ext: "json", - bytes: pose.into_bytes(), - }]) - } - - fn live_supported(&self) -> bool { - true - } - - fn live_step( - &mut self, - frame: LiveFrameIn<'_>, - cancel: &CancelToken, - ) -> Result { - cancel.check()?; - let start = Instant::now(); - let init = frame.init.ok_or_else(|| { - AssetAiError::Params("sam3dbody live step requires an input frame".to_string()) - })?; - let png = crate::testpattern::encode_png_rgb8( - &init.data, - init.width as usize, - init.height as usize, - )?; - let worker = self.worker_mut()?; - if frame.frame_index == 0 { - worker.begin_session(); - } - let pose = worker.process_png(&png, cancel)?; - cancel.check()?; - Ok(LiveFrameOut { - image: init.clone(), - aux_json: Some(pose), - model_ms: start.elapsed().as_secs_f64() * 1000.0, - text_encode_ms: 0.0, - }) - } -} diff --git a/libs/ai/hub/src/body_native_backend.rs b/libs/ai/hub/src/body_native_backend.rs index ad97522a9..a5691124e 100644 --- a/libs/ai/hub/src/body_native_backend.rs +++ b/libs/ai/hub/src/body_native_backend.rs @@ -80,6 +80,20 @@ impl BodyOptions { } } +/// The packet contract every body result must meet before it leaves the +/// backend: a JSON object with a top-level `n_people`. +pub fn validate_pose_packet(line: &str) -> Result<(), AssetAiError> { + let value = makepad_strict_json::parse(line.as_bytes()).map_err(|error| { + AssetAiError::Backend(format!("sam3dbody returned invalid json: {error}")) + })?; + if !matches!(&value, makepad_strict_json::Value::Obj(_)) || value.get("n_people").is_none() { + return Err(AssetAiError::Backend( + "sam3dbody json is missing top-level n_people".to_string(), + )); + } + Ok(()) +} + /// Pluggable inference for CPU-only backend tests. pub type BodyFn = Box< dyn FnMut(&[u8], u32, u32, Option<[f32; 4]>) -> Result + Send, @@ -170,7 +184,7 @@ impl BodyNativeBackend { packet.to_json() } }; - crate::body_backend::validate_pose_packet(&packet)?; + validate_pose_packet(&packet)?; Ok(packet) } diff --git a/libs/ai/hub/src/lib.rs b/libs/ai/hub/src/lib.rs index c80f84adf..49415eee8 100644 --- a/libs/ai/hub/src/lib.rs +++ b/libs/ai/hub/src/lib.rs @@ -32,7 +32,8 @@ //! see `protocol.rs`'s wire doc block and `crate::realtime`. pub mod backend; -pub mod body_backend; +#[cfg(feature = "beats-native")] +pub mod beats_backend; pub mod body_native_backend; pub mod chat_wire; pub use makepad_base64; @@ -56,6 +57,8 @@ pub mod http_client; pub mod jobs; pub mod lane_advert; pub mod lease; +#[cfg(feature = "local")] +pub mod license; pub mod indextts_backend; pub mod kokoro_backend; #[cfg(feature = "stt")] @@ -65,6 +68,8 @@ pub mod speech; pub mod llm_backend; #[cfg(feature = "llm")] pub mod local_llm; +#[cfg(feature = "local")] +pub mod local; pub mod matte_backend; pub mod segment_backend; pub mod upscale_backend; @@ -106,6 +111,8 @@ pub mod trellis_backend; pub mod wav; pub mod woosh_backend; pub mod music3_backend; +#[cfg(feature = "notes-native")] +pub mod notes_backend; pub mod world_backend; #[cfg(feature = "flux")] diff --git a/libs/ai/hub/src/registry.rs b/libs/ai/hub/src/registry.rs index 3fe79e62b..6103f83ef 100644 --- a/libs/ai/hub/src/registry.rs +++ b/libs/ai/hub/src/registry.rs @@ -1529,8 +1529,7 @@ mod tests { // The licensing guard lives in the note: the x.1 refreshes are NC. assert!(depth.note.as_deref().unwrap().contains("Apache-2.0")); - // Body domain: pinned native artifact and externally provisioned - // reference worker. + // Body domain: the pinned native artifact. let native_body = registry.find("sam3dbody").unwrap(); assert_eq!(native_body.domain, Domain::Body); assert_eq!(native_body.backend, "body-native"); @@ -1571,13 +1570,6 @@ mod tests { ); assert!(!body_weights.repo.starts_with("facebook/")); - let body = registry.find("sam3dbody-ref").unwrap(); - assert_eq!(body.domain, Domain::Body); - assert_eq!(body.backend, "body"); - assert!(body.available); - assert_eq!(body.vram_gb, Some(4.0)); - assert!(body.files.is_empty()); - // Segment domain: pinned Comfy-Org SAM 3.1 multiplex CUDA artifact. let segment = registry.find("sam3-1-multiplex").unwrap(); assert_eq!(segment.domain, Domain::Segment); diff --git a/libs/ai/hub/tests/body_worker.rs b/libs/ai/hub/tests/body_worker.rs deleted file mode 100644 index b2a628059..000000000 --- a/libs/ai/hub/tests/body_worker.rs +++ /dev/null @@ -1,219 +0,0 @@ -use makepad_ai_hub::backend::{ - CancelToken, ContentBackend, GenerateParams, LiveConfig, LiveFrameIn, RgbImage, -}; -use makepad_ai_hub::body_backend::{ - BodyBackend, BodyWorker, BODY_TIMEOUT_ENV, BODY_WORKER_ENV, -}; -use makepad_ai_hub::protocol::GenerateRequestJson; -use makepad_ai_hub::testpattern::encode_png_rgb8; -use std::io::{Read, Write}; -use std::path::{Path, PathBuf}; -use std::time::{Duration, Instant}; - -const FAKE_FLAG: &str = "MAKEPAD_SAM3DBODY_FAKE_WORKER"; -const FAKE_MODE: &str = "MAKEPAD_SAM3DBODY_FAKE_MODE"; -const FAKE_MARKER: &str = "MAKEPAD_SAM3DBODY_FAKE_MARKER"; -const PACKET: &str = r#"{"n_people":1,"people":[],"opaque":{"keep":[1, 2]}}"#; - -fn main() { - if std::env::var(FAKE_FLAG).ok().as_deref() == Some("1") { - fake_worker_main(); - return; - } - - worker_round_trip_keeps_child_alive(); - worker_restarts_after_child_death(); - worker_stops_after_three_restarts(); - worker_timeout_is_bounded(); - backend_live_step_echoes_frame_and_pose_aux(); - backend_generate_returns_json_artifact(); - unset_worker_command_is_clear(); - println!("body_worker: 7 passed"); -} - -fn fake_worker_main() { - let mode = std::env::var(FAKE_MODE).unwrap_or_else(|_| "normal".to_string()); - if mode == "die" { - return; - } - if mode == "die_once" { - let marker = PathBuf::from(std::env::var(FAKE_MARKER).expect("fake marker")); - if !marker.exists() { - std::fs::write(marker, b"died").expect("write fake marker"); - return; - } - } - - let mut stdin = std::io::stdin().lock(); - let mut stdout = std::io::stdout().lock(); - writeln!(stdout, "{{\"ready\":true}}").expect("fake worker ready"); - stdout.flush().expect("fake worker ready flush"); - loop { - let mut length = [0u8; 4]; - match stdin.read_exact(&mut length) { - Ok(()) => {} - Err(error) if error.kind() == std::io::ErrorKind::UnexpectedEof => return, - Err(error) => panic!("fake worker length read: {error}"), - } - let length = u32::from_le_bytes(length) as usize; - let mut png = vec![0u8; length]; - stdin.read_exact(&mut png).expect("fake worker png read"); - assert!(png.starts_with(b"\x89PNG\r\n\x1a\n")); - if mode == "timeout" { - std::thread::sleep(Duration::from_secs(2)); - } - writeln!(stdout, "{PACKET}").expect("fake worker response"); - stdout.flush().expect("fake worker flush"); - } -} - -struct FakeEnv { - marker: Option, -} - -impl FakeEnv { - fn set(mode: &str, timeout_s: &str, marker: Option<&Path>) -> Self { - let executable = std::env::current_exe().expect("current test executable"); - let command = executable - .to_str() - .expect("test executable path is utf-8") - .to_string(); - assert!(!command.contains(char::is_whitespace)); - std::env::set_var(BODY_WORKER_ENV, command); - std::env::set_var(BODY_TIMEOUT_ENV, timeout_s); - std::env::set_var(FAKE_FLAG, "1"); - std::env::set_var(FAKE_MODE, mode); - if let Some(marker) = marker { - std::env::set_var(FAKE_MARKER, marker); - } else { - std::env::remove_var(FAKE_MARKER); - } - Self { - marker: marker.map(Path::to_path_buf), - } - } -} - -impl Drop for FakeEnv { - fn drop(&mut self) { - std::env::remove_var(BODY_WORKER_ENV); - std::env::remove_var(BODY_TIMEOUT_ENV); - std::env::remove_var(FAKE_FLAG); - std::env::remove_var(FAKE_MODE); - std::env::remove_var(FAKE_MARKER); - if let Some(marker) = self.marker.as_ref() { - let _ = std::fs::remove_file(marker); - } - } -} - -fn test_png() -> Vec { - encode_png_rgb8(&[10, 20, 30, 40, 50, 60], 2, 1).unwrap() -} - -fn worker_round_trip_keeps_child_alive() { - let _env = FakeEnv::set("normal", "1", None); - let mut worker = BodyWorker::new().unwrap(); - let cancel = CancelToken::new(); - assert_eq!(worker.process_png(&test_png(), &cancel).unwrap(), PACKET); - assert_eq!(worker.process_png(&test_png(), &cancel).unwrap(), PACKET); - assert_eq!(worker.restart_count(), 0); -} - -fn worker_restarts_after_child_death() { - let marker = std::env::current_dir() - .unwrap() - .join("target") - .join(format!("body-worker-die-once-{}", std::process::id())); - std::fs::create_dir_all(marker.parent().unwrap()).unwrap(); - let _ = std::fs::remove_file(&marker); - let _env = FakeEnv::set("die_once", "1", Some(&marker)); - let mut worker = BodyWorker::new().unwrap(); - let pose = worker - .process_png(&test_png(), &CancelToken::new()) - .unwrap(); - assert_eq!(pose, PACKET); - assert_eq!(worker.restart_count(), 1); -} - -fn worker_timeout_is_bounded() { - let _env = FakeEnv::set("timeout", "0.05", None); - let mut worker = BodyWorker::new().unwrap(); - let start = Instant::now(); - let error = worker - .process_png(&test_png(), &CancelToken::new()) - .unwrap_err(); - assert!(error.to_string().contains("timed out"), "{error}"); - assert!(start.elapsed() < Duration::from_secs(1)); - assert!(!worker.is_started()); -} - -fn worker_stops_after_three_restarts() { - let _env = FakeEnv::set("die", "1", None); - let mut worker = BodyWorker::new().unwrap(); - let error = worker - .process_png(&test_png(), &CancelToken::new()) - .unwrap_err(); - assert!(error.to_string().contains("after 3 restarts"), "{error}"); - assert_eq!(worker.restart_count(), 3); -} - -fn backend_live_step_echoes_frame_and_pose_aux() { - let _env = FakeEnv::set("normal", "1", None); - let worker = BodyWorker::new().unwrap(); - let mut backend = BodyBackend::with_worker("sam3dbody-ref", worker); - let image = RgbImage { - width: 2, - height: 1, - data: vec![10, 20, 30, 40, 50, 60], - }; - let config = LiveConfig::default(); - let out = backend - .live_step( - LiveFrameIn { - init: Some(&image), - anchor: None, - frame_index: 9, - config: &config, - }, - &CancelToken::new(), - ) - .unwrap(); - assert_eq!(out.image, image); - assert_eq!(out.aux_json.as_deref(), Some(PACKET)); - assert_eq!(out.text_encode_ms, 0.0); -} - -fn backend_generate_returns_json_artifact() { - let _env = FakeEnv::set("normal", "1", None); - let worker = BodyWorker::new().unwrap(); - let mut backend = BodyBackend::with_worker("sam3dbody-ref", worker); - let input_b64 = String::from_utf8(makepad_ai_hub::makepad_base64::base64_encode( - &test_png(), - &makepad_ai_hub::makepad_base64::BASE64_STANDARD, - )) - .unwrap(); - let params = GenerateParams::from_request(&GenerateRequestJson { - model: "sam3dbody-ref".to_string(), - input_b64: Some(input_b64), - ..Default::default() - }) - .unwrap(); - let mut progress = |_: &str, _: f64| {}; - let artifacts = backend - .generate(¶ms, &mut progress, &CancelToken::new()) - .unwrap(); - assert_eq!(artifacts.len(), 1); - assert_eq!(artifacts[0].content_type, "application/json"); - assert_eq!(artifacts[0].ext, "json"); - assert_eq!(artifacts[0].bytes, PACKET.as_bytes()); -} - -fn unset_worker_command_is_clear() { - std::env::remove_var(BODY_WORKER_ENV); - std::env::remove_var(BODY_TIMEOUT_ENV); - let error = BodyWorker::new() - .err() - .expect("an unset worker command must be refused"); - assert!(error.to_string().contains(BODY_WORKER_ENV), "{error}"); -} From 7ff875a33e336d94b79c3a9c970d3a15df84192c Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 01:47:49 +0200 Subject: [PATCH 043/417] ai-hub: keep a peer's in-flight beats/notes/local work out of the body commits The last two hub commits staged whole files and carried uncommitted hunks of another lane (beats-native, notes-native, the local runner, new domains and license keys) that reference files not yet in the tree. This restores those files to the body changes only; the other lane's edits stay in its working tree. Co-Authored-By: Claude Fable 5.1 --- libs/ai/hub/Cargo.toml | 12 -------- libs/ai/hub/registry.json | 59 ------------------------------------- libs/ai/hub/src/backend.rs | 17 ----------- libs/ai/hub/src/lib.rs | 8 ----- libs/ai/hub/src/registry.rs | 51 ++------------------------------ 5 files changed, 3 insertions(+), 144 deletions(-) diff --git a/libs/ai/hub/Cargo.toml b/libs/ai/hub/Cargo.toml index b2c0cae4b..22b82eef3 100644 --- a/libs/ai/hub/Cargo.toml +++ b/libs/ai/hub/Cargo.toml @@ -34,8 +34,6 @@ default = [ "motion-native", "rig-native", "splat-native", - "beats-native", - "notes-native", ] # Box-provisioned Python/Torch reference backends (FlashWorld, Music3, # Depth-Anything-3, and the rig/motion oracles). Not in default: a native @@ -97,14 +95,6 @@ splat-native = ["matte-native", "dep:makepad-ai-splat", "dep:makepad-ai-common"] # lossless skinned-GLB augmentation. The reference Torch/bpy backend remains # separately available as `rig-oracle` through `python-backends`. rig-native = ["dep:makepad-ai-rig", "dep:makepad-ai-common", "dep:makepad-gltf"] -# In-process registry/downloader/backend runner for desktop applications. -# Opt-in so featureless fleet clients do not pull the GPU model substrate. -local = ["dep:makepad-ai-common"] -# Native Beat This! audio -> beat/downbeat JSON analysis. -beats-native = ["dep:makepad-ai-beats", "dep:makepad-ai-common"] -# Native Spotify Basic Pitch audio -> notes/MIDI transcription. The model is -# tiny and has a CPU fallback, so this lane is available without a GPU. -notes-native = ["dep:makepad-ai-notes"] [dependencies] makepad-micro-serde = { path = "../../micro_serde" } @@ -141,8 +131,6 @@ makepad-xatlas = { path = "../../xatlas", optional = true } makepad-render = { path = "../../render", optional = true } makepad-ai-llm = { path = "../../ai/llm", optional = true } makepad-ai-speech = { path = "../../ai/models/speech", default-features = false, optional = true } -makepad-ai-beats = { path = "../../ai/models/beats", optional = true } -makepad-ai-notes = { path = "../../ai/models/notes", optional = true } makepad-system-speech = { path = "../../system_speech", optional = true } makepad-video = { path = "../../../platform/video", optional = true } # The `mkfl` motion payload: ONE definition, shared with the VJ's import diff --git a/libs/ai/hub/registry.json b/libs/ai/hub/registry.json index 70b1344dc..457c3e649 100644 --- a/libs/ai/hub/registry.json +++ b/libs/ai/hub/registry.json @@ -1,64 +1,5 @@ { "models": [ - { - "id": "beat-this", - "domain": "beats", - "backend": "beats", - "available": true, - "gated": false, - "license": { - "name": "MIT License", - "url": "https://github.com/CPJKU/beat_this", - "summary": "Beat This! beat and downbeat tracker (Foscarin, Schl\u00fcter, Widmer 2024), code and released weights MIT; training data partly copyrighted \u2014 weights are unrestricted.", - "restriction": "none" - }, - "vram_gb": 0.5, - "note": "Contract: input_b64 is a WAV, MP3, FLAC or Ogg Vorbis file at any sample rate/channel count; the backend downmixes and resamples to 22050 Hz. Output is one application/json artifact: {bpm, confidence, beats:[seconds], downbeats:[seconds], frame_rate:50}.", - "files": [ - { - "role": "weights", - "repo": "CPJKU/beat_this", - "path": "https://cloud.cp.jku.at/public.php/dav/files/7ik4RrBKTS273gp/final0.ckpt", - "cache_as": "beats/beat_this_final0.ckpt", - "size": 81058141, - "sha256": "8c328b45f59d8dd3dff219253ff6a8d6482be57d0133a29140e2febbf8eb8331" - }, - { - "role": "weights-small", - "repo": "CPJKU/beat_this", - "path": "https://cloud.cp.jku.at/public.php/dav/files/7ik4RrBKTS273gp/small0.ckpt", - "cache_as": "beats/beat_this_small0.ckpt", - "size": 8451101, - "sha256": "6074be2c4d490c5f6101fcc374a1ec72ae93456e23bb6019783b849f5dc7d47b", - "optional": true - } - ] - }, - { - "id": "basic-pitch", - "domain": "notes", - "backend": "notes", - "available": true, - "gated": false, - "license": { - "name": "Apache License 2.0", - "url": "https://github.com/spotify/basic-pitch", - "summary": "Spotify Basic Pitch instrument-agnostic polyphonic note transcription model (ICASSP 2022), Apache-2.0 code and weights; permissive incl. commercial.", - "restriction": "none" - }, - "vram_gb": 0.1, - "note": "Request: domain notes with input_b64 containing a PCM WAV (16/24/32-bit integer or f32, any sample rate/channels). Response artifacts: application/json {frame_rate,notes:[{start_secs,end_secs,midi,amplitude,bends:[semitones_per_frame]}]} and audio/midi .mid bytes with per-note pitch bends in the standard +/-2-semitone range.", - "files": [ - { - "role": "model", - "repo": "spotify/basic-pitch", - "path": "https://github.com/spotify/basic-pitch/raw/main/basic_pitch/saved_models/icassp_2022/nmp.onnx", - "cache_as": "notes/basic_pitch_nmp.onnx", - "size": 230444, - "sha256": "2c3c1d144bfa61ad236e92e169c13535c880469a12a047d4e73451f2c059a0ec" - } - ] - }, { "id": "hunyuan3d-paint-2.1", "domain": "paint", diff --git a/libs/ai/hub/src/backend.rs b/libs/ai/hub/src/backend.rs index d7f928363..ec7cd5ef1 100644 --- a/libs/ai/hub/src/backend.rs +++ b/libs/ai/hub/src/backend.rs @@ -1219,7 +1219,6 @@ pub fn validate_loras_for_backend( /// One generated output. `content_type` drives the `/artifact` response; /// `ext` names the file on disk. -#[derive(Clone, Debug)] pub struct ArtifactData { pub content_type: &'static str, pub ext: &'static str, @@ -1569,7 +1568,6 @@ pub fn backend_compiled(name: &str) -> bool { // so it is compiled in exactly when the LLM is. "vision" => cfg!(feature = "llm"), "ocr" => cfg!(feature = "llm"), - "notes" => cfg!(feature = "notes-native"), "kokoro" => cfg!(feature = "tts"), "whisper" => cfg!(feature = "stt"), "indextts" => cfg!(feature = "indextts"), @@ -1579,7 +1577,6 @@ pub fn backend_compiled(name: &str) -> bool { "moss" => cfg!(feature = "audio"), "woosh" => cfg!(feature = "audio"), "ace" => cfg!(feature = "audio"), - "beats" => cfg!(feature = "beats-native"), "trellis" => cfg!(feature = "mesh"), "paint" | "paint-test" => cfg!(feature = "paint"), "matte-native" => cfg!(feature = "matte-native"), @@ -1769,13 +1766,6 @@ pub fn model_availability( pub fn create_backend(spec: &ModelSpec) -> Result, AssetAiError> { match spec.backend.as_str() { - #[cfg(feature = "notes-native")] - "notes" => Ok(Box::new(crate::notes_backend::NotesBackend::new(&spec.id))), - #[cfg(not(feature = "notes-native"))] - "notes" => Err(AssetAiError::Unavailable(format!( - "model {} needs a build with the 'notes-native' cargo feature", - spec.id - ))), #[cfg(feature = "paint")] "paint" | "paint-test" => Ok(Box::new(crate::paint_backend::PaintBackend::new(spec))), "testpattern" => Ok(Box::new(crate::testpattern::TestPatternBackend::new( @@ -1890,13 +1880,6 @@ pub fn create_backend(spec: &ModelSpec) -> Result, Asset ))), #[cfg(feature = "audio")] "ace" => Ok(Box::new(crate::ace_backend::AceBackend::new_ace(&spec.id))), - #[cfg(feature = "beats-native")] - "beats" => Ok(Box::new(crate::beats_backend::BeatsBackend::new(&spec.id))), - #[cfg(not(feature = "beats-native"))] - "beats" => Err(AssetAiError::Unavailable(format!( - "model {} needs a build with the 'beats-native' cargo feature", - spec.id - ))), #[cfg(not(feature = "audio"))] "moss" => Err(AssetAiError::Unavailable(format!( "model {} needs a build with the 'audio' cargo feature", diff --git a/libs/ai/hub/src/lib.rs b/libs/ai/hub/src/lib.rs index 49415eee8..3da743a22 100644 --- a/libs/ai/hub/src/lib.rs +++ b/libs/ai/hub/src/lib.rs @@ -32,8 +32,6 @@ //! see `protocol.rs`'s wire doc block and `crate::realtime`. pub mod backend; -#[cfg(feature = "beats-native")] -pub mod beats_backend; pub mod body_native_backend; pub mod chat_wire; pub use makepad_base64; @@ -57,8 +55,6 @@ pub mod http_client; pub mod jobs; pub mod lane_advert; pub mod lease; -#[cfg(feature = "local")] -pub mod license; pub mod indextts_backend; pub mod kokoro_backend; #[cfg(feature = "stt")] @@ -68,8 +64,6 @@ pub mod speech; pub mod llm_backend; #[cfg(feature = "llm")] pub mod local_llm; -#[cfg(feature = "local")] -pub mod local; pub mod matte_backend; pub mod segment_backend; pub mod upscale_backend; @@ -111,8 +105,6 @@ pub mod trellis_backend; pub mod wav; pub mod woosh_backend; pub mod music3_backend; -#[cfg(feature = "notes-native")] -pub mod notes_backend; pub mod world_backend; #[cfg(feature = "flux")] diff --git a/libs/ai/hub/src/registry.rs b/libs/ai/hub/src/registry.rs index 6103f83ef..c3b846f9d 100644 --- a/libs/ai/hub/src/registry.rs +++ b/libs/ai/hub/src/registry.rs @@ -198,14 +198,6 @@ pub enum Domain { /// Speech audio -> timed transcript (Whisper). The `stt.whisper` pipe; /// `Speech` stays text-to-speech, so the two never share affinity. Stt, - /// Audio -> beat and downbeat tracking JSON. - Beats, - /// Audio -> polyphonic note transcription JSON/MIDI. - Notes, - /// Audio -> music-structure sections. - Sections, - /// Image -> sewing-pattern JSON. - Garment, } impl Domain { @@ -235,10 +227,6 @@ impl Domain { "vision" => Some(Domain::Vision), "ocr" => Some(Domain::Ocr), "stt" => Some(Domain::Stt), - "beats" => Some(Domain::Beats), - "notes" => Some(Domain::Notes), - "sections" => Some(Domain::Sections), - "garment" => Some(Domain::Garment), _ => None, } } @@ -269,10 +257,6 @@ impl Domain { Domain::Vision => "vision", Domain::Ocr => "ocr", Domain::Stt => "stt", - Domain::Beats => "beats", - Domain::Notes => "notes", - Domain::Sections => "sections", - Domain::Garment => "garment", } } } @@ -394,14 +378,11 @@ pub struct ModelLicense { impl ModelLicense { /// Stable identity of the *text* the user accepted: sha256 when pinned, - /// otherwise a hash of the licence name and canonical URL. A registry - /// correction to either value therefore prompts again. + /// otherwise the canonical URL. pub fn identity(&self) -> String { self.sha256 .clone() - .unwrap_or_else(|| { - crate::sha256::sha256_hex(format!("{}\0{}", self.name, self.url).as_bytes()) - }) + .unwrap_or_else(|| self.url.clone()) } } @@ -475,7 +456,7 @@ impl Registry { for model in wire.models { let domain = Domain::parse(&model.domain).ok_or_else(|| { AssetAiError::Registry(format!( - "model {}: unknown domain {:?} (expected image|mesh|video|audio|text|speech|world|matte|depth|body|segment|rig|motion|music|paint|edit|upscale|control|inpaint|enhance|splat|vision|ocr|beats|notes|sections|garment)", + "model {}: unknown domain {:?} (expected image|mesh|video|audio|text|speech|world|matte|depth|body|segment|rig|motion)", model.id, model.domain )) })?; @@ -896,19 +877,6 @@ mod tests { registry.find("pbr-testpattern").is_none(), "deterministic paint-test is crate-internal and must not advertise" ); - let beats = registry.find("beat-this").unwrap(); - assert_eq!(beats.domain, Domain::Beats); - assert_eq!(beats.backend, "beats"); - assert_eq!(beats.vram_gb, Some(0.5)); - assert_eq!(beats.files.len(), 2); - let final_weights = beats.file_by_role("weights").unwrap(); - assert_eq!(final_weights.size, Some(81_058_141)); - assert_eq!( - final_weights.sha256.as_deref(), - Some("8c328b45f59d8dd3dff219253ff6a8d6482be57d0133a29140e2febbf8eb8331") - ); - assert!(final_weights.path.starts_with("https://cloud.cp.jku.at/")); - assert!(beats.file_by_role("weights-small").unwrap().optional); let hunyuan = registry.find("hunyuan3d-paint-2.1").unwrap(); assert_eq!(hunyuan.domain, Domain::Paint); assert_eq!(hunyuan.backend, "paint"); @@ -1842,17 +1810,4 @@ mod tests { let message = Registry::parse(json).unwrap_err().to_string(); assert!(message.contains("unknown license restriction"), "{message}"); } - - #[test] - fn local_app_domains_round_trip() { - for (text, domain) in [ - ("beats", Domain::Beats), - ("notes", Domain::Notes), - ("sections", Domain::Sections), - ("garment", Domain::Garment), - ] { - assert_eq!(Domain::parse(text), Some(domain)); - assert_eq!(domain.as_str(), text); - } - } } From c189b035affc1e16a2aa8adc858853b7415e3da8 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 02:29:06 +0200 Subject: [PATCH 044/417] =?UTF-8?q?game=20brief:=20agents=20follow=20the?= =?UTF-8?q?=20rules=20by=20themselves=20=E2=80=94=20you=20never=20script?= =?UTF-8?q?=20a=20stop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- libs/asset/chat/context/game.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/libs/asset/chat/context/game.md b/libs/asset/chat/context/game.md index c13420c88..ea251adeb 100644 --- a/libs/asset/chat/context/game.md +++ b/libs/asset/chat/context/game.md @@ -79,7 +79,7 @@ A "small car" = `world.spawn({model: "...", scale: 0.5})` or `scale: "small"` CITIES, VILLAGES, RACETRACKS, RAILWAYS, ROADS, FORESTS AND DUNGEONS ARE ONE CALL; never hand-place their tiles. They are deterministic from seed: -- `game.city({seed, size, density})`, `game.village({seed, size})`, and +- `game.city({seed, size, density, pos})`, `game.village({seed, size, pos})`, and `game.dungeon({kit, extent, seed})` build complete layouts. - `game.scatter({models, pos, size, spacing, count, seed})` builds forests or crowds while avoiding earlier roads/buildings. @@ -103,6 +103,13 @@ never hand-place their tiles. They are deterministic from seed: AFTER it crosses on a BRIDGE automatically — deck clearing the water, piers standing in the shallows. Call game.river BEFORE the roads and railways that must bridge it; never ford a river with a flat road. + THE ENGINE KEEPS THE MAP SANE regardless of call order: a town whose + footprint touches a river slides to its bank (`pos` is the town CENTRE), + lots on water or on a road are left unbuilt, props and characters asked + for in water are steered to the shore, a river carved after a town bends + around it, and every corridor — city streets included — bridges water + with freeboard. Each repair is logged as an "assist" line; read them and + edit the plan rather than fighting them. - `game.racetrack({seed, size, complexity})` — a complete circuit as one generated road surface (true swept corners, graded, bridged) — returns slots, checkpoints, start and waypoints. A race's essential shape is: @@ -128,6 +135,8 @@ never hand-place their tiles. They are deterministic from seed: railway at its own measured size (front faces -Z). A railway's essential shape is: game.traintrack({seed: 3, size: 90}) + An authored `path` is an OPEN line unless you say `closed: true` (a + crossing line is two points; a loop needs three or more). game.train({cars: 4}) game.race({laps: 3}) game.player_character({pos: t.start, model: "kenney/mini-characters/character-male-b"}) @@ -231,6 +240,16 @@ game.follower(id, {target, near, far}) — companion; never attacks game.pacer(id, {speed, turn_at: ["wall","edge"]}) — walks a line, turns at walls/drop-offs; with hurt rules it is the classic 2D enemy game.patroller(id, {points | axis: "x" + span, pause, turn_at}) — routes +game.pedestrians({count, near, range}) — walkers on the sidewalks: they + keep to the sidewalks, cross only at crosswalks on the walk phase, wait at + closed rail gates, and cars brake for them. NEVER script a stop or a + crossing — the corridor graph governs every agent automatically. +game.route(id, {to}) — send a car or pedestrian to a point over the graph + (lanes, turns, lights obeyed). game.autodrive(car, {points, stops, dwell}) + with streets under the points drives the LANES: right side, speed limits, + red lights, gates, the car ahead; stops+dwell make it a bus. +game.train({..., pace, stops: [pos...], dwell}) — a timetable service: drives + itself, stops at its platforms, holds behind the train in the block ahead. game.wanderer(id, {home, range, pois: [tags]}) — ambler; pois = villager game.pickup(id, {give: {health, ammo, count, key, weapon}, respawn}) game.hazard(id, {damage, period}) — a volume that hurts (lava, spikes) From f4af6df5a008b191d5444b073e2f9ed862c4e479 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 02:38:40 +0200 Subject: [PATCH 045/417] =?UTF-8?q?sim:=20terrain=20knows=20who=20changed?= =?UTF-8?q?=20it=20=E2=80=94=20a=20plan=20layer=20over=20player=20history?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Chunks keep the player's bytes apart from the composed density: plan presses land in an owner-keyed PlanTerrainPatch that is retracted with its feature and never touches history, so removing a railway takes its bed with it and a human fill under it survives. Surface queries answer Surface | Hole | Outside instead of pretending the heightfield continues over a hole or past the border; landforms issued inside a plan eval are plan, outside it history. Seven tests pin the layering, including same-inputs-twice equality. Co-Authored-By: Claude Fable 5.1 --- libs/sim/src/landform.rs | 17 +++ libs/sim/src/terrain.rs | 19 +++ libs/sim/src/voxel.rs | 283 +++++++++++++++++++++++++++++++---- libs/sim/src/world.rs | 78 +++++++++- libs/sim/tests/plan_layer.rs | 218 +++++++++++++++++++++++++++ 5 files changed, 584 insertions(+), 31 deletions(-) create mode 100644 libs/sim/tests/plan_layer.rs diff --git a/libs/sim/src/landform.rs b/libs/sim/src/landform.rs index 466932fb0..d64efe13c 100644 --- a/libs/sim/src/landform.rs +++ b/libs/sim/src/landform.rs @@ -407,6 +407,23 @@ fn same_landform(a: &VoxelOp, b: &VoxelOp) -> bool { /// own landform line) applies heightfield-only — the chunks already carry /// its voxel effect plus everything dug since. pub fn host_apply_landform(world: &mut GameWorld, op: VoxelOp) { + // A landform issued by the level source is a PLAN product (worldgen + // DESIGN.md, amendment B): the next eval re-derives it on the rebuilt + // heightfield, a removed line removes the mountain, and it is never + // recorded or persisted as history. Heightfield-only — composing it + // into materialized chunks would bake plan into history bytes (the + // voxel-side plan overlay for landforms is the next step). It still + // replicates so replicas raise the same ground. + if world.in_plan_eval { + if let Some(field) = world.voxel.as_deref_mut() { + if field.pending_ops.len() < 65536 { + field.pending_ops.push(op); + } + } + apply_landform_op(world, op, false); + return; + } + world.history_revision = world.history_revision.wrapping_add(1); let mut overflow = false; let field = world .voxel diff --git a/libs/sim/src/terrain.rs b/libs/sim/src/terrain.rs index 549e3fc06..bd80b1ffe 100644 --- a/libs/sim/src/terrain.rs +++ b/libs/sim/src/terrain.rs @@ -53,6 +53,25 @@ pub struct TerrainMaterials { pub surfaces: Vec, } +impl TerrainMaterials { + /// Is the heightfield cell under (x, z) punched out (box3d's `0xFF` + /// hole value)? Row-major `(cells-1)²` like the indices themselves; + /// a missing entry is material 0, never a hole. + pub fn is_hole_at(&self, terrain: &Terrain, x: f32, z: f32) -> bool { + let fx = (x - terrain.origin) / terrain.cell_size; + let fz = (z - terrain.origin) / terrain.cell_size; + if fx < 0.0 || fz < 0.0 || terrain.cells < 2 { + return false; + } + let side = terrain.cells - 1; + let (ix, iz) = (fx.floor() as usize, fz.floor() as usize); + if ix >= side || iz >= side { + return false; + } + self.indices.get(iz * side + ix).is_some_and(|m| *m == 0xFF) + } +} + impl Terrain { /// Piecewise-planar ground height at (x, z): the two triangles per cell, /// same split the mesh uses, so collision and pixels agree. None outside. diff --git a/libs/sim/src/voxel.rs b/libs/sim/src/voxel.rs index ca5d89e85..1674ade87 100644 --- a/libs/sim/src/voxel.rs +++ b/libs/sim/src/voxel.rs @@ -87,11 +87,67 @@ fn site_index(lx: i32, ly: i32, lz: i32) -> usize { /// what schedules remeshing, collider swaps and wire resends. #[derive(Clone, Debug)] pub struct VoxelChunk { + /// The COMPOSED density every mesher and probe reads: the history layer + /// with the plan patch clipped over it. pub density: Vec, + /// The HISTORY layer alone — the player's digs, fills and tunnels. This + /// is what persists, replicates as chunk bytes and survives a plan + /// change; a plan press never writes here, so retracting a railway + /// cannot leave its berm behind and a snapshot cannot bake it. + pub history: Vec, pub material: Vec, pub rev: u64, } +/// One PLAN-layer press: open air above the plane `y` inside the x/z box. +/// `owner` is the plan feature that asked for it (0 = arrived over the +/// wire without provenance), the key a retraction uses. +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct PlanPress { + pub owner: u64, + pub min: Vec3f, + pub max: Vec3f, + pub y: f32, +} + +/// The plan's terrain patch over the voxel layer (worldgen DESIGN.md, +/// amendment B): derived from plan features, rebuilt by every solve, +/// retracted by owner, composed over the history at READ time and never +/// written into chunk bytes. Presses today; lot pads and channel carves +/// take the same shape. +#[derive(Clone, Debug, Default)] +pub struct PlanTerrainPatch { + pub presses: Vec, +} + +impl PlanTerrainPatch { + pub fn is_empty(&self) -> bool { + self.presses.is_empty() + } + + /// The plan's clip at a world point: the strongest "air above the pad + /// plane" any press asks for there, `None` when no press covers the + /// column. + pub fn clip(&self, w: Vec3f, cell: f32) -> Option { + let mut best: Option = None; + for p in &self.presses { + if w.x >= p.min.x && w.x <= p.max.x && w.z >= p.min.z && w.z <= p.max.z { + let q = VoxelField::quantize((w.y - p.y) / cell); + best = Some(best.map_or(q, |b| b.max(q))); + } + } + best + } + + /// History composed with the plan: air wins wherever a press clips. + pub fn compose(history: i8, clip: Option) -> i8 { + match clip { + Some(q) => history.max(q), + None => history, + } + } +} + /// Which mesher a volume uses (D5: two meshers, one field). #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum VoxelMode { @@ -299,6 +355,10 @@ pub struct VoxelField { pub persist_overflow: bool, /// Terrain revision the heightfield hole-punch was last applied against. pub punch_rev: Option, + /// The plan layer over this field — see [`PlanTerrainPatch`]. Cleared on + /// every reset_content (the eval re-registers every press it still + /// wants), never persisted, never part of a chunk blob. + pub plan: PlanTerrainPatch, /// Monotonic mesh revision source. mesh_rev: u64, /// One-shot "chunk cap hit" log latch. @@ -323,6 +383,7 @@ impl VoxelField { persist_ops: Vec::new(), persist_overflow: false, punch_rev: None, + plan: PlanTerrainPatch::default(), mesh_rev: 0, cap_logged: false, } @@ -568,6 +629,20 @@ impl VoxelField { /// crossing in materialized data. `None` also when the column was carved /// clean through everything materialized (the caller falls back to the /// heightfield, which is what the base layer below would say). + /// Does a materialized column own the surface at (x, z)? The sites just + /// above and below the base surface are both in chunks — the punch rule. + /// Ownership without a floor below means a HOLE, not "ask the + /// heightfield" (see `GameWorld::surface_sample_at`). + pub fn owns_surface(&self, x: f32, z: f32, base_h: f32) -> bool { + if self.chunks.is_empty() { + return false; + } + let air = self.world_site(vec3f(x, base_h, z)); + let solid = [air[0], air[1] - 1, air[2]]; + self.chunks.contains_key(&ChunkKey::of_site(air)) + && self.chunks.contains_key(&ChunkKey::of_site(solid)) + } + pub fn surface_at(&self, x: f32, z: f32, base_h: f32) -> Option { if self.chunks.is_empty() { return None; @@ -710,10 +785,15 @@ impl VoxelField { } } } + // The base layer IS history at birth (nothing has been dug yet); + // the plan clips over it at read time. + let history = density; + let density = self.compose_history(key, &history); self.chunks.insert( key, VoxelChunk { density, + history, material, rev: 1, }, @@ -745,6 +825,16 @@ impl VoxelField { record: bool, log: &mut Vec, ) { + // A press is PLAN, not history: it registers in the patch (owner 0 — + // the wire carries no provenance) and composes at read time. The + // op still records so replicas compose the same patch. + if let VoxelOp::Press { min, max, y } = op { + self.plan_press(0, min, max, y); + if record { + self.record_op(op); + } + return; + } let (lo, hi) = self.op_site_bounds(&op); // Materialize every chunk the op's bounds touch — the WHOLE world is // implicitly editable; lazy materialization is what keeps that free @@ -796,6 +886,7 @@ impl VoxelField { }) .copied() .collect(); + let plan = self.plan.clone(); for key in keys { let b = key.base(); let (x0, x1) = (lo[0].max(b[0]), hi[0].min(b[0] + CHUNK - 1)); @@ -810,7 +901,9 @@ impl VoxelField { let s = [sx, sy, sz]; let w = vec3f(s[0] as f32 * cell, s[1] as f32 * cell, s[2] as f32 * cell); let at = site_index(sx - b[0], sy - b[1], sz - b[2]); - let old_d = chunk.density[at]; + // History ops read and write the HISTORY layer; the + // composed byte is re-derived from it below. + let old_d = chunk.history[at]; let old_m = chunk.material[at]; let (new_d, new_m) = match op { VoxelOp::Dig { pos, r, mode, material } => { @@ -867,23 +960,15 @@ impl VoxelField { let nd = old_d.max(q); (nd, if nd >= 0 { 0 } else { old_m }) } - VoxelOp::Press { min, max, y } => { - // Open air above the pad plane inside the box — - // the voxel twin of the heightfield press. - if w.x >= min.x && w.x <= max.x && w.z >= min.z && w.z <= max.z { - let q = Self::quantize((w.y - y) / cell); - let nd = old_d.max(q); - (nd, if nd >= 0 { 0 } else { old_m }) - } else { - (old_d, old_m) - } - } + // Routed into the plan patch above; never a site op. + VoxelOp::Press { .. } => (old_d, old_m), // World-level appliers own it (crate::landform); // reaching here is a routing bug, kept harmless. VoxelOp::Landform { .. } => (old_d, old_m), }; if new_d != old_d || new_m != old_m { - chunk.density[at] = new_d; + chunk.history[at] = new_d; + chunk.density[at] = PlanTerrainPatch::compose(new_d, plan.clip(w, cell)); chunk.material[at] = new_m; changed_any = true; chunk.rev += 1; @@ -910,17 +995,154 @@ impl VoxelField { } } if record { - // Leak guard for hosts that never pump a session (raw sim tests): - // the session drains this every tick in every role. - if self.pending_ops.len() < 65536 { - self.pending_ops.push(op); + self.record_op(op); + } + } + + fn record_op(&mut self, op: VoxelOp) { + // Leak guard for hosts that never pump a session (raw sim tests): + // the session drains this every tick in every role. + if self.pending_ops.len() < 65536 { + self.pending_ops.push(op); + } + // The persistence tail (drained by the app's debounced saver). + if self.persist_ops.len() < 8192 { + self.persist_ops.push(op); + } else { + self.persist_overflow = true; + self.persist_ops.clear(); + } + } + + // ── the plan layer ────────────────────────────────────────────────── + + /// Register a plan press (a foundation pad, a corridor bed) keyed by its + /// owning feature. Composed over the history at read time; the chunk + /// bytes never change, so a retraction is exact and a snapshot never + /// bakes it. + pub fn plan_press(&mut self, owner: u64, min: Vec3f, max: Vec3f, y: f32) { + let press = PlanPress { + owner, + min: vec3f(min.x.min(max.x), min.y.min(max.y), min.z.min(max.z)), + max: vec3f(min.x.max(max.x), min.y.max(max.y), min.z.max(max.z)), + y, + }; + if self.plan.presses.contains(&press) { + return; + } + self.plan.presses.push(press); + self.recompose_region(press.min, press.max); + } + + /// Drop every plan press `owner` registered and give the ground back to + /// its history — the berm leaves with the railway. + pub fn retract_plan(&mut self, owner: u64) { + let gone: Vec = + self.plan.presses.iter().filter(|p| p.owner == owner).copied().collect(); + if gone.is_empty() { + return; + } + self.plan.presses.retain(|p| p.owner != owner); + for p in gone { + self.recompose_region(p.min, p.max); + } + } + + /// Drop the whole plan layer (a solve starts from nothing and re-registers + /// every press it still wants). + pub fn clear_plan(&mut self) { + let all = std::mem::take(&mut self.plan.presses); + for p in all { + self.recompose_region(p.min, p.max); + } + } + + /// The history bytes of a chunk — what persistence and the wire carry. + pub fn chunk_history(&self, key: ChunkKey) -> Option<&[i8]> { + self.chunks.get(&key).map(|c| c.history.as_slice()) + } + + /// `history ⊕ plan` for one chunk's worth of sites. + fn compose_history(&self, key: ChunkKey, history: &[i8]) -> Vec { + if self.plan.is_empty() { + return history.to_vec(); + } + let b = key.base(); + let cell = self.cell; + let mut out = history.to_vec(); + for lz in 0..CHUNK { + for lx in 0..CHUNK { + for ly in 0..CHUNK { + let w = vec3f( + (b[0] + lx) as f32 * cell, + (b[1] + ly) as f32 * cell, + (b[2] + lz) as f32 * cell, + ); + let at = site_index(lx, ly, lz); + out[at] = PlanTerrainPatch::compose(history[at], self.plan.clip(w, cell)); + } } - // The persistence tail (drained by the app's debounced saver). - if self.persist_ops.len() < 8192 { - self.persist_ops.push(op); - } else { - self.persist_overflow = true; - self.persist_ops.clear(); + } + out + } + + /// Recompose every materialized chunk under the x/z box after the plan + /// changed there; a chunk whose composed bytes moved is dirtied with its + /// neighbours (their meshes sampled its apron). + fn recompose_region(&mut self, min: Vec3f, max: Vec3f) { + let cell = self.cell; + let span = CHUNK as f32 * cell; + let keys: Vec = self + .chunks + .keys() + .filter(|k| { + let x0 = k.x as f32 * span; + let z0 = k.z as f32 * span; + x0 <= max.x && x0 + span >= min.x && z0 <= max.z && z0 + span >= min.z + }) + .copied() + .collect(); + let plan = self.plan.clone(); + let mut changed_keys = Vec::new(); + for key in keys { + let b = key.base(); + let Some(chunk) = self.chunks.get_mut(&key) else { + continue; + }; + let mut changed = false; + for lz in 0..CHUNK { + for lx in 0..CHUNK { + let x = (b[0] + lx) as f32 * cell; + let z = (b[2] + lz) as f32 * cell; + for ly in 0..CHUNK { + let y = (b[1] + ly) as f32 * cell; + let at = site_index(lx, ly, lz); + let d = PlanTerrainPatch::compose( + chunk.history[at], + plan.clip(vec3f(x, y, z), cell), + ); + if d != chunk.density[at] { + chunk.density[at] = d; + changed = true; + } + } + } + } + if changed { + chunk.rev += 1; + changed_keys.push(key); + } + } + for key in changed_keys { + for dx in -1..=1 { + for dy in -1..=1 { + for dz in -1..=1 { + let k = ChunkKey { x: key.x + dx, y: key.y + dy, z: key.z + dz }; + if self.chunks.contains_key(&k) { + self.mark_dirty(k); + } + } + } } } } @@ -949,6 +1171,7 @@ impl VoxelField { return; } let cell = self.cell; + let plan = self.plan.clone(); let span = CHUNK as f32 * cell; let cols: std::collections::BTreeSet<(i32, i32)> = self .chunks @@ -997,7 +1220,7 @@ impl VoxelField { for ly in 0..CHUNK { let y = (b[1] + ly) as f32 * cell; let at = site_index(lx, ly, lz); - let old_d = chunk.density[at]; + let old_d = chunk.history[at]; let old_m = chunk.material[at]; let mut nd = old_d; let mut nm = old_m; @@ -1020,7 +1243,9 @@ impl VoxelField { } } if nd != old_d || nm != old_m { - chunk.density[at] = nd; + chunk.history[at] = nd; + chunk.density[at] = + PlanTerrainPatch::compose(nd, plan.clip(vec3f(x, y, z), cell)); chunk.material[at] = nm; changed = true; } @@ -1098,7 +1323,10 @@ impl VoxelField { return; } let rev = self.chunks.get(&key).map_or(1, |c| c.rev + 1); - self.chunks.insert(key, VoxelChunk { density, material, rev }); + // A blob carries HISTORY bytes; the plan composes over them here. + let history = density; + let density = self.compose_history(key, &history); + self.chunks.insert(key, VoxelChunk { density, history, material, rev }); for dx in -1..=1 { for dy in -1..=1 { for dz in -1..=1 { @@ -1164,6 +1392,9 @@ impl VoxelField { /// data they were built from is still here, and a re-declared volume /// re-marks what its mode change affects. pub fn on_reset_content(&mut self) { + // The plan layer is script content: the eval re-registers every + // press it still wants, and a feature that vanished leaves nothing. + self.clear_plan(); self.volumes.clear(); self.structure_rev += 1; self.punch_rev = None; diff --git a/libs/sim/src/world.rs b/libs/sim/src/world.rs index bb962957b..df1e2ca3a 100644 --- a/libs/sim/src/world.rs +++ b/libs/sim/src/world.rs @@ -14,6 +14,31 @@ use crate::entity::*; use crate::terrain::*; use crate::CallbackSlot; +/// One answer from the world-surface seam — see +/// [`GameWorld::surface_sample_at`]. +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum SurfaceSample { + /// Ground at this height. + Surface(f32), + /// The column is open: carved through, or a punched heightfield cell. + Hole, + /// Beyond the heightfield (and no voxel ownership). + Outside, +} + +impl SurfaceSample { + /// The height where there is ground; `None` for a hole or the outside. + pub fn height(self) -> Option { + match self { + SurfaceSample::Surface(h) => Some(h), + _ => None, + } + } + pub fn is_ground(self) -> bool { + matches!(self, SurfaceSample::Surface(_)) + } +} + /// Everything the script API reads/writes. Shared (Rc) between the /// widget and the native `game` handle registered into the isolate, so script /// calls mutate it synchronously — no async widget trampoline, deterministic @@ -158,6 +183,19 @@ pub struct GameWorld { /// worlds that never do carry a null pointer and every pre-voxel code /// path byte-identically. pub voxel: Option>, + /// True while the host evaluates the level source (a PLAN solve). Ops + /// issued inside it are plan products — re-derived by the next eval, + /// retracted when their line is gone, never history; ops issued outside + /// it (a brush, an excavator, a hand controller) are history. Set and + /// cleared by the script host around eval. + pub in_plan_eval: bool, + /// Solve epochs (worldgen DESIGN.md, amendment E): `plan_revision` + /// advances once per level eval, `history_revision` once per HISTORY + /// terrain op (dig, tunnel, brush landform). A solve records the history + /// epoch it read and can refuse to commit products derived from older + /// ground once solves run off the play thread. + pub plan_revision: u64, + pub history_revision: u64, /// Water volumes with an analytic wave surface (mix.md D7/W1). None /// until `game.water` declares one — same null-pointer contract as /// `voxel`: worlds without it run every pre-water path byte-identically. @@ -235,16 +273,41 @@ impl GameWorld { /// at once. `None` outside the heightfield (and outside any voxel /// ownership): flat/streamed worlds keep their own floor rules. pub fn surface_height_at(&self, x: f32, z: f32) -> Option { + self.surface_sample_at(x, z).height() + } + + /// The seam with its edges spelled out (worldgen DESIGN.md, amendment + /// B): `Surface(h)` where ground exists, `Hole` where the column has + /// been carved through or the heightfield cell is punched out, `Outside` + /// beyond the heightfield. A hole is never the heightfield underneath + /// it (placement used to see ground over a pit) and the border is + /// never height 0. + pub fn surface_sample_at(&self, x: f32, z: f32) -> SurfaceSample { let base = self.terrain.as_ref().and_then(|t| t.height_at(x, z)); if let Some(v) = self.voxel.as_deref() { - if v.chunk_count() > 0 { - // No terrain = the voxel base layer's y=0 ground plane. - if let Some(h) = v.surface_at(x, z, base.unwrap_or(0.0)) { - return Some(h); + // No terrain = the voxel base layer's y=0 ground plane. + let base_h = base.unwrap_or(0.0); + if v.chunk_count() > 0 && v.owns_surface(x, z, base_h) { + return match v.surface_at(x, z, base_h) { + Some(h) => SurfaceSample::Surface(h), + None => SurfaceSample::Hole, + }; + } + } + match base { + None => SurfaceSample::Outside, + Some(h) => { + let punched = match (&self.terrain, &self.terrain_materials) { + (Some(t), Some(m)) => m.is_hole_at(t, x, z), + _ => false, + }; + if punched { + SurfaceSample::Hole + } else { + SurfaceSample::Surface(h) } } } - base } /// A world with the canonical starting camera (the values the gamemaker @@ -576,6 +639,11 @@ impl GameWorld { let field = voxel .get_or_insert_with(|| Box::new(crate::voxel::VoxelField::new(0.5))); field.apply_op(op, terrain.as_ref(), true, true, log_pending); + // A press is plan (routed into the patch inside apply_op); every + // other op is HISTORY and moves the epoch a solve commits against. + if !matches!(op, crate::voxel::VoxelOp::Press { .. }) { + self.history_revision = self.history_revision.wrapping_add(1); + } } } diff --git a/libs/sim/tests/plan_layer.rs b/libs/sim/tests/plan_layer.rs new file mode 100644 index 000000000..355becea0 --- /dev/null +++ b/libs/sim/tests/plan_layer.rs @@ -0,0 +1,218 @@ +//! The plan layer over the destructible terrain (worldgen DESIGN.md, +//! amendment B): plan presses compose over history at read time and never +//! touch history bytes; a retracted feature leaves nothing; a human fill +//! under a plan press survives it; holes and the border answer as +//! themselves; the same (plan, history) composes to the same bytes twice. + +use makepad_game_sim::voxel::{ChunkKey, DigMode}; +use makepad_game_sim::*; +use makepad_math::*; + +fn flat_terrain(h: f32) -> Terrain { + let cells = 33; + let cell_size = 2.0; + let origin = -32.0; + Terrain { + cells, + cell_size, + origin, + heights: vec![h; cells * cells], + colors: vec![vec4f(0.4, 0.6, 0.4, 1.0); cells * cells], + revision: 1, + } +} + +fn world() -> GameWorld { + let mut w = GameWorld::new(); + w.terrain = Some(flat_terrain(4.0)); + w +} + +fn field(w: &mut GameWorld) -> &mut makepad_game_sim::voxel::VoxelField { + w.voxel + .get_or_insert_with(|| Box::new(makepad_game_sim::voxel::VoxelField::new(0.5))) +} + +/// A history op that materializes the chunks around the origin: a shallow +/// fill dome, so the surface there is ABOVE the plane a press will ask for. +fn fill_mound(w: &mut GameWorld) { + w.apply_voxel_op(VoxelOp::Dig { + pos: vec3f(0.0, 4.0, 0.0), + r: 3.0, + mode: DigMode::Fill, + material: 2, + }); +} + +#[test] +fn a_plan_press_never_touches_history_bytes() { + let mut w = world(); + fill_mound(&mut w); + let before = w.surface_height_at(0.0, 0.0).expect("mound owns the surface"); + assert!(before > 4.5, "the fill raised the ground: {before}"); + let field = w.voxel.as_deref().unwrap(); + let key = ChunkKey::of_site(field.world_site(vec3f(0.0, 4.0, 0.0))); + let history_before = field.chunk_history(key).unwrap().to_vec(); + let hash_before = field.field_hash(); + + // The plan presses a pad plane at y = 4.2 over the mound. + w.voxel + .as_deref_mut() + .unwrap() + .plan_press(7, vec3f(-4.0, 0.0, -4.0), vec3f(4.0, 20.0, 4.0), 4.2); + let pressed = w.surface_height_at(0.0, 0.0).expect("still owned"); + assert!( + pressed <= 4.2 + 0.6 && pressed < before, + "the press clips the mound to its plane: {pressed} (was {before})" + ); + let field = w.voxel.as_deref().unwrap(); + assert_eq!( + field.chunk_history(key).unwrap(), + history_before.as_slice(), + "history bytes are untouched by a plan press" + ); + assert_ne!(field.field_hash(), hash_before, "the composed field did change"); + + // Retracting the owner gives the mound back, byte-exact. + w.voxel.as_deref_mut().unwrap().retract_plan(7); + let after = w.surface_height_at(0.0, 0.0).unwrap(); + assert!((after - before).abs() < 1e-4, "retraction restores the surface: {after} vs {before}"); + assert_eq!(w.voxel.as_deref().unwrap().field_hash(), hash_before, "retraction is exact"); +} + +#[test] +fn a_human_fill_under_a_plan_press_survives_the_press() { + let mut w = world(); + // Plan first (a railway bed), then the player fills under it. + field(&mut w).plan_press(3, vec3f(-6.0, 0.0, -6.0), vec3f(6.0, 20.0, 6.0), 3.0); + fill_mound(&mut w); + // While pressed, the surface is the pad plane. + let pressed = w.surface_height_at(0.0, 0.0).unwrap(); + assert!(pressed <= 3.6, "pressed under the railway: {pressed}"); + // The railway is removed: the fill the player made is still there. + w.voxel.as_deref_mut().unwrap().retract_plan(3); + let free = w.surface_height_at(0.0, 0.0).unwrap(); + assert!(free > 4.5, "the human fill survived the plan press: {free}"); +} + +#[test] +fn reset_content_clears_the_plan_but_keeps_history() { + let mut w = world(); + fill_mound(&mut w); + let mound = w.surface_height_at(0.0, 0.0).unwrap(); + w.voxel + .as_deref_mut() + .unwrap() + .plan_press(1, vec3f(-4.0, 0.0, -4.0), vec3f(4.0, 20.0, 4.0), 4.0); + assert!(w.surface_height_at(0.0, 0.0).unwrap() < mound); + w.reset_content(); + w.terrain = Some(flat_terrain(4.0)); + assert!(w.voxel.as_deref().unwrap().plan.is_empty(), "the plan layer is script content"); + let back = w.surface_height_at(0.0, 0.0).unwrap(); + assert!((back - mound).abs() < 1e-4, "history survives reset_content: {back} vs {mound}"); +} + +#[test] +fn the_wire_press_op_lands_in_the_plan_not_the_chunks() { + let mut w = world(); + fill_mound(&mut w); + let key = ChunkKey::of_site(w.voxel.as_deref().unwrap().world_site(vec3f(0.0, 4.0, 0.0))); + let history = w.voxel.as_deref().unwrap().chunk_history(key).unwrap().to_vec(); + w.apply_voxel_op(VoxelOp::Press { + min: vec3f(-4.0, 0.0, -4.0), + max: vec3f(4.0, 20.0, 4.0), + y: 4.1, + }); + let field = w.voxel.as_deref().unwrap(); + assert_eq!(field.plan.presses.len(), 1, "a Press op is a plan press"); + assert_eq!(field.chunk_history(key).unwrap(), history.as_slice()); + assert!(w.surface_height_at(0.0, 0.0).unwrap() <= 4.7); +} + +#[test] +fn holes_answer_hole_and_the_border_answers_outside() { + let mut w = world(); + // Carve every solid site of the column inside the one chunk band the + // capsule materializes ([0, 16) m): the ground beneath is gone there, + // and the base layer below the band is not the column's business. + // A carve whose box sits exactly on the chunk band [0, 16) — its sphere + // removes every solid site of the column there (ground is at 4). + w.apply_voxel_op(VoxelOp::Dig { + pos: vec3f(0.0, 2.0, 0.0), + r: 2.0, + mode: DigMode::Carve, + material: 0, + }); + match w.surface_sample_at(0.0, 0.0) { + SurfaceSample::Hole => {} + other => panic!("a column carved through is a Hole, not {other:?}"), + } + assert_eq!(w.surface_height_at(0.0, 0.0), None, "no fake heightfield ground over a hole"); + assert_eq!(w.surface_sample_at(500.0, 500.0), SurfaceSample::Outside); + assert_eq!(w.surface_sample_at(-32.0, -32.0).height(), Some(4.0), "the near edge is inside"); + assert!(w.surface_sample_at(10.0, 10.0).is_ground()); + // A punched heightfield cell is a hole even with no voxel chunk there. + let t = w.terrain.as_ref().unwrap(); + let side = t.cells - 1; + let mut m = TerrainMaterials::default(); + m.indices = vec![0u8; side * side]; + let ix = ((20.0 - t.origin) / t.cell_size).floor() as usize; + let iz = ((20.0 - t.origin) / t.cell_size).floor() as usize; + m.indices[iz * side + ix] = 0xFF; + w.terrain_materials = Some(m); + assert_eq!(w.surface_sample_at(20.5, 20.5), SurfaceSample::Hole); + assert!(w.surface_sample_at(24.5, 24.5).is_ground()); +} + +#[test] +fn plan_landforms_are_not_history() { + let mut w = world(); + w.in_plan_eval = true; + landform::host_apply_landform( + &mut w, + VoxelOp::Landform { + pos: vec3f(10.0, 4.0, 10.0), + kind: LandKind::Hill.to_u8(), + r: 12.0, + height: 6.0, + seed: 3, + }, + ); + w.in_plan_eval = false; + assert!(w.surface_height_at(10.0, 10.0).unwrap() > 6.0, "the plan hill rose"); + let recorded = w.voxel.as_deref().map_or(0, |f| f.land_ops.len() + f.persist_ops.len()); + assert_eq!(recorded, 0, "a plan landform is never recorded or persisted as history"); + // A landform issued outside eval IS history. + landform::host_apply_landform( + &mut w, + VoxelOp::Landform { + pos: vec3f(-10.0, 4.0, -10.0), + kind: LandKind::Hill.to_u8(), + r: 8.0, + height: 3.0, + seed: 4, + }, + ); + let field = w.voxel.as_deref().unwrap(); + assert_eq!(field.land_ops.len(), 1, "a brush landform is history"); +} + +#[test] +fn the_same_plan_and_history_compose_identically() { + let build = || { + let mut w = world(); + fill_mound(&mut w); + w.apply_voxel_op(VoxelOp::Dig { + pos: vec3f(6.0, 4.0, 2.0), + r: 2.0, + mode: DigMode::Carve, + material: 0, + }); + w.voxel + .as_deref_mut() + .unwrap() + .plan_press(9, vec3f(-3.0, 0.0, -3.0), vec3f(5.0, 20.0, 5.0), 4.3); + w.voxel.as_deref().unwrap().field_hash() + }; + assert_eq!(build(), build()); +} From 31e5faaff5ce77f94ec9e32ec772fe5b988a69af Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 02:51:44 +0200 Subject: [PATCH 046/417] ai-hub: local model runner, licence acknowledgements, a shared install panel; Beat This!, Basic Pitch and the Salamander drum-kit entries LocalModels runs registry models in-process (install state, resumable downloads, recorded licence acknowledgements at $MAKEPAD_HOME/license_acks.json, weight paths by file role) and libs/ai/hub_ui is the install panel + licence modal every app can embed. New native ports: Beat This! (beats + downbeats) and Basic Pitch (note transcription) with their registry entries; the Salamander Drumkit samples (CC BY-SA 3.0, 37 files pinned by size and sha256) as a sample bank the downloader fetches like a model. Co-Authored-By: Claude Fable 5.1 --- Cargo.toml | 8 + libs/ai/Cargo.toml | 2 + libs/ai/hub/Cargo.toml | 12 + libs/ai/hub/registry.json | 335 ++++++++++ libs/ai/hub/src/backend.rs | 32 +- libs/ai/hub/src/beats_backend.rs | 332 +++++++++ libs/ai/hub/src/error.rs | 10 + libs/ai/hub/src/hub.rs | 8 + libs/ai/hub/src/lib.rs | 8 + libs/ai/hub/src/license.rs | 201 ++++++ libs/ai/hub/src/local.rs | 701 ++++++++++++++++++++ libs/ai/hub/src/notes_backend.rs | 192 ++++++ libs/ai/hub/src/registry.rs | 51 +- libs/ai/hub_ui/Cargo.toml | 10 + libs/ai/hub_ui/src/lib.rs | 672 +++++++++++++++++++ libs/ai/loader/src/formats/mod.rs | 1 + libs/ai/loader/src/formats/onnx.rs | 444 +++++++++++++ libs/ai/models/beats/Cargo.toml | 10 + libs/ai/models/beats/src/config.rs | 59 ++ libs/ai/models/beats/src/graph.rs | 537 +++++++++++++++ libs/ai/models/beats/src/lib.rs | 27 + libs/ai/models/beats/src/mel.rs | 235 +++++++ libs/ai/models/beats/src/model.rs | 412 ++++++++++++ libs/ai/models/beats/src/weights.rs | 660 ++++++++++++++++++ libs/ai/models/notes/Cargo.toml | 11 + libs/ai/models/notes/src/config.rs | 54 ++ libs/ai/models/notes/src/cqt.rs | 235 +++++++ libs/ai/models/notes/src/graph.rs | 469 +++++++++++++ libs/ai/models/notes/src/lib.rs | 24 + libs/ai/models/notes/src/model.rs | 580 ++++++++++++++++ libs/ai/models/notes/src/weights.rs | 255 +++++++ libs/ai/models/notes/tests/transcription.rs | 121 ++++ 32 files changed, 6704 insertions(+), 4 deletions(-) create mode 100644 libs/ai/hub/src/beats_backend.rs create mode 100644 libs/ai/hub/src/license.rs create mode 100644 libs/ai/hub/src/local.rs create mode 100644 libs/ai/hub/src/notes_backend.rs create mode 100644 libs/ai/hub_ui/Cargo.toml create mode 100644 libs/ai/hub_ui/src/lib.rs create mode 100644 libs/ai/loader/src/formats/onnx.rs create mode 100644 libs/ai/models/beats/Cargo.toml create mode 100644 libs/ai/models/beats/src/config.rs create mode 100644 libs/ai/models/beats/src/graph.rs create mode 100644 libs/ai/models/beats/src/lib.rs create mode 100644 libs/ai/models/beats/src/mel.rs create mode 100644 libs/ai/models/beats/src/model.rs create mode 100644 libs/ai/models/beats/src/weights.rs create mode 100644 libs/ai/models/notes/Cargo.toml create mode 100644 libs/ai/models/notes/src/config.rs create mode 100644 libs/ai/models/notes/src/cqt.rs create mode 100644 libs/ai/models/notes/src/graph.rs create mode 100644 libs/ai/models/notes/src/lib.rs create mode 100644 libs/ai/models/notes/src/model.rs create mode 100644 libs/ai/models/notes/src/weights.rs create mode 100644 libs/ai/models/notes/tests/transcription.rs diff --git a/Cargo.toml b/Cargo.toml index 43ddada9d..789ec7a79 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ workspace.members = [ "libs/asset/store", "libs/asset/chat", "libs/chat_ui", + "libs/ai/hub_ui", "libs/asset/annotate", "libs/render", "libs/raytrace", @@ -82,6 +83,9 @@ workspace.members = [ "examples/render_to_texture", # === digital-fabrication product === "apps/fab", + "apps/fabric", + "libs/fabric/measure", + "libs/fabric/draft", # === xr app === "xr", # === studio === @@ -94,6 +98,8 @@ workspace.members = [ "libs/score_layout", "libs/score_play", "libs/score_render", + "libs/score_view", + "libs/score_view/tests/embed_app", "libs/score_ai", "libs/score_import", "libs/score_pdf", @@ -102,6 +108,8 @@ workspace.members = [ "libs/midi_file", "libs/soundfont", "libs/piano_model", + "libs/drumkit", + "libs/drumkit_phys", "libs/musicxml", # === own MP3 / Ogg Vorbis decoders === "libs/audio_decode", diff --git a/libs/ai/Cargo.toml b/libs/ai/Cargo.toml index 32dd9fe8f..8f47fcfc5 100644 --- a/libs/ai/Cargo.toml +++ b/libs/ai/Cargo.toml @@ -24,6 +24,8 @@ members = [ "models/speech", "models/splat", "models/stems", + "models/beats", + "models/notes", "models/trellis", ] resolver = "2" diff --git a/libs/ai/hub/Cargo.toml b/libs/ai/hub/Cargo.toml index 22b82eef3..b2c0cae4b 100644 --- a/libs/ai/hub/Cargo.toml +++ b/libs/ai/hub/Cargo.toml @@ -34,6 +34,8 @@ default = [ "motion-native", "rig-native", "splat-native", + "beats-native", + "notes-native", ] # Box-provisioned Python/Torch reference backends (FlashWorld, Music3, # Depth-Anything-3, and the rig/motion oracles). Not in default: a native @@ -95,6 +97,14 @@ splat-native = ["matte-native", "dep:makepad-ai-splat", "dep:makepad-ai-common"] # lossless skinned-GLB augmentation. The reference Torch/bpy backend remains # separately available as `rig-oracle` through `python-backends`. rig-native = ["dep:makepad-ai-rig", "dep:makepad-ai-common", "dep:makepad-gltf"] +# In-process registry/downloader/backend runner for desktop applications. +# Opt-in so featureless fleet clients do not pull the GPU model substrate. +local = ["dep:makepad-ai-common"] +# Native Beat This! audio -> beat/downbeat JSON analysis. +beats-native = ["dep:makepad-ai-beats", "dep:makepad-ai-common"] +# Native Spotify Basic Pitch audio -> notes/MIDI transcription. The model is +# tiny and has a CPU fallback, so this lane is available without a GPU. +notes-native = ["dep:makepad-ai-notes"] [dependencies] makepad-micro-serde = { path = "../../micro_serde" } @@ -131,6 +141,8 @@ makepad-xatlas = { path = "../../xatlas", optional = true } makepad-render = { path = "../../render", optional = true } makepad-ai-llm = { path = "../../ai/llm", optional = true } makepad-ai-speech = { path = "../../ai/models/speech", default-features = false, optional = true } +makepad-ai-beats = { path = "../../ai/models/beats", optional = true } +makepad-ai-notes = { path = "../../ai/models/notes", optional = true } makepad-system-speech = { path = "../../system_speech", optional = true } makepad-video = { path = "../../../platform/video", optional = true } # The `mkfl` motion payload: ONE definition, shared with the VJ's import diff --git a/libs/ai/hub/registry.json b/libs/ai/hub/registry.json index 457c3e649..3aab2ce89 100644 --- a/libs/ai/hub/registry.json +++ b/libs/ai/hub/registry.json @@ -1,5 +1,340 @@ { "models": [ + { + "id": "beat-this", + "domain": "beats", + "backend": "beats", + "available": true, + "gated": false, + "license": { + "name": "MIT License", + "url": "https://github.com/CPJKU/beat_this", + "summary": "Beat This! beat and downbeat tracker (Foscarin, Schl\u00fcter, Widmer 2024), code and released weights MIT; training data partly copyrighted \u2014 weights are unrestricted.", + "restriction": "none" + }, + "vram_gb": 0.5, + "note": "Contract: input_b64 is a WAV, MP3, FLAC or Ogg Vorbis file at any sample rate/channel count; the backend downmixes and resamples to 22050 Hz. Output is one application/json artifact: {bpm, confidence, beats:[seconds], downbeats:[seconds], frame_rate:50}.", + "files": [ + { + "role": "weights", + "repo": "CPJKU/beat_this", + "path": "https://cloud.cp.jku.at/public.php/dav/files/7ik4RrBKTS273gp/final0.ckpt", + "cache_as": "beats/beat_this_final0.ckpt", + "size": 81058141, + "sha256": "8c328b45f59d8dd3dff219253ff6a8d6482be57d0133a29140e2febbf8eb8331" + }, + { + "role": "weights-small", + "repo": "CPJKU/beat_this", + "path": "https://cloud.cp.jku.at/public.php/dav/files/7ik4RrBKTS273gp/small0.ckpt", + "cache_as": "beats/beat_this_small0.ckpt", + "size": 8451101, + "sha256": "6074be2c4d490c5f6101fcc374a1ec72ae93456e23bb6019783b849f5dc7d47b", + "optional": true + } + ] + }, + { + "id": "basic-pitch", + "domain": "notes", + "backend": "notes", + "available": true, + "gated": false, + "license": { + "name": "Apache License 2.0", + "url": "https://github.com/spotify/basic-pitch", + "summary": "Spotify Basic Pitch instrument-agnostic polyphonic note transcription model (ICASSP 2022), Apache-2.0 code and weights; permissive incl. commercial.", + "restriction": "none" + }, + "vram_gb": 0.1, + "note": "Request: domain notes with input_b64 containing a PCM WAV (16/24/32-bit integer or f32, any sample rate/channels). Response artifacts: application/json {frame_rate,notes:[{start_secs,end_secs,midi,amplitude,bends:[semitones_per_frame]}]} and audio/midi .mid bytes with per-note pitch bends in the standard +/-2-semitone range.", + "files": [ + { + "role": "model", + "repo": "spotify/basic-pitch", + "path": "https://github.com/spotify/basic-pitch/raw/main/basic_pitch/saved_models/icassp_2022/nmp.onnx", + "cache_as": "notes/basic_pitch_nmp.onnx", + "size": 230444, + "sha256": "2c3c1d144bfa61ad236e92e169c13535c880469a12a047d4e73451f2c059a0ec" + } + ] + }, + { + "id": "salamander-drumkit", + "domain": "audio", + "backend": "sample-kit", + "available": true, + "gated": false, + "license": { + "name": "CC BY-SA 3.0", + "url": "https://creativecommons.org/licenses/by-sa/3.0/", + "summary": "Salamander Drumkit by Alexander Holm. Free use with attribution; adaptations must be shared under the same licence.", + "restriction": "community" + }, + "vram_gb": 0.0, + "note": "37 overhead samples from the Salamander Drumkit (48 kHz, 24-bit stereo). This is a sample bank for makepad-drumkit, not a runnable AI model.", + "files": [ + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/kick_OH_P_1.wav", + "cache_as": "drums/salamander/OH/kick_OH_P_1.wav", + "size": 12832244, + "sha256": "bab7bc6aaec2c0d6db39c8e33214c4bf6870f51b557238eb1a5ce88052c92f06" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/kick_OH_P_2.wav", + "cache_as": "drums/salamander/OH/kick_OH_P_2.wav", + "size": 137012, + "sha256": "3520f1518c7d05a7ad507aee1d50aa6e299572c6daba9c9d50731bfd9e33beb3" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/kick_OH_F_1.wav", + "cache_as": "drums/salamander/OH/kick_OH_F_1.wav", + "size": 135920, + "sha256": "fc1a6388402144f1888a3febce1207799795fbbc3d87f41ce84be31f4adc70ae" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/kick_OH_F_2.wav", + "cache_as": "drums/salamander/OH/kick_OH_F_2.wav", + "size": 136316, + "sha256": "30bfcd1f944c3a427e443db037a813278f404628bde6349cba96cd1501365fc2" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/kick_OH_FF_1.wav", + "cache_as": "drums/salamander/OH/kick_OH_FF_1.wav", + "size": 136022, + "sha256": "f3c3272a7d0623b6d9b7cb028b08b5b3812c650fd22f4739e43e77e9faf69b28" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/kick_OH_FF_2.wav", + "cache_as": "drums/salamander/OH/kick_OH_FF_2.wav", + "size": 135296, + "sha256": "d7a5c50cdd03cf985b330397030dada2a4ce4350b6a6db43fa1b8a3db48c9a75" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/snare_OH_Ghost_1.wav", + "cache_as": "drums/salamander/OH/snare_OH_Ghost_1.wav", + "size": 133448, + "sha256": "b856339d674b8c92200cdb2aaace161c6b54001e029df7f1f7328c182fc59f0a" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/snare_OH_Ghost_2.wav", + "cache_as": "drums/salamander/OH/snare_OH_Ghost_2.wav", + "size": 132026, + "sha256": "abe51b8167caff1f9d2e9fafff7dcaf632647359e65293ef8bfdd0604423cb10" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/snare_OH_Ghost_3.wav", + "cache_as": "drums/salamander/OH/snare_OH_Ghost_3.wav", + "size": 132980, + "sha256": "1829e6a8ab0e76a301f032f7b0b1a32307247d2aec77741bc25f69bf5997971c" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/snare_OH_MP_1.wav", + "cache_as": "drums/salamander/OH/snare_OH_MP_1.wav", + "size": 440678, + "sha256": "9f671962ba0eccd713d85f5b297bfb5e2cde2e7f4ff7735e535480b524aa185f" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/snare_OH_MP_2.wav", + "cache_as": "drums/salamander/OH/snare_OH_MP_2.wav", + "size": 439310, + "sha256": "cbfec703cc8d3bec8b12127aa4d9daf626af2d50842995fd98fc27716eac17f9" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/snare_OH_MP_3.wav", + "cache_as": "drums/salamander/OH/snare_OH_MP_3.wav", + "size": 439832, + "sha256": "4aea5fd07444a45f30a3a79304e58aa2f0e31d267a694dd7fbf813730c704aab" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/snare_OH_F_1.wav", + "cache_as": "drums/salamander/OH/snare_OH_F_1.wav", + "size": 479102, + "sha256": "502b42305ae9c82c34060b1664d5ab5bf9d23dc7afacedbafaf92bb7047b7457" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/snare_OH_F_2.wav", + "cache_as": "drums/salamander/OH/snare_OH_F_2.wav", + "size": 476714, + "sha256": "4daaefe7f43a7e8a2d9a45f9bb1ef35502122ec95191cf9dbf6a55776f401ff3" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/snare_OH_F_3.wav", + "cache_as": "drums/salamander/OH/snare_OH_F_3.wav", + "size": 492866, + "sha256": "79450ca54856fc8351bb0b5c6f3cef7d10e6c7aa9f9b92480de3fec1254e0d73" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/snare_OH_FF_1.wav", + "cache_as": "drums/salamander/OH/snare_OH_FF_1.wav", + "size": 526562, + "sha256": "4f30503ba0b27e702c75f027cfecdb49ec526ae31ea510f7bea71f98eaf9dc39" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/snare_OH_FF_2.wav", + "cache_as": "drums/salamander/OH/snare_OH_FF_2.wav", + "size": 514484, + "sha256": "4a4e1a3cd56d87e013cd93379e71e4ef9e8c8b781cbb0cd177f5f068b168bf29" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/snare_OH_FF_3.wav", + "cache_as": "drums/salamander/OH/snare_OH_FF_3.wav", + "size": 527324, + "sha256": "5cc0315e222b2a2e8ffc538f03fd76bf9de34acd8d42111ca08460f9d099fee5" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/snareStick_OH_F_1.wav", + "cache_as": "drums/salamander/OH/snareStick_OH_F_1.wav", + "size": 200330, + "sha256": "cf1eb153fd033d822325071e7496f54a1f7610ae1702c2d700135ac98eaf5354" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/hihatClosed_OH_P_1.wav", + "cache_as": "drums/salamander/OH/hihatClosed_OH_P_1.wav", + "size": 150878, + "sha256": "75e3a8ee84db75d0e9cec922d8bb44b977f5a73648145fbcd59a76e706636040" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/hihatClosed_OH_F_1.wav", + "cache_as": "drums/salamander/OH/hihatClosed_OH_F_1.wav", + "size": 162758, + "sha256": "bd485de70450f68bb4692557a4ae909caaa965f5739693317365ebe85c986cbb" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/hihatOpen_OH_P_1.wav", + "cache_as": "drums/salamander/OH/hihatOpen_OH_P_1.wav", + "size": 2397722, + "sha256": "3aeb5939739ac0d94a0ab5e0d237d96c46545f0c98778a5b2b18001be1090391" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/hihatOpen_OH_F_1.wav", + "cache_as": "drums/salamander/OH/hihatOpen_OH_F_1.wav", + "size": 2554610, + "sha256": "7493fce31fb00093e4944f878a7fe802177a5c311e82725ac0ce7956e86f2fdc" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/hihatOpen_OH_FF_1.wav", + "cache_as": "drums/salamander/OH/hihatOpen_OH_FF_1.wav", + "size": 2897654, + "sha256": "ef88d66d0289de4befe583de11298d75bae788de9ea63f156b493689668a7d54" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/hihatFoot_OH_MP_1.wav", + "cache_as": "drums/salamander/OH/hihatFoot_OH_MP_1.wav", + "size": 382556, + "sha256": "2ad5e1bc38e5b9984d923b278b8ec5488540366082f4de9401d4702b9ba95e4c" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/hiTom_OH_P_1.wav", + "cache_as": "drums/salamander/OH/hiTom_OH_P_1.wav", + "size": 599078, + "sha256": "fe826370a1ef7562a3c11701281a536f2b722f10390bf0322f95655919581568" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/hiTom_OH_F_1.wav", + "cache_as": "drums/salamander/OH/hiTom_OH_F_1.wav", + "size": 789824, + "sha256": "b6802ce4ff40974f91ab9e30dea885a51db324376db3a56bbcaaaa6eaf69a043" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/hiTom_OH_FF_1.wav", + "cache_as": "drums/salamander/OH/hiTom_OH_FF_1.wav", + "size": 871400, + "sha256": "25d6092617cc798ba488b2d4843f1ea789324a795007ba405884c981f63f079e" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/loTom_OH_PP_1.wav", + "cache_as": "drums/salamander/OH/loTom_OH_PP_1.wav", + "size": 583160, + "sha256": "8afb4c8bbb7a46472f387db6cb0d6597f3ad14f73a6e23bbf58ed945accef0e1" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/loTom_OH_MP_1.wav", + "cache_as": "drums/salamander/OH/loTom_OH_MP_1.wav", + "size": 609278, + "sha256": "4c1fdf7233a170eb625efa5e5681d1811fb53fb7f34a85a05c8bc936d5ac60b2" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/loTom_OH_FF_1.wav", + "cache_as": "drums/salamander/OH/loTom_OH_FF_1.wav", + "size": 680900, + "sha256": "bfb74d255554c2965bf012452bc3717dee88a44aa04d120f2a1b86b9b6a7082d" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/crash1_OH_P_1.wav", + "cache_as": "drums/salamander/OH/crash1_OH_P_1.wav", + "size": 2558096, + "sha256": "82b0ff9452b35ee6cf56445420af28b554d5ccc3659dff48167c21f1a357d795" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/crash1_OH_FF_1.wav", + "cache_as": "drums/salamander/OH/crash1_OH_FF_1.wav", + "size": 3312620, + "sha256": "da28a2e9446c0e0a124f37ccf727db796f0d8575f63fbc923d16ad0143f1310c" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/crash2_OH_FF_1.wav", + "cache_as": "drums/salamander/OH/crash2_OH_FF_1.wav", + "size": 3088784, + "sha256": "a361cfd992cb33026b1174c82b97b7cf04c10f23af7c9c5c1d1f588dfabc2ff1" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/ride1_OH_MP_1.wav", + "cache_as": "drums/salamander/OH/ride1_OH_MP_1.wav", + "size": 1946042, + "sha256": "9e9135d595edf9f41ee3bd5caa9c797233422f62a3fb2c63ea542c58fb5ba155" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/ride1_OH_FF_1.wav", + "cache_as": "drums/salamander/OH/ride1_OH_FF_1.wav", + "size": 3094256, + "sha256": "5dbdf8cdecd62b83acfde4e268be6a52da0ca64ae145536004ffce3b1b7d6608" + }, + { + "repo": "endolith/Salamander-Drumkit", + "path": "https://raw.githubusercontent.com/endolith/Salamander-Drumkit/master/OH/ride1Bell_OH_F_1.wav", + "cache_as": "drums/salamander/OH/ride1Bell_OH_F_1.wav", + "size": 2123384, + "sha256": "736bb2a58147359054df4b7c857b74c2d7b848efb9335b9e354661f025363e78" + } + ] + }, { "id": "hunyuan3d-paint-2.1", "domain": "paint", diff --git a/libs/ai/hub/src/backend.rs b/libs/ai/hub/src/backend.rs index ec7cd5ef1..8f5a9672a 100644 --- a/libs/ai/hub/src/backend.rs +++ b/libs/ai/hub/src/backend.rs @@ -1219,6 +1219,7 @@ pub fn validate_loras_for_backend( /// One generated output. `content_type` drives the `/artifact` response; /// `ext` names the file on disk. +#[derive(Clone, Debug)] pub struct ArtifactData { pub content_type: &'static str, pub ext: &'static str, @@ -1568,6 +1569,7 @@ pub fn backend_compiled(name: &str) -> bool { // so it is compiled in exactly when the LLM is. "vision" => cfg!(feature = "llm"), "ocr" => cfg!(feature = "llm"), + "notes" => cfg!(feature = "notes-native"), "kokoro" => cfg!(feature = "tts"), "whisper" => cfg!(feature = "stt"), "indextts" => cfg!(feature = "indextts"), @@ -1577,6 +1579,7 @@ pub fn backend_compiled(name: &str) -> bool { "moss" => cfg!(feature = "audio"), "woosh" => cfg!(feature = "audio"), "ace" => cfg!(feature = "audio"), + "beats" => cfg!(feature = "beats-native"), "trellis" => cfg!(feature = "mesh"), "paint" | "paint-test" => cfg!(feature = "paint"), "matte-native" => cfg!(feature = "matte-native"), @@ -1766,6 +1769,16 @@ pub fn model_availability( pub fn create_backend(spec: &ModelSpec) -> Result, AssetAiError> { match spec.backend.as_str() { + "sample-kit" => Err(AssetAiError::Unavailable( + "sample-kit is a sample bank, not a model".to_string(), + )), + #[cfg(feature = "notes-native")] + "notes" => Ok(Box::new(crate::notes_backend::NotesBackend::new(&spec.id))), + #[cfg(not(feature = "notes-native"))] + "notes" => Err(AssetAiError::Unavailable(format!( + "model {} needs a build with the 'notes-native' cargo feature", + spec.id + ))), #[cfg(feature = "paint")] "paint" | "paint-test" => Ok(Box::new(crate::paint_backend::PaintBackend::new(spec))), "testpattern" => Ok(Box::new(crate::testpattern::TestPatternBackend::new( @@ -1880,6 +1893,13 @@ pub fn create_backend(spec: &ModelSpec) -> Result, Asset ))), #[cfg(feature = "audio")] "ace" => Ok(Box::new(crate::ace_backend::AceBackend::new_ace(&spec.id))), + #[cfg(feature = "beats-native")] + "beats" => Ok(Box::new(crate::beats_backend::BeatsBackend::new(&spec.id))), + #[cfg(not(feature = "beats-native"))] + "beats" => Err(AssetAiError::Unavailable(format!( + "model {} needs a build with the 'beats-native' cargo feature", + spec.id + ))), #[cfg(not(feature = "audio"))] "moss" => Err(AssetAiError::Unavailable(format!( "model {} needs a build with the 'audio' cargo feature", @@ -2024,7 +2044,6 @@ mod tests { use super::{backend_compiled, create_backend, model_availability}; #[cfg(not(feature = "python-backends"))] use super::backend_provisioned; - #[cfg(not(feature = "python-backends"))] use crate::error::AssetAiError; use crate::gpu::GpuInfo; use crate::registry::{Domain, ModelSpec}; @@ -2054,6 +2073,17 @@ mod tests { } } + #[test] + fn sample_kit_is_downloadable_but_not_runnable() { + match create_backend(&spec("sample-kit", true, Some(0.0))) { + Err(AssetAiError::Unavailable(message)) => { + assert_eq!(message, "sample-kit is a sample bank, not a model") + } + Err(error) => panic!("wrong sample-kit error: {error}"), + Ok(_) => panic!("sample-kit unexpectedly created a runnable backend"), + } + } + #[cfg(feature = "indextts")] #[test] fn indextts_is_advertised_when_its_backend_is_compiled() { diff --git a/libs/ai/hub/src/beats_backend.rs b/libs/ai/hub/src/beats_backend.rs new file mode 100644 index 000000000..b467b3cd2 --- /dev/null +++ b/libs/ai/hub/src/beats_backend.rs @@ -0,0 +1,332 @@ +//! Native Beat This! backend: audio bytes in, beat/downbeat JSON out. + +use crate::backend::{ + ArtifactData, BackendCtx, CancelToken, ContentBackend, GenerateParams, ProgressSink, +}; +use crate::error::AssetAiError; +use makepad_ai_beats::{BeatAnalysis, BeatsModel, SAMPLE_RATE}; +use makepad_ai_common::DiffusionError; +use makepad_audio_decode::{decode_audio_limited, sniff as sniff_audio, Limits}; +use std::fmt::Write; +use std::path::PathBuf; +use std::sync::mpsc; +use std::thread; + +const MAX_DECODE_FRAMES: usize = 192_000 * 60 * 120; + +pub struct BeatsBackend { + model_id: String, + model_path: Option, + worker: Option, +} + +impl BeatsBackend { + pub fn new(model_id: &str) -> Self { + Self { + model_id: model_id.to_string(), + model_path: None, + worker: None, + } + } +} + +enum WorkerCommand { + Analyze { + mono: Vec, + cancel: CancelToken, + events: mpsc::Sender, + }, + Shutdown, +} + +enum WorkerEvent { + Progress(usize, usize), + Done(Result), +} + +enum WorkerError { + Cancelled, + Failed(String), +} + +struct BeatsWorker { + commands: mpsc::Sender, + join: Option>, +} + +impl BeatsWorker { + fn spawn(path: PathBuf) -> Result { + let (commands_tx, commands_rx) = mpsc::channel(); + let (ready_tx, ready_rx) = mpsc::sync_channel(1); + let join = thread::Builder::new() + .name("makepad-beats".to_string()) + .spawn(move || { + let mut model = match BeatsModel::load(&path) { + Ok(model) => { + let _ = ready_tx.send(Ok(())); + model + } + Err(error) => { + let _ = ready_tx.send(Err(error.to_string())); + return; + } + }; + while let Ok(command) = commands_rx.recv() { + match command { + WorkerCommand::Analyze { + mono, + cancel, + events, + } => { + let mut hook = |done: usize, total: usize| { + if cancel.is_cancelled() { + return Err(DiffusionError::Cancelled); + } + events.send(WorkerEvent::Progress(done, total)).map_err(|_| { + DiffusionError::model("beats progress receiver disconnected") + })?; + Ok(()) + }; + let result = model.analyze_with_progress(&mono, &mut hook).map_err( + |error| match error { + DiffusionError::Cancelled => WorkerError::Cancelled, + other => WorkerError::Failed(other.to_string()), + }, + ); + let _ = events.send(WorkerEvent::Done(result)); + } + WorkerCommand::Shutdown => break, + } + } + }) + .map_err(|error| AssetAiError::Backend(format!("beats worker spawn: {error}")))?; + match ready_rx.recv() { + Ok(Ok(())) => Ok(Self { + commands: commands_tx, + join: Some(join), + }), + Ok(Err(error)) => { + let _ = join.join(); + Err(AssetAiError::Backend(format!("beats load: {error}"))) + } + Err(_) => { + let _ = join.join(); + Err(AssetAiError::Backend( + "beats worker exited during model load".to_string(), + )) + } + } + } + + fn analyze(&self, mono: Vec, cancel: &CancelToken) -> Result, AssetAiError> { + let (events_tx, events_rx) = mpsc::channel(); + self.commands + .send(WorkerCommand::Analyze { + mono, + cancel: cancel.clone(), + events: events_tx, + }) + .map_err(|_| AssetAiError::Backend("beats worker is not running".to_string()))?; + Ok(events_rx) + } + + fn shutdown(&mut self) -> Result<(), AssetAiError> { + let _ = self.commands.send(WorkerCommand::Shutdown); + if let Some(join) = self.join.take() { + join.join() + .map_err(|_| AssetAiError::Backend("beats worker panicked".to_string()))?; + } + Ok(()) + } +} + +impl Drop for BeatsWorker { + fn drop(&mut self) { + let _ = self.commands.send(WorkerCommand::Shutdown); + if let Some(join) = self.join.take() { + let _ = join.join(); + } + } +} + +impl ContentBackend for BeatsBackend { + fn model_id(&self) -> &str { + &self.model_id + } + + fn ensure_loaded(&mut self, ctx: &mut BackendCtx) -> Result<(), AssetAiError> { + ctx.ensure_files()?; + let path = ctx.path_by_role("weights")?; + if self.worker.is_some() && self.model_path.as_ref() == Some(&path) { + return Ok(()); + } + ctx.cancel.check()?; + (ctx.progress)("load beat-this checkpoint", 0.0); + if let Some(mut worker) = self.worker.take() { + worker.shutdown()?; + } + let worker = BeatsWorker::spawn(path.clone())?; + ctx.cancel.check()?; + self.model_path = Some(path); + self.worker = Some(worker); + (ctx.progress)("load beat-this checkpoint", 1.0); + Ok(()) + } + + fn is_resident(&self) -> bool { + self.worker.is_some() + } + + fn unload(&mut self) -> Result<(), AssetAiError> { + if let Some(mut worker) = self.worker.take() { + worker.shutdown()?; + } + self.model_path = None; + Ok(()) + } + + fn generate( + &mut self, + params: &GenerateParams, + progress: ProgressSink, + cancel: &CancelToken, + ) -> Result, AssetAiError> { + cancel.check()?; + if params.input_bytes.is_empty() { + return Err(AssetAiError::Params( + "beats requires an audio file in input_b64".to_string(), + )); + } + progress("decode audio", 0.01); + let (mono, input_rate) = decode_audio(¶ms.input_bytes, ¶ms.input_content_type)?; + cancel.check()?; + let mono = if input_rate == SAMPLE_RATE { + mono + } else { + progress("resample audio to 22050 Hz", 0.04); + crate::resample::resample_channel(&mono, input_rate, SAMPLE_RATE) + }; + cancel.check()?; + progress("log-mel frontend", 0.07); + let worker = self.worker.as_ref().ok_or_else(|| { + AssetAiError::Backend("beats generate called before ensure_loaded".to_string()) + })?; + let events = worker.analyze(mono, cancel)?; + let analysis = loop { + match events.recv() { + Ok(WorkerEvent::Progress(done, total)) => { + let ratio = if total == 0 { + 1.0 + } else { + done as f64 / total as f64 + }; + progress( + &format!("beat inference {done}/{total}"), + 0.10 + 0.88 * ratio, + ); + } + Ok(WorkerEvent::Done(Ok(analysis))) => break analysis, + Ok(WorkerEvent::Done(Err(WorkerError::Cancelled))) => { + return Err(AssetAiError::Cancelled) + } + Ok(WorkerEvent::Done(Err(WorkerError::Failed(error)))) => { + return Err(AssetAiError::Backend(format!("beats: {error}"))) + } + Err(_) => { + return Err(AssetAiError::Backend( + "beats worker disconnected during inference".to_string(), + )) + } + } + }; + cancel.check()?; + progress("serialize beat analysis", 0.99); + let bytes = analysis_json(&analysis).into_bytes(); + progress("done", 1.0); + Ok(vec![ArtifactData { + content_type: "application/json", + ext: "json", + bytes, + }]) + } +} + +fn decode_audio(bytes: &[u8], declared: &str) -> Result<(Vec, u32), AssetAiError> { + if bytes.len() >= 12 && &bytes[0..4] == b"RIFF" && &bytes[8..12] == b"WAVE" { + return crate::wav::decode_wav_to_mono_f32(bytes) + .map_err(|error| AssetAiError::Params(format!("beats wav: {error}"))); + } + let format = sniff_audio(bytes).ok_or_else(|| { + AssetAiError::Params(format!( + "beats input is not a supported audio file (declared {declared:?}); send WAV, MP3, FLAC or Ogg Vorbis" + )) + })?; + let audio = decode_audio_limited(bytes, format, Limits::with_max_frames(MAX_DECODE_FRAMES)) + .map_err(|error| AssetAiError::Params(format!("beats audio decode: {error}")))?; + if audio.rate == 0 || audio.channels == 0 || audio.frames() == 0 { + return Err(AssetAiError::Params("beats audio is empty".to_string())); + } + let channels = audio.channels as usize; + let mut mono = Vec::with_capacity(audio.frames()); + for frame in audio.pcm_interleaved_f32.chunks_exact(channels) { + mono.push(frame.iter().copied().sum::() / channels as f32); + } + Ok((mono, audio.rate)) +} + +fn analysis_json(analysis: &BeatAnalysis) -> String { + let mut output = String::with_capacity( + 128 + (analysis.beats_secs.len() + analysis.downbeats_secs.len()) * 12, + ); + write!( + output, + "{{\"bpm\":{},\"confidence\":{},\"beats\":[", + analysis.bpm, analysis.confidence + ) + .unwrap(); + write_numbers(&mut output, &analysis.beats_secs); + output.push_str("],\"downbeats\":["); + write_numbers(&mut output, &analysis.downbeats_secs); + write!(output, "],\"frame_rate\":{}}}", analysis.frame_rate).unwrap(); + output +} + +fn write_numbers(output: &mut String, values: &[f64]) { + for (index, value) in values.iter().enumerate() { + if index != 0 { + output.push(','); + } + write!(output, "{value}").unwrap(); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn json_contract_has_only_public_summary_fields() { + let analysis = BeatAnalysis { + beats_secs: vec![0.5, 1.0], + downbeats_secs: vec![0.5], + bpm: 120.0, + confidence: 0.875, + frame_rate: 50.0, + beat_prob: vec![0.1], + downbeat_prob: vec![0.2], + }; + assert_eq!( + analysis_json(&analysis), + "{\"bpm\":120,\"confidence\":0.875,\"beats\":[0.5,1],\"downbeats\":[0.5],\"frame_rate\":50}" + ); + } + + #[test] + fn wav_decode_downmixes_channels() { + let wav = crate::wav::encode_wav_pcm16_stereo(&[0.5, -0.5], &[-0.5, -0.5], 44_100); + let (mono, rate) = decode_audio(&wav, "audio/wav").unwrap(); + assert_eq!(rate, 44_100); + assert!(mono[0].abs() < 1e-3); + assert!((mono[1] + 0.5).abs() < 1e-3); + } +} diff --git a/libs/ai/hub/src/error.rs b/libs/ai/hub/src/error.rs index 7362a3860..827aaf04e 100644 --- a/libs/ai/hub/src/error.rs +++ b/libs/ai/hub/src/error.rs @@ -29,6 +29,12 @@ pub enum AssetAiError { Cancelled, /// Model id not present in the registry. UnknownModel(String), + /// A local pull or run was attempted before the current weight licence + /// identity had been acknowledged. + LicenseNotAcknowledged, + /// A local run was attempted before all of the model's files were + /// installed at their pinned sizes. + NotInstalled(String), /// Model is in the registry but marked unavailable, or no backend is /// compiled in for it (e.g. `flux` without the cargo feature). Unavailable(String), @@ -49,6 +55,10 @@ impl fmt::Display for AssetAiError { } AssetAiError::Cancelled => write!(f, "cancelled"), AssetAiError::UnknownModel(m) => write!(f, "unknown model: {m}"), + AssetAiError::LicenseNotAcknowledged => { + write!(f, "model licence has not been acknowledged") + } + AssetAiError::NotInstalled(m) => write!(f, "model not installed: {m}"), AssetAiError::Unavailable(m) => write!(f, "model unavailable: {m}"), } } diff --git a/libs/ai/hub/src/hub.rs b/libs/ai/hub/src/hub.rs index 3e9947620..3958b652e 100644 --- a/libs/ai/hub/src/hub.rs +++ b/libs/ai/hub/src/hub.rs @@ -45,6 +45,14 @@ impl AiHub { Self { _private: () } } + /// Open the shared local registry/downloader/backend manager. Like the + /// hub itself this binds no listener; workers start only for installs or + /// runs. + #[cfg(feature = "local")] + pub fn local_models(&self) -> Result { + crate::local::LocalModels::open() + } + /// Start a chat on this machine. The session's worker runs the machine /// residency election first (aicore §3): route to a serving co-located /// holder, wait on a loading one, else claim and load in-process. diff --git a/libs/ai/hub/src/lib.rs b/libs/ai/hub/src/lib.rs index 3da743a22..49415eee8 100644 --- a/libs/ai/hub/src/lib.rs +++ b/libs/ai/hub/src/lib.rs @@ -32,6 +32,8 @@ //! see `protocol.rs`'s wire doc block and `crate::realtime`. pub mod backend; +#[cfg(feature = "beats-native")] +pub mod beats_backend; pub mod body_native_backend; pub mod chat_wire; pub use makepad_base64; @@ -55,6 +57,8 @@ pub mod http_client; pub mod jobs; pub mod lane_advert; pub mod lease; +#[cfg(feature = "local")] +pub mod license; pub mod indextts_backend; pub mod kokoro_backend; #[cfg(feature = "stt")] @@ -64,6 +68,8 @@ pub mod speech; pub mod llm_backend; #[cfg(feature = "llm")] pub mod local_llm; +#[cfg(feature = "local")] +pub mod local; pub mod matte_backend; pub mod segment_backend; pub mod upscale_backend; @@ -105,6 +111,8 @@ pub mod trellis_backend; pub mod wav; pub mod woosh_backend; pub mod music3_backend; +#[cfg(feature = "notes-native")] +pub mod notes_backend; pub mod world_backend; #[cfg(feature = "flux")] diff --git a/libs/ai/hub/src/license.rs b/libs/ai/hub/src/license.rs new file mode 100644 index 000000000..2a0cecbc1 --- /dev/null +++ b/libs/ai/hub/src/license.rs @@ -0,0 +1,201 @@ +//! Durable acknowledgement of model-weight licence identities. +//! +//! Acknowledgements are deliberately separate from the weight cache: clearing +//! downloads must not erase the record of what text the operator accepted, +//! and changing that text's identity must make the model prompt again. + +use crate::error::AssetAiError; +use crate::home::makepad_home; +use crate::registry::{LicenseRestriction, ModelSpec}; +use makepad_micro_serde::*; +use std::fs; +use std::path::{Path, PathBuf}; +use std::time::{SystemTime, UNIX_EPOCH}; + +pub const LICENSE_ACKS_FILE: &str = "license_acks.json"; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct LicensePrompt { + pub model_id: String, + pub name: String, + pub url: String, + pub summary: String, + pub restriction: LicenseRestriction, + pub identity: String, +} + +impl LicensePrompt { + pub fn from_spec(spec: &ModelSpec) -> Self { + match &spec.license { + Some(license) => Self { + model_id: spec.id.clone(), + name: license.name.clone(), + url: license.url.clone(), + summary: license.summary.clone(), + restriction: license.restriction, + identity: license.identity(), + }, + None => Self { + model_id: spec.id.clone(), + name: "Unknown weight licence".to_string(), + url: "https://huggingface.co/".to_string(), + summary: format!( + "{} has no licence record in the registry. It cannot be cleared for download or generation until a licence record is added.", + spec.id + ), + restriction: LicenseRestriction::Restricted, + identity: "missing".to_string(), + }, + } + } +} + +#[derive(Clone, Debug, SerJson, DeJson, PartialEq, Eq)] +pub struct LicenseAcknowledgement { + pub model_id: String, + pub identity: String, + pub acknowledged_at: u64, +} + +#[derive(Clone, Debug, Default, SerJson, DeJson)] +struct LicenseFile { + version: u32, + acknowledgements: Vec, +} + +pub struct LicenseStore { + path: PathBuf, + records: Vec, +} + +impl LicenseStore { + pub fn open() -> Result { + Self::open_at(makepad_home().join(LICENSE_ACKS_FILE)) + } + + pub(crate) fn open_at(path: PathBuf) -> Result { + let records = match fs::read_to_string(&path) { + Ok(text) => LicenseFile::deserialize_json(&text) + .map_err(|error| { + AssetAiError::Io(format!("parse {}: {error:?}", path.display())) + })? + .acknowledgements, + Err(error) if error.kind() == std::io::ErrorKind::NotFound => Vec::new(), + Err(error) => { + return Err(AssetAiError::Io(format!( + "read {}: {error}", + path.display() + ))) + } + }; + Ok(Self { path, records }) + } + + pub fn path(&self) -> &Path { + &self.path + } + + pub fn records(&self) -> &[LicenseAcknowledgement] { + &self.records + } + + pub fn acknowledged(&self, model_id: &str, identity: &str) -> bool { + self.records + .iter() + .any(|record| record.model_id == model_id && record.identity == identity) + } + + pub fn acknowledge(&mut self, model_id: &str, identity: &str) -> Result<(), AssetAiError> { + if self.acknowledged(model_id, identity) { + return Ok(()); + } + self.records.push(LicenseAcknowledgement { + model_id: model_id.to_string(), + identity: identity.to_string(), + acknowledged_at: unix_time(), + }); + if let Err(error) = self.persist() { + self.records.pop(); + return Err(error); + } + Ok(()) + } + + fn persist(&self) -> Result<(), AssetAiError> { + let parent = self.path.parent().ok_or_else(|| { + AssetAiError::Io(format!("licence acknowledgement path has no parent: {}", self.path.display())) + })?; + fs::create_dir_all(parent) + .map_err(|error| AssetAiError::Io(format!("mkdir {}: {error}", parent.display())))?; + let file = LicenseFile { + version: 1, + acknowledgements: self.records.clone(), + }; + let part = parent.join(format!( + ".license_acks-{}-{}.part", + std::process::id(), + unix_nanos() + )); + fs::write(&part, file.serialize_json()).map_err(|error| { + AssetAiError::Io(format!("write {}: {error}", part.display())) + })?; + if let Ok(handle) = fs::OpenOptions::new().write(true).open(&part) { + let _ = handle.sync_all(); + } + #[cfg(windows)] + if self.path.exists() { + fs::remove_file(&self.path).map_err(|error| { + AssetAiError::Io(format!("replace {}: {error}", self.path.display())) + })?; + } + fs::rename(&part, &self.path).map_err(|error| { + let _ = fs::remove_file(&part); + AssetAiError::Io(format!( + "rename {} to {}: {error}", + part.display(), + self.path.display() + )) + })?; + Ok(()) + } +} + +fn unix_time() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .map(|duration| duration.as_secs()) + .unwrap_or(0) +} + +fn unix_nanos() -> u128 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .map(|duration| duration.as_nanos()) + .unwrap_or(0) +} + +#[cfg(test)] +mod tests { + use super::*; + + // Opened at an explicit path: sibling tests drive MAKEPAD_HOME themselves and + // run in parallel, so touching the process environment here would race them. + #[test] + fn license_persistence_round_trip_at_an_explicit_path() { + let root = std::env::temp_dir().join(format!( + "makepad-ai-license-test-{}-{}", + std::process::id(), + unix_nanos() + )); + let path = root.join(LICENSE_ACKS_FILE); + let mut store = LicenseStore::open_at(path.clone()).unwrap(); + assert_eq!(store.path(), path.as_path()); + assert!(!store.acknowledged("model-a", "licence-v1")); + store.acknowledge("model-a", "licence-v1").unwrap(); + assert_eq!(store.records().len(), 1); + let reopened = LicenseStore::open_at(path).unwrap(); + assert!(reopened.acknowledged("model-a", "licence-v1")); + assert!(!reopened.acknowledged("model-a", "licence-v2")); + let _ = fs::remove_dir_all(root); + } +} diff --git a/libs/ai/hub/src/local.rs b/libs/ai/hub/src/local.rs new file mode 100644 index 000000000..f18882927 --- /dev/null +++ b/libs/ai/hub/src/local.rs @@ -0,0 +1,701 @@ +//! Poll-driven, in-process model installation and execution for desktop apps. +//! +//! This is a local face over the same registry, downloader and backend +//! implementations used by the fleet service. It opens no socket and starts +//! no thread until an install or generation is requested. + +use crate::backend::{ + create_backend, ArtifactData, BackendCtx, CancelToken, ContentBackend, GenerateParams, +}; +use crate::download::{part_path, DownloadProgress, Downloader}; +use crate::error::AssetAiError; +use crate::home::weights_dir; +pub use crate::license::LicensePrompt; +use crate::license::LicenseStore; +use crate::registry::{FileSpec, ModelSpec, Registry}; +pub use makepad_ai_common::backend::GraphDevice; +use std::collections::HashMap; +use std::fs; +use std::path::{Path, PathBuf}; +use std::sync::{mpsc, Arc, Mutex}; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum InstallState { + NotInstalled { bytes_total: u64 }, + Partial { bytes_done: u64, bytes_total: u64 }, + Installed, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum InstallMsg { + Progress { file: String, done: u64, total: u64 }, + FileDone { file: String }, + Finished, + Failed(String), + Cancelled, +} + +pub struct InstallHandle { + receiver: mpsc::Receiver, + cancel: CancelToken, +} + +impl InstallHandle { + /// Drain every message currently available without blocking the caller. + pub fn poll(&self) -> Vec { + self.receiver.try_iter().collect() + } + + /// Leave verified final files in place and resumable `.part` files on + /// disk, then stop at the downloader's next natural boundary. + pub fn cancel(&self) { + self.cancel.cancel(); + } +} + +#[derive(Clone, Debug)] +pub enum JobState { + Queued, + Running { stage: String, progress: f64 }, + Done(Vec), + Failed(String), + Cancelled, +} + +impl JobState { + pub fn is_terminal(&self) -> bool { + matches!(self, Self::Done(_) | Self::Failed(_) | Self::Cancelled) + } +} + +pub struct JobHandle { + receiver: mpsc::Receiver, + cancel: CancelToken, + state: JobState, +} + +impl JobHandle { + /// Return the newest state currently available. Terminal results remain + /// readable on later polls. + pub fn poll(&mut self) -> JobState { + for state in self.receiver.try_iter() { + self.state = state; + } + self.state.clone() + } + + pub fn cancel(&self) { + self.cancel.cancel(); + } +} + +struct CachedBackend { + backend: Box, + prepared: bool, + loaded: bool, +} + +/// Registry-backed local model manager. Construction performs filesystem and +/// environment setup only; no GPU runtime is created until [`Self::run`]. +pub struct LocalModels { + registry: Registry, + downloader: Downloader, + weights_dir: PathBuf, + licenses: LicenseStore, + backends: HashMap>>, + device: GraphDevice, +} + +impl LocalModels { + /// Open the shared weight directory, its optional `registry.json` + /// override, the downloader environment, and the durable licence store. + pub fn open() -> Result { + let weights_dir = std::env::var_os("MAKEPAD_ASSET_AI_CACHE") + .map(PathBuf::from) + .unwrap_or_else(weights_dir); + fs::create_dir_all(&weights_dir).map_err(|error| { + AssetAiError::Io(format!("mkdir {}: {error}", weights_dir.display())) + })?; + let override_path = weights_dir.join("registry.json"); + let registry = if override_path.is_file() { + Registry::load_file(&override_path)? + } else { + Registry::embedded()? + }; + Ok(Self { + registry, + downloader: Downloader::from_env()?, + weights_dir, + licenses: LicenseStore::open()?, + backends: HashMap::new(), + device: resolve_graph_device(), + }) + } + + pub fn spec(&self, model_id: &str) -> Option<&ModelSpec> { + self.registry.find(model_id) + } + + /// Where an installed file of this model lives, by its registry role + /// (`"native-body"`…), for callers that run the model in-process + /// instead of through `run`. `None` until the file is installed exactly. + pub fn installed_path(&self, model_id: &str, role: &str) -> Option { + let spec = self.registry.find(model_id)?; + let file = spec.files.iter().find(|file| file.role.as_deref() == Some(role))?; + if !file_is_exact(file, &self.weights_dir) { + return None; + } + installed_path(file, &self.weights_dir) + } + + /// Directory containing a model's installed files. Unlike + /// [`Self::installed_path`], this is for multi-file banks whose files do + /// not have individual runtime roles. It stays unavailable until every + /// required file is present with its pinned identity. + pub fn installed_dir(&self, model_id: &str) -> Option { + let spec = self.registry.find(model_id)?; + if !spec + .files + .iter() + .filter(|file| !file.optional) + .all(|file| file_is_exact(file, &self.weights_dir)) + { + return None; + } + let first = spec + .files + .iter() + .find(|file| file_is_exact(file, &self.weights_dir))?; + installed_path(first, &self.weights_dir)?.parent().map(Path::to_path_buf) + } + + pub fn install_state(&self, model_id: &str) -> InstallState { + let Some(spec) = self.registry.find(model_id) else { + return InstallState::NotInstalled { bytes_total: 0 }; + }; + install_state_for(spec, &self.weights_dir) + } + + /// Return the registry licence or a fail-closed synthetic restricted + /// prompt when the model has no licence block. + pub fn license(&self, model_id: &str) -> Option { + self.registry.find(model_id).map(LicensePrompt::from_spec) + } + + pub fn license_acknowledged(&self, model_id: &str) -> bool { + let Some(spec) = self.registry.find(model_id) else { + return false; + }; + let Some(license) = &spec.license else { + return false; + }; + self.licenses + .acknowledged(model_id, &license.identity()) + } + + pub fn acknowledge_license(&mut self, model_id: &str) -> Result<(), AssetAiError> { + let spec = self + .registry + .find(model_id) + .ok_or_else(|| AssetAiError::UnknownModel(model_id.to_string()))?; + let license = spec.license.as_ref().ok_or_else(|| { + AssetAiError::Registry(format!( + "model {model_id} has no licence record; acknowledgement is fail-closed" + )) + })?; + self.licenses.acknowledge(model_id, &license.identity()) + } + + pub fn start_install(&self, model_id: &str) -> Result { + let spec = self + .registry + .find(model_id) + .ok_or_else(|| AssetAiError::UnknownModel(model_id.to_string()))? + .clone(); + if !self.license_acknowledged(model_id) { + return Err(AssetAiError::LicenseNotAcknowledged); + } + if !spec.available { + return Err(AssetAiError::Unavailable(format!( + "model {} is disabled in the registry", + spec.id + ))); + } + + let downloader = self.downloader.clone(); + let weights_dir = self.weights_dir.clone(); + let (sender, receiver) = mpsc::channel(); + let cancel = CancelToken::new(); + let worker_cancel = cancel.clone(); + std::thread::Builder::new() + .name(format!("ai-local-install-{}", spec.id)) + .spawn(move || { + for file in &spec.files { + if worker_cancel.is_cancelled() { + let _ = sender.send(InstallMsg::Cancelled); + return; + } + let fallback_total = file.size.unwrap_or(0); + let result = downloader.ensure_file( + file, + &weights_dir, + &mut |progress: DownloadProgress| { + let _ = sender.send(InstallMsg::Progress { + file: progress.file, + done: progress.done, + total: progress.total.unwrap_or(fallback_total), + }); + }, + &worker_cancel, + ); + match result { + Ok(_) => { + let _ = sender.send(InstallMsg::FileDone { + file: file.cache_as.clone(), + }); + } + Err(AssetAiError::Cancelled) => { + let _ = sender.send(InstallMsg::Cancelled); + return; + } + Err(error) if file.optional => { + let _ = sender.send(InstallMsg::Failed(error.to_string())); + } + Err(error) => { + let _ = sender.send(InstallMsg::Failed(error.to_string())); + let _ = sender.send(InstallMsg::Finished); + return; + } + } + } + let _ = sender.send(InstallMsg::Finished); + }) + .map_err(|error| AssetAiError::Io(format!("spawn local installer: {error}")))?; + Ok(InstallHandle { receiver, cancel }) + } + + pub fn run( + &mut self, + model_id: &str, + mut params: GenerateParams, + ) -> Result { + let spec = self + .registry + .find(model_id) + .ok_or_else(|| AssetAiError::UnknownModel(model_id.to_string()))? + .clone(); + if !self.license_acknowledged(model_id) { + return Err(AssetAiError::LicenseNotAcknowledged); + } + if !matches!(self.install_state(model_id), InstallState::Installed) { + return Err(AssetAiError::NotInstalled(model_id.to_string())); + } + if !spec.available { + return Err(AssetAiError::Unavailable(format!( + "model {} is disabled in the registry", + spec.id + ))); + } + params.model = model_id.to_string(); + + let cached = match self.backends.get(model_id) { + Some(cached) => cached.clone(), + None => { + let cached = Arc::new(Mutex::new(CachedBackend { + backend: create_backend(&spec)?, + prepared: false, + loaded: false, + })); + self.backends.insert(model_id.to_string(), cached.clone()); + cached + } + }; + let downloader = self.downloader.clone(); + let weights_dir = self.weights_dir.clone(); + let (sender, receiver) = mpsc::channel(); + let cancel = CancelToken::new(); + let worker_cancel = cancel.clone(); + std::thread::Builder::new() + .name(format!("ai-local-run-{model_id}")) + .spawn(move || { + let _ = sender.send(JobState::Running { + stage: "queued for local backend".to_string(), + progress: 0.0, + }); + let mut cached = match cached.lock() { + Ok(cached) => cached, + Err(_) => { + let _ = sender.send(JobState::Failed( + "local backend lock was poisoned".to_string(), + )); + return; + } + }; + if worker_cancel.is_cancelled() { + let _ = sender.send(JobState::Cancelled); + return; + } + + if !cached.prepared || !cached.loaded { + let download_sender = sender.clone(); + let mut download_progress = move |progress: DownloadProgress| { + let fraction = progress + .total + .filter(|total| *total > 0) + .map(|total| progress.done as f64 / total as f64) + .unwrap_or(0.0) + .clamp(0.0, 1.0); + let _ = download_sender.send(JobState::Running { + stage: format!("download {}", progress.file), + progress: fraction, + }); + }; + let load_sender = sender.clone(); + let mut load_progress = move |stage: &str, progress: f64| { + let _ = load_sender.send(JobState::Running { + stage: stage.to_string(), + progress: progress.clamp(0.0, 1.0), + }); + }; + let mut ctx = BackendCtx { + spec: &spec, + cache_dir: &weights_dir, + downloader: &downloader, + download_progress: &mut download_progress, + cancel: &worker_cancel, + progress: &mut load_progress, + }; + if !cached.prepared { + if let Err(error) = cached.backend.prepare_artifacts(&mut ctx) { + let _ = cached.backend.unload(); + cached.prepared = false; + cached.loaded = false; + send_job_error(&sender, error); + return; + } + cached.prepared = true; + } + if let Err(error) = cached.backend.ensure_loaded(&mut ctx) { + let _ = cached.backend.unload(); + cached.loaded = false; + send_job_error(&sender, error); + return; + } + cached.loaded = true; + } + + if worker_cancel.is_cancelled() { + let _ = sender.send(JobState::Cancelled); + return; + } + let progress_sender = sender.clone(); + let mut progress = move |stage: &str, fraction: f64| { + let _ = progress_sender.send(JobState::Running { + stage: stage.to_string(), + progress: fraction.clamp(0.0, 1.0), + }); + }; + match cached + .backend + .generate(¶ms, &mut progress, &worker_cancel) + { + Ok(artifacts) => { + let _ = sender.send(JobState::Done(artifacts)); + } + Err(error) => { + if !cached.backend.resident_is_healthy_after_error(&error) { + let _ = cached.backend.unload(); + cached.loaded = false; + } + send_job_error(&sender, error); + } + } + }) + .map_err(|error| AssetAiError::Io(format!("spawn local model job: {error}")))?; + + Ok(JobHandle { + receiver, + cancel, + state: JobState::Queued, + }) + } + + /// Evict one cached backend's resident state. Installed files and licence + /// acknowledgements are left untouched. + pub fn unload(&mut self, model_id: &str) -> Result<(), AssetAiError> { + let Some(cached) = self.backends.get(model_id).cloned() else { + return Ok(()); + }; + let mut cached = match cached.try_lock() { + Ok(cached) => cached, + Err(std::sync::TryLockError::WouldBlock) => return Err(AssetAiError::Busy), + Err(std::sync::TryLockError::Poisoned(_)) => { + return Err(AssetAiError::Backend( + "local backend lock was poisoned".to_string(), + )) + } + }; + cached.backend.unload()?; + cached.loaded = false; + drop(cached); + self.backends.remove(model_id); + Ok(()) + } + + /// Report the graph store selected by the platform/environment without + /// constructing a runtime or touching the GPU. + pub fn device(&self) -> GraphDevice { + self.device + } +} + +fn send_job_error(sender: &mpsc::Sender, error: AssetAiError) { + let state = if matches!(error, AssetAiError::Cancelled) { + JobState::Cancelled + } else { + JobState::Failed(error.to_string()) + }; + let _ = sender.send(state); +} + +fn resolve_graph_device() -> GraphDevice { + match std::env::var("MAKEPAD_AI_GRAPH_BACKEND") + .ok() + .as_deref() + .map(str::trim) + { + Some("cuda") | Some("CUDA") => GraphDevice::Cuda, + Some("metal") | Some("METAL") => GraphDevice::Metal, + _ if cfg!(target_os = "macos") => GraphDevice::Metal, + _ => GraphDevice::Cuda, + } +} + +fn install_state_for(spec: &ModelSpec, weights_dir: &Path) -> InstallState { + let required: Vec<&FileSpec> = spec.files.iter().filter(|file| !file.optional).collect(); + if required.is_empty() { + return InstallState::Installed; + } + let bytes_total = required.iter().filter_map(|file| file.size).sum(); + let mut bytes_done = 0u64; + let mut all_installed = true; + for file in required { + if file_is_exact(file, weights_dir) { + bytes_done = bytes_done.saturating_add(file.size.unwrap_or_else(|| { + installed_path(file, weights_dir) + .and_then(|path| fs::metadata(path).ok()) + .map(|metadata| metadata.len()) + .unwrap_or(0) + })); + continue; + } + all_installed = false; + let dest = file.dest_path(weights_dir); + let partial_len = fs::metadata(part_path(&dest)) + .or_else(|_| fs::metadata(&dest)) + .map(|metadata| metadata.len()) + .unwrap_or(0); + bytes_done = bytes_done.saturating_add(match file.size { + Some(expected) => partial_len.min(expected), + None => partial_len, + }); + } + if all_installed { + InstallState::Installed + } else if bytes_done == 0 { + InstallState::NotInstalled { bytes_total } + } else { + InstallState::Partial { + bytes_done, + bytes_total, + } + } +} + +fn installed_path(file: &FileSpec, weights_dir: &Path) -> Option { + if converted_is_exact(file, weights_dir) { + file.converted_path(weights_dir) + } else { + Some(file.dest_path(weights_dir)) + } +} + +fn file_is_exact(file: &FileSpec, weights_dir: &Path) -> bool { + if converted_is_exact(file, weights_dir) { + return true; + } + let path = file.dest_path(weights_dir); + exact_size_or_exists(&path, file.size) +} + +fn converted_is_exact(file: &FileSpec, weights_dir: &Path) -> bool { + let Some(path) = file.converted_path(weights_dir) else { + return false; + }; + let expected = file.conversion.as_ref().map(|conversion| conversion.size); + exact_size_or_exists(&path, expected) +} + +fn exact_size_or_exists(path: &Path, expected: Option) -> bool { + fs::metadata(path) + .map(|metadata| metadata.is_file() && expected.map_or(true, |size| metadata.len() == size)) + .unwrap_or(false) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn registry(license_name: Option<&str>) -> Registry { + let license = match license_name { + Some(name) => format!( + r#", "license": {{"name":"{name}","url":"https://example.test/licence","summary":"test terms","restriction":"none","sha256":null}}"# + ), + None => String::new(), + }; + Registry::parse(&format!( + r#"{{"models":[{{"id":"local-test","domain":"image","backend":"testpattern","available":true,"gated":false,"vram_gb":0.0,"min_vram_gb":null,"min_compute_cap":null,"note":null{license},"files":[]}}]}}"# + )) + .unwrap() + } + + fn manager(root: &Path, registry: Registry) -> LocalModels { + fs::create_dir_all(root).unwrap(); + LocalModels { + registry, + downloader: Downloader::new("http://127.0.0.1:9", None).unwrap(), + weights_dir: root.join("weights"), + licenses: LicenseStore::open_at(root.join("license_acks.json")).unwrap(), + backends: HashMap::new(), + device: GraphDevice::Metal, + } + } + + fn temp_root(tag: &str) -> PathBuf { + std::env::temp_dir().join(format!( + "makepad-ai-local-{tag}-{}-{}", + std::process::id(), + crate::jobs::now_ms() + )) + } + + fn test_params() -> GenerateParams { + GenerateParams::from_request(&crate::protocol::GenerateRequestJson { + model: "local-test".to_string(), + prompt: Some("local runner".to_string()), + width: Some(8), + height: Some(8), + ..Default::default() + }) + .unwrap() + } + + #[test] + fn local_refuses_before_ack_and_allows_after_ack() { + let root = temp_root("gate"); + let mut models = manager(&root, registry(Some("Licence v1"))); + assert!(matches!( + models.start_install("local-test"), + Err(AssetAiError::LicenseNotAcknowledged) + )); + assert!(matches!( + models.run("local-test", test_params()), + Err(AssetAiError::LicenseNotAcknowledged) + )); + models.acknowledge_license("local-test").unwrap(); + assert!(models.license_acknowledged("local-test")); + let install = models.start_install("local-test").unwrap(); + let mut finished = false; + for _ in 0..10_000 { + if install + .poll() + .iter() + .any(|message| matches!(message, InstallMsg::Finished)) + { + finished = true; + break; + } + std::thread::yield_now(); + } + assert!(finished, "empty local install worker did not finish"); + + let mut job = models.run("local-test", test_params()).unwrap(); + let mut terminal = None; + for _ in 0..10_000 { + let state = job.poll(); + if state.is_terminal() { + terminal = Some(state); + break; + } + std::thread::yield_now(); + } + assert!(matches!(terminal, Some(JobState::Done(_)))); + let _ = fs::remove_dir_all(root); + } + + #[test] + fn local_install_state_requires_the_exact_pinned_size() { + let root = temp_root("size"); + let registry = Registry::parse( + r#"{"models":[{"id":"sized","domain":"image","backend":"testpattern","available":true,"gated":false,"vram_gb":0.0,"note":null,"license":{"name":"L","url":"https://example.test/l","summary":"s","restriction":"none"},"files":[{"repo":"o/r","path":"model.bin","cache_as":"sized/model.bin","size":8,"sha256":null}]}]}"#, + ) + .unwrap(); + let models = manager(&root, registry); + let dest = models.spec("sized").unwrap().files[0].dest_path(&models.weights_dir); + fs::create_dir_all(dest.parent().unwrap()).unwrap(); + fs::write(&dest, b"1234").unwrap(); + assert_eq!( + models.install_state("sized"), + InstallState::Partial { + bytes_done: 4, + bytes_total: 8 + } + ); + fs::write(&dest, b"12345678").unwrap(); + assert_eq!(models.install_state("sized"), InstallState::Installed); + let _ = fs::remove_dir_all(root); + } + + #[test] + fn installed_dir_requires_every_required_file() { + let root = temp_root("dir"); + let registry = Registry::parse( + r#"{"models":[{"id":"bank","domain":"audio","backend":"sample-kit","available":true,"gated":false,"vram_gb":0.0,"note":null,"license":{"name":"L","url":"https://example.test/l","summary":"s","restriction":"none"},"files":[{"repo":"o/r","path":"a.wav","cache_as":"drums/bank/OH/a.wav","size":1,"sha256":null},{"repo":"o/r","path":"b.wav","cache_as":"drums/bank/OH/b.wav","size":1,"sha256":null}]}]}"#, + ) + .unwrap(); + let models = manager(&root, registry); + let files = &models.spec("bank").unwrap().files; + let first = files[0].dest_path(&models.weights_dir); + let second = files[1].dest_path(&models.weights_dir); + fs::create_dir_all(first.parent().unwrap()).unwrap(); + fs::write(&first, b"a").unwrap(); + assert_eq!(models.installed_dir("bank"), None); + fs::write(&second, b"b").unwrap(); + assert_eq!(models.installed_dir("bank"), first.parent().map(Path::to_path_buf)); + let _ = fs::remove_dir_all(root); + } + + #[test] + fn local_reprompts_when_unpinned_license_identity_changes() { + let root = temp_root("identity"); + let mut first = manager(&root, registry(Some("Licence v1"))); + first.acknowledge_license("local-test").unwrap(); + assert!(first.license_acknowledged("local-test")); + drop(first); + + let second = manager(&root, registry(Some("Licence v2"))); + assert!(!second.license_acknowledged("local-test")); + let _ = fs::remove_dir_all(root); + } + + #[test] + fn local_missing_license_is_synthetic_and_never_clears() { + let root = temp_root("missing"); + let mut models = manager(&root, registry(None)); + let prompt = models.license("local-test").unwrap(); + assert_eq!(prompt.restriction, crate::registry::LicenseRestriction::Restricted); + assert!(models.acknowledge_license("local-test").is_err()); + assert!(!models.license_acknowledged("local-test")); + let _ = fs::remove_dir_all(root); + } +} diff --git a/libs/ai/hub/src/notes_backend.rs b/libs/ai/hub/src/notes_backend.rs new file mode 100644 index 000000000..a278855a6 --- /dev/null +++ b/libs/ai/hub/src/notes_backend.rs @@ -0,0 +1,192 @@ +//! `notes` domain: PCM WAV -> Basic Pitch note-event JSON + MIDI. + +use crate::backend::{ + ArtifactData, BackendCtx, CancelToken, ContentBackend, GenerateParams, ProgressSink, +}; +use crate::error::AssetAiError; +use makepad_ai_notes::{to_midi_bytes, NoteTranscription, NotesModel}; + +pub struct NotesBackend { + model_id: String, + model: Option, +} + +impl NotesBackend { + pub fn new(model_id: &str) -> Self { + Self { + model_id: model_id.to_string(), + model: None, + } + } +} + +impl ContentBackend for NotesBackend { + fn model_id(&self) -> &str { + &self.model_id + } + + fn ensure_loaded(&mut self, ctx: &mut BackendCtx) -> Result<(), AssetAiError> { + if self.model.is_some() { + return Ok(()); + } + ctx.ensure_files()?; + ctx.cancel.check()?; + (ctx.progress)("notes: parse ONNX", 0.5); + let path = ctx.path_by_role("model")?; + self.model = Some( + NotesModel::load(&path) + .map_err(|error| AssetAiError::Backend(format!("notes load: {error}")))?, + ); + (ctx.progress)("notes: ready", 1.0); + Ok(()) + } + + fn is_resident(&self) -> bool { + self.model.is_some() + } + + fn unload(&mut self) -> Result<(), AssetAiError> { + self.model = None; + Ok(()) + } + + fn generate( + &mut self, + params: &GenerateParams, + progress: ProgressSink, + cancel: &CancelToken, + ) -> Result, AssetAiError> { + if params.input_bytes.is_empty() { + return Err(AssetAiError::Params( + "notes: input_b64 is required (PCM WAV, any rate/channels)".to_string(), + )); + } + cancel.check()?; + progress("notes: decode WAV", 0.02); + let (mono, source_rate) = crate::wav::decode_wav_to_mono_f32(¶ms.input_bytes) + .map_err(|error| AssetAiError::Params(format!("notes: invalid WAV: {error}")))?; + if source_rate == 0 { + return Err(AssetAiError::Params( + "notes: WAV sample rate must be non-zero".to_string(), + )); + } + cancel.check()?; + progress("notes: resample 22050 Hz", 0.05); + let mono = crate::resample::resample_channel( + &mono, + source_rate, + makepad_ai_notes::SAMPLE_RATE as u32, + ); + let model = self.model.as_mut().ok_or_else(|| { + AssetAiError::Backend("notes backend used before ensure_loaded".to_string()) + })?; + let transcription = model + .transcribe_with_progress(&mono, |done, total| { + let fraction = if total == 0 { + 1.0 + } else { + done as f64 / total as f64 + }; + progress( + &format!("notes: window {done}/{total}"), + 0.08 + 0.84 * fraction, + ); + !cancel.is_cancelled() + }) + .map_err(|error| { + if cancel.is_cancelled() { + AssetAiError::Cancelled + } else { + AssetAiError::Backend(format!("notes inference: {error}")) + } + })?; + cancel.check()?; + progress("notes: encode JSON + MIDI", 0.96); + let json = transcription_json(&transcription).into_bytes(); + let midi = to_midi_bytes(&transcription, None); + progress("done", 1.0); + Ok(vec![ + ArtifactData { + content_type: "application/json", + ext: "json", + bytes: json, + }, + ArtifactData { + content_type: "audio/midi", + ext: "mid", + bytes: midi, + }, + ]) + } +} + +fn transcription_json(transcription: &NoteTranscription) -> String { + let mut json = format!( + "{{\"frame_rate\":{},\"notes\":[", + transcription.frame_rate + ); + for (index, note) in transcription.notes.iter().enumerate() { + if index != 0 { + json.push(','); + } + json.push_str(&format!( + "{{\"start_secs\":{},\"end_secs\":{},\"midi\":{},\"amplitude\":{},\"bends\":[", + note.start_secs, note.end_secs, note.midi, note.amplitude + )); + for (bend_index, bend) in note.bends.iter().enumerate() { + if bend_index != 0 { + json.push(','); + } + json.push_str(&bend.to_string()); + } + json.push_str("]}"); + } + json.push_str("]}"); + json +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::registry::{Domain, Registry}; + use makepad_ai_notes::{NoteEvent, FRAME_RATE}; + + #[test] + fn registry_contract_is_complete() { + let registry = Registry::embedded().unwrap(); + let spec = registry.find("basic-pitch").expect("basic-pitch entry"); + assert_eq!(spec.domain, Domain::Notes); + assert_eq!(spec.backend, "notes"); + assert_eq!(spec.vram_gb, Some(0.1)); + let model = spec.file_by_role("model").unwrap(); + assert_eq!(model.cache_as, "notes/basic_pitch_nmp.onnx"); + assert_eq!(model.size, Some(230_444)); + assert_eq!( + model.sha256.as_deref(), + Some("2c3c1d144bfa61ad236e92e169c13535c880469a12a047d4e73451f2c059a0ec") + ); + } + + #[test] + fn domain_round_trips() { + assert_eq!(Domain::parse("notes"), Some(Domain::Notes)); + assert_eq!(Domain::Notes.as_str(), "notes"); + } + + #[test] + fn json_contract_contains_bends() { + let text = transcription_json(&NoteTranscription { + notes: vec![NoteEvent { + start_secs: 0.0, + end_secs: 0.5, + midi: 60, + amplitude: 0.75, + bends: vec![0.0, 1.0 / 3.0], + }], + frame_rate: FRAME_RATE, + onsets: Vec::new(), + }); + let value = makepad_strict_json::parse(text.as_bytes()).unwrap(); + assert_eq!(value.get("notes").and_then(|notes| notes.as_arr()).unwrap().len(), 1); + } +} diff --git a/libs/ai/hub/src/registry.rs b/libs/ai/hub/src/registry.rs index c3b846f9d..6103f83ef 100644 --- a/libs/ai/hub/src/registry.rs +++ b/libs/ai/hub/src/registry.rs @@ -198,6 +198,14 @@ pub enum Domain { /// Speech audio -> timed transcript (Whisper). The `stt.whisper` pipe; /// `Speech` stays text-to-speech, so the two never share affinity. Stt, + /// Audio -> beat and downbeat tracking JSON. + Beats, + /// Audio -> polyphonic note transcription JSON/MIDI. + Notes, + /// Audio -> music-structure sections. + Sections, + /// Image -> sewing-pattern JSON. + Garment, } impl Domain { @@ -227,6 +235,10 @@ impl Domain { "vision" => Some(Domain::Vision), "ocr" => Some(Domain::Ocr), "stt" => Some(Domain::Stt), + "beats" => Some(Domain::Beats), + "notes" => Some(Domain::Notes), + "sections" => Some(Domain::Sections), + "garment" => Some(Domain::Garment), _ => None, } } @@ -257,6 +269,10 @@ impl Domain { Domain::Vision => "vision", Domain::Ocr => "ocr", Domain::Stt => "stt", + Domain::Beats => "beats", + Domain::Notes => "notes", + Domain::Sections => "sections", + Domain::Garment => "garment", } } } @@ -378,11 +394,14 @@ pub struct ModelLicense { impl ModelLicense { /// Stable identity of the *text* the user accepted: sha256 when pinned, - /// otherwise the canonical URL. + /// otherwise a hash of the licence name and canonical URL. A registry + /// correction to either value therefore prompts again. pub fn identity(&self) -> String { self.sha256 .clone() - .unwrap_or_else(|| self.url.clone()) + .unwrap_or_else(|| { + crate::sha256::sha256_hex(format!("{}\0{}", self.name, self.url).as_bytes()) + }) } } @@ -456,7 +475,7 @@ impl Registry { for model in wire.models { let domain = Domain::parse(&model.domain).ok_or_else(|| { AssetAiError::Registry(format!( - "model {}: unknown domain {:?} (expected image|mesh|video|audio|text|speech|world|matte|depth|body|segment|rig|motion)", + "model {}: unknown domain {:?} (expected image|mesh|video|audio|text|speech|world|matte|depth|body|segment|rig|motion|music|paint|edit|upscale|control|inpaint|enhance|splat|vision|ocr|beats|notes|sections|garment)", model.id, model.domain )) })?; @@ -877,6 +896,19 @@ mod tests { registry.find("pbr-testpattern").is_none(), "deterministic paint-test is crate-internal and must not advertise" ); + let beats = registry.find("beat-this").unwrap(); + assert_eq!(beats.domain, Domain::Beats); + assert_eq!(beats.backend, "beats"); + assert_eq!(beats.vram_gb, Some(0.5)); + assert_eq!(beats.files.len(), 2); + let final_weights = beats.file_by_role("weights").unwrap(); + assert_eq!(final_weights.size, Some(81_058_141)); + assert_eq!( + final_weights.sha256.as_deref(), + Some("8c328b45f59d8dd3dff219253ff6a8d6482be57d0133a29140e2febbf8eb8331") + ); + assert!(final_weights.path.starts_with("https://cloud.cp.jku.at/")); + assert!(beats.file_by_role("weights-small").unwrap().optional); let hunyuan = registry.find("hunyuan3d-paint-2.1").unwrap(); assert_eq!(hunyuan.domain, Domain::Paint); assert_eq!(hunyuan.backend, "paint"); @@ -1810,4 +1842,17 @@ mod tests { let message = Registry::parse(json).unwrap_err().to_string(); assert!(message.contains("unknown license restriction"), "{message}"); } + + #[test] + fn local_app_domains_round_trip() { + for (text, domain) in [ + ("beats", Domain::Beats), + ("notes", Domain::Notes), + ("sections", Domain::Sections), + ("garment", Domain::Garment), + ] { + assert_eq!(Domain::parse(text), Some(domain)); + assert_eq!(domain.as_str(), text); + } + } } diff --git a/libs/ai/hub_ui/Cargo.toml b/libs/ai/hub_ui/Cargo.toml new file mode 100644 index 000000000..bcb73488d --- /dev/null +++ b/libs/ai/hub_ui/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "makepad-ai-hub-ui" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" +description = "Shared Makepad model-install and weight-licence UI for local AI models" + +[dependencies] +makepad-widgets = { path = "../../../widgets" } +makepad-ai-hub = { path = "../hub", default-features = false, features = ["local"] } diff --git a/libs/ai/hub_ui/src/lib.rs b/libs/ai/hub_ui/src/lib.rs new file mode 100644 index 000000000..be196516b --- /dev/null +++ b/libs/ai/hub_ui/src/lib.rs @@ -0,0 +1,672 @@ +//! Shared local-model install rows, licence ceremony, and install controller. + +use makepad_ai_hub::license::LicensePrompt; +use makepad_ai_hub::local::{InstallHandle, InstallMsg, InstallState, LocalModels}; +use makepad_ai_hub::registry::LicenseRestriction; +use makepad_widgets::*; +use std::collections::HashMap; + +script_mod! { + use mod.prelude.widgets_internal.* + use mod.widgets.* + + mod.widgets.ModelInstallRowBase = #(ModelInstallRow::register_widget(vm)) + mod.widgets.ModelInstallRow = set_type_default() do mod.widgets.ModelInstallRowBase { + width: Fill + height: Fit + flow: Down + spacing: 6 + margin: Inset{bottom: 6} + padding: Inset{left: 12 right: 12 top: 10 bottom: 10} + show_bg: true + draw_bg +: { + color: #x20242b + } + + View { + width: Fill + height: Fit + flow: Right + spacing: 8 + align: Align{x: 0.0 y: 0.5} + model_name := Label { + width: Fill + height: Fit + text: "" + draw_text +: { + color: #xe8edf4 + text_style: theme.font_bold{font_size: 12} + } + } + model_size := Label { + width: Fit + height: Fit + text: "0 MB" + draw_text +: { + color: #x8f9baa + text_style: theme.font_regular{font_size: 10} + } + } + } + + View { + width: Fill + height: Fit + flow: Right + spacing: 8 + align: Align{x: 0.0 y: 0.5} + licence_link := LinkLabel { + width: Fit + height: Fit + text: "Licence" + draw_text +: { text_style: theme.font_regular{font_size: 10} } + } + restriction_chip := RoundedView { + width: Fit + height: Fit + padding: Inset{left: 6 right: 6 top: 2 bottom: 2} + show_bg: true + draw_bg +: { + color: #x343a44 + radius: 8.0 + } + restriction := Label { + width: Fit + height: Fit + text: "restricted" + draw_text +: { + color: #xc7cfda + text_style: theme.font_regular{font_size: 9} + } + } + } + } + + View { + width: Fill + height: Fit + flow: Right + spacing: 8 + align: Align{x: 0.0 y: 0.5} + state_text := Label { + width: Fill + height: Fit + text: "not installed" + draw_text +: { + color: #xaab4c2 + text_style: theme.font_regular{font_size: 10} + } + } + install_button := Button { + width: 92 + height: 26 + text: "INSTALL" + } + } + } + + mod.widgets.LicenseModalBase = #(LicenseModal::register_widget(vm)) + mod.widgets.LicenseModal = set_type_default() do mod.widgets.LicenseModalBase { + modal := Modal { + can_dismiss: false + content +: { + width: 540 + height: Fit + card := RoundedView { + width: Fill + height: Fit + flow: Down + spacing: 10 + padding: 20 + show_bg: true + draw_bg +: { + color: #x16161b + border_color: #xffffff18 + border_size: 1.0 + radius: 6.0 + } + licence_title := Label { + width: Fill + height: Fit + text: "Before downloading model" + draw_text +: { + color: #xf2f4f8 + text_style: theme.font_bold{font_size: 13} + } + } + licence_name := Label { + width: Fill + height: Fit + text: "" + draw_text +: { color: #xc8d0dc } + } + restriction_text := Label { + width: Fill + height: Fit + text: "" + draw_text +: { + color: #xe2b982 + text_style: theme.font_regular{font_size: 10} + } + } + licence_summary := Label { + width: Fill + height: Fit + text: "" + draw_text +: { + color: #xaeb8c6 + text_style: theme.font_regular{font_size: 11} + } + } + full_licence := LinkLabel { + text: "Read the full licence" + } + View { + width: Fill + height: Fit + flow: Right + spacing: 8 + align: Align{x: 1.0 y: 0.5} + decline := Button { width: 90 height: 28 text: "Decline" } + accept := Button { width: 90 height: 28 text: "Accept" } + } + } + } + } + } + + mod.widgets.ModelInstallPanelBase = #(ModelInstallPanel::register_widget(vm)) + mod.widgets.ModelInstallPanel = set_type_default() do mod.widgets.ModelInstallPanelBase { + width: Fill + height: Fill + flow: Overlay + + empty := Label { + width: Fill + height: Fit + text: "no models registered for this app" + draw_text +: { + color: #x8f9baa + text_style: theme.font_regular{font_size: 11} + } + } + list := PortalList { + width: Fill + height: Fill + flow: Down + drag_scrolling: false + Row := mod.widgets.ModelInstallRow {} + } + licence_modal := mod.widgets.LicenseModal {} + } +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub enum ModelRowInstallState { + #[default] + NotInstalled, + Downloading, + Installed, + Failed(String), +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct ModelRowState { + pub model_id: String, + pub name: String, + pub bytes_total: u64, + pub bytes_done: u64, + pub state: ModelRowInstallState, + pub license_name: String, + pub restriction: String, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub enum ModelInstallAction { + Install(String), + Cancel(String), + OpenLicense(String), + #[default] + None, +} + +#[derive(Script, ScriptHook, Widget)] +pub struct ModelInstallRow { + #[source] + source: ScriptObjectRef, + #[deref] + view: View, + #[rust] + state: ModelRowState, +} + +impl ModelInstallRow { + pub fn set_state(&mut self, cx: &mut Cx, state: ModelRowState) { + self.state = state; + self.sync(cx); + } + + fn sync(&mut self, cx: &mut Cx) { + self.view + .label(cx, ids!(model_name)) + .set_text(cx, &self.state.name); + self.view + .label(cx, ids!(model_size)) + .set_text(cx, &format_mb(self.state.bytes_total)); + let link = self.view.link_label(cx, ids!(licence_link)); + link.set_text(cx, &self.state.license_name); + self.view + .label(cx, ids!(restriction)) + .set_text( + cx, + if self.state.restriction == "none" { + "permissive" + } else { + &self.state.restriction + }, + ); + + let (status, button, visible) = match &self.state.state { + ModelRowInstallState::NotInstalled => ("not installed".to_string(), "INSTALL", true), + ModelRowInstallState::Downloading => { + let total = self.state.bytes_total.max(1); + ( + format!( + "downloading {}% · {}/{} MB", + (self.state.bytes_done.saturating_mul(100) / total).min(100), + self.state.bytes_done / 1_000_000, + self.state.bytes_total / 1_000_000 + ), + "CANCEL", + true, + ) + } + ModelRowInstallState::Installed => ("installed".to_string(), "INSTALL", false), + ModelRowInstallState::Failed(error) => { + (format!("not installed · {error}"), "INSTALL", true) + } + }; + self.view + .label(cx, ids!(state_text)) + .set_text(cx, &status); + let install = self.view.button(cx, ids!(install_button)); + install.set_text(cx, button); + install.set_visible(cx, visible); + self.view.redraw(cx); + } +} + +impl Widget for ModelInstallRow { + fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) { + self.view.handle_event(cx, event, scope); + let Event::Actions(actions) = event else { + return; + }; + if self.view.button(cx, ids!(install_button)).clicked(actions) { + let action = if matches!(self.state.state, ModelRowInstallState::Downloading) { + ModelInstallAction::Cancel(self.state.model_id.clone()) + } else { + ModelInstallAction::Install(self.state.model_id.clone()) + }; + cx.widget_action(self.widget_uid(), action); + } + if self.view.link_label(cx, ids!(licence_link)).clicked(actions) { + cx.widget_action( + self.widget_uid(), + ModelInstallAction::OpenLicense(self.state.model_id.clone()), + ); + } + } + + fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep { + self.view.draw_walk(cx, scope, walk) + } +} + +impl ModelInstallRowRef { + pub fn set_state(&self, cx: &mut Cx, state: ModelRowState) { + if let Some(mut row) = self.borrow_mut() { + row.set_state(cx, state); + } + } +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub enum LicenseModalAction { + Accepted(String), + Declined(String), + #[default] + None, +} + +#[derive(Script, ScriptHook, Widget)] +pub struct LicenseModal { + #[source] + source: ScriptObjectRef, + #[deref] + view: View, + #[rust] + model_id: String, +} + +impl LicenseModal { + pub fn show(&mut self, cx: &mut Cx, prompt: &LicensePrompt) { + self.model_id = prompt.model_id.clone(); + self.view + .label(cx, ids!(licence_title)) + .set_text(cx, &format!("Before downloading {}", prompt.model_id)); + self.view + .label(cx, ids!(licence_name)) + .set_text(cx, &prompt.name); + self.view + .label(cx, ids!(restriction_text)) + .set_text(cx, restriction_text(prompt.restriction)); + self.view + .label(cx, ids!(licence_summary)) + .set_text(cx, &prompt.summary); + let link = self.view.link_label(cx, ids!(full_licence)); + link.set_text(cx, "Read the full licence"); + link.set_url(&prompt.url); + self.view.modal(cx, ids!(modal)).open(cx); + self.view.redraw(cx); + } + + fn close(&mut self, cx: &mut Cx) { + self.view.modal(cx, ids!(modal)).close(cx); + self.view.redraw(cx); + } +} + +impl Widget for LicenseModal { + fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) { + self.view.handle_event(cx, event, scope); + let Event::Actions(actions) = event else { + return; + }; + if self.view.button(cx, ids!(accept)).clicked(actions) { + let model_id = self.model_id.clone(); + self.close(cx); + cx.widget_action(self.widget_uid(), LicenseModalAction::Accepted(model_id)); + } else if self.view.button(cx, ids!(decline)).clicked(actions) { + let model_id = self.model_id.clone(); + self.close(cx); + cx.widget_action(self.widget_uid(), LicenseModalAction::Declined(model_id)); + } + } + + fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep { + self.view.draw_walk(cx, scope, walk) + } +} + +impl LicenseModalRef { + pub fn show(&self, cx: &mut Cx, prompt: &LicensePrompt) { + if let Some(mut modal) = self.borrow_mut() { + modal.show(cx, prompt); + } + } +} + +#[derive(Script, ScriptHook, Widget)] +pub struct ModelInstallPanel { + #[source] + source: ScriptObjectRef, + #[deref] + view: View, + #[rust] + rows: Vec, + #[rust] + installs: HashMap, + #[rust] + pending: Vec, + #[rust] + install_after_accept: Option, +} + +#[derive(Clone, Debug)] +enum PanelAction { + Model(ModelInstallAction), + License(LicenseModalAction), +} + +impl ModelInstallPanel { + pub fn set_rows(&mut self, cx: &mut Cx, rows: Vec) { + self.rows = rows; + self.sync_empty(cx); + self.view.redraw(cx); + } + + pub fn rows(&self) -> &[ModelRowState] { + &self.rows + } + + /// Drain UI intentions and installer workers without blocking the UI + /// thread. Calling this from the host's normal event/frame pump is the + /// only controller glue an embedding app needs. + pub fn pump(&mut self, cx: &mut Cx, models: &mut LocalModels) { + for action in std::mem::take(&mut self.pending) { + match action { + PanelAction::Model(ModelInstallAction::Install(model_id)) => { + if self.installs.contains_key(&model_id) { + continue; + } + if models.license_acknowledged(&model_id) { + self.begin_install(cx, models, &model_id); + } else if let Some(prompt) = models.license(&model_id) { + self.install_after_accept = Some(model_id); + self.show_license(cx, &prompt); + } + } + PanelAction::Model(ModelInstallAction::Cancel(model_id)) => { + if let Some(handle) = self.installs.get(&model_id) { + handle.cancel(); + } + } + PanelAction::Model(ModelInstallAction::OpenLicense(model_id)) => { + self.install_after_accept = None; + if let Some(prompt) = models.license(&model_id) { + self.show_license(cx, &prompt); + } + } + PanelAction::Model(ModelInstallAction::None) => {} + PanelAction::License(LicenseModalAction::Accepted(model_id)) => { + match models.acknowledge_license(&model_id) { + Ok(()) => { + if self.install_after_accept.as_deref() == Some(model_id.as_str()) { + self.begin_install(cx, models, &model_id); + } + } + Err(error) => self.fail_row(&model_id, error.to_string()), + } + self.install_after_accept = None; + } + PanelAction::License(LicenseModalAction::Declined(_)) => { + self.install_after_accept = None; + } + PanelAction::License(LicenseModalAction::None) => {} + } + } + + let model_ids: Vec = self.installs.keys().cloned().collect(); + let mut finished = Vec::new(); + for model_id in model_ids { + let messages = self + .installs + .get(&model_id) + .map(InstallHandle::poll) + .unwrap_or_default(); + for message in messages { + match message { + InstallMsg::Progress { .. } | InstallMsg::FileDone { .. } => { + self.update_progress_from_disk(models, &model_id); + } + InstallMsg::Finished => { + finished.push(model_id.clone()); + } + InstallMsg::Failed(error) => self.fail_row(&model_id, error), + InstallMsg::Cancelled => { + finished.push(model_id.clone()); + } + } + } + } + for model_id in finished { + self.installs.remove(&model_id); + self.update_progress_from_disk(models, &model_id); + } + self.sync_empty(cx); + self.view.redraw(cx); + } + + fn begin_install(&mut self, cx: &mut Cx, models: &LocalModels, model_id: &str) { + match models.start_install(model_id) { + Ok(handle) => { + self.installs.insert(model_id.to_string(), handle); + if let Some(row) = self.row_mut(model_id) { + row.state = ModelRowInstallState::Downloading; + } + } + Err(error) => self.fail_row(model_id, error.to_string()), + } + self.view.redraw(cx); + } + + fn update_progress_from_disk(&mut self, models: &LocalModels, model_id: &str) { + let active = self.installs.contains_key(model_id); + let state = models.install_state(model_id); + if let Some(row) = self.row_mut(model_id) { + let preserve_failure = + !active && matches!(&row.state, ModelRowInstallState::Failed(_)); + match state { + InstallState::NotInstalled { bytes_total } => { + row.bytes_done = 0; + row.bytes_total = bytes_total; + if !preserve_failure { + row.state = if active { + ModelRowInstallState::Downloading + } else { + ModelRowInstallState::NotInstalled + }; + } + } + InstallState::Partial { + bytes_done, + bytes_total, + } => { + row.bytes_done = bytes_done; + row.bytes_total = bytes_total; + if !preserve_failure { + row.state = if active { + ModelRowInstallState::Downloading + } else { + ModelRowInstallState::NotInstalled + }; + } + } + InstallState::Installed => { + row.bytes_done = row.bytes_total; + row.state = ModelRowInstallState::Installed; + } + } + } + } + + fn fail_row(&mut self, model_id: &str, error: String) { + if let Some(row) = self.row_mut(model_id) { + row.state = ModelRowInstallState::Failed(error); + } + } + + fn row_mut(&mut self, model_id: &str) -> Option<&mut ModelRowState> { + self.rows.iter_mut().find(|row| row.model_id == model_id) + } + + fn show_license(&self, cx: &mut Cx, prompt: &LicensePrompt) { + let widget = self.view.widget(cx, ids!(licence_modal)); + if let Some(mut modal) = widget.borrow_mut::() { + modal.show(cx, prompt); + }; + } + + fn sync_empty(&self, cx: &mut Cx) { + let empty = self.rows.is_empty(); + self.view.label(cx, ids!(empty)).set_visible(cx, empty); + self.view.portal_list(cx, ids!(list)).set_visible(cx, !empty); + } +} + +impl Widget for ModelInstallPanel { + fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) { + self.view.handle_event(cx, event, scope); + let Event::Actions(actions) = event else { + return; + }; + let list = self.view.portal_list(cx, ids!(list)); + for (_, item) in list.items_with_actions(actions) { + let model = actions.find_widget_action_cast::(item.widget_uid()); + if !matches!(model, ModelInstallAction::None) { + self.pending.push(PanelAction::Model(model)); + } + } + let modal_uid = self.view.widget(cx, ids!(licence_modal)).widget_uid(); + let license = actions.find_widget_action_cast::(modal_uid); + if !matches!(license, LicenseModalAction::None) { + self.pending.push(PanelAction::License(license)); + } + } + + fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep { + while let Some(item) = self.view.draw_walk(cx, scope, walk).step() { + let Some(mut list) = item.borrow_mut::() else { + continue; + }; + list.set_item_range(cx, 0, self.rows.len()); + while let Some(item_id) = list.next_visible_item(cx) { + let row_widget = list.item(cx, item_id, id!(Row)); + if let (Some(state), Some(mut row)) = ( + self.rows.get(item_id).cloned(), + row_widget.borrow_mut::(), + ) { + row.set_state(cx, state); + } + row_widget.draw_all_unscoped(cx); + } + } + DrawStep::done() + } +} + +impl ModelInstallPanelRef { + pub fn set_rows(&self, cx: &mut Cx, rows: Vec) { + if let Some(mut panel) = self.borrow_mut() { + panel.set_rows(cx, rows); + } + } + + pub fn pump(&self, cx: &mut Cx, models: &mut LocalModels) { + if let Some(mut panel) = self.borrow_mut() { + panel.pump(cx, models); + } + } +} + +fn format_mb(bytes: u64) -> String { + format!("{:.0} MB", bytes as f64 / 1_000_000.0) +} + +fn restriction_text(restriction: LicenseRestriction) -> &'static str { + match restriction { + LicenseRestriction::None => { + "Permissive weight licence. Acknowledgement is still required to clear the model." + } + LicenseRestriction::NonCommercial => { + "Non-commercial weights. Personal / research use only." + } + LicenseRestriction::Community => { + "Community licence. Read the terms before any product use." + } + LicenseRestriction::Restricted => { + "Restricted licence. Review the full terms before use." + } + } +} diff --git a/libs/ai/loader/src/formats/mod.rs b/libs/ai/loader/src/formats/mod.rs index 9fa1a5d6d..dbe5b3829 100644 --- a/libs/ai/loader/src/formats/mod.rs +++ b/libs/ai/loader/src/formats/mod.rs @@ -3,6 +3,7 @@ pub mod gguf; pub mod npy; +pub mod onnx; pub mod safetensors; pub mod torch; pub mod torch_pth; diff --git a/libs/ai/loader/src/formats/onnx.rs b/libs/ai/loader/src/formats/onnx.rs new file mode 100644 index 000000000..7921ccbf5 --- /dev/null +++ b/libs/ai/loader/src/formats/onnx.rs @@ -0,0 +1,444 @@ +//! Small, dependency-free ONNX protobuf reader. +//! +//! This intentionally implements only the protobuf messages needed by native +//! model loaders: model/graph metadata, nodes and their attributes, and tensor +//! initializers. Unknown fields are skipped, so newer ONNX producer versions +//! remain readable without pulling a protobuf runtime into every model crate. + +use std::collections::BTreeMap; +use std::fs; +use std::path::Path; + +#[derive(Clone, Debug, PartialEq)] +pub struct OnnxModel { + pub producer_name: String, + pub producer_version: String, + pub graph: OnnxGraph, +} + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct OnnxGraph { + pub name: String, + pub nodes: Vec, + pub initializers: BTreeMap, + pub inputs: Vec, + pub outputs: Vec, +} + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct OnnxNode { + pub name: String, + pub op_type: String, + pub inputs: Vec, + pub outputs: Vec, + pub attributes: BTreeMap, +} + +#[derive(Clone, Debug, PartialEq)] +pub enum OnnxAttribute { + Float(f32), + Int(i64), + String(Vec), + Tensor(OnnxTensor), + Floats(Vec), + Ints(Vec), + Strings(Vec>), +} + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct OnnxTensor { + pub name: String, + pub dims: Vec, + /// ONNX TensorProto.DataType numeric value (FLOAT is 1, INT64 is 7). + pub data_type: i32, + pub raw_data: Vec, + pub float_data: Vec, + pub int32_data: Vec, + pub int64_data: Vec, + pub double_data: Vec, + pub uint64_data: Vec, +} + +impl OnnxTensor { + pub fn element_count(&self) -> Result { + self.dims.iter().try_fold(1usize, |n, &d| { + let d = usize::try_from(d).map_err(|_| { + format!("ONNX tensor '{}' has negative dimension {d}", self.name) + })?; + n.checked_mul(d).ok_or_else(|| { + format!("ONNX tensor '{}' element count overflows usize", self.name) + }) + }) + } + + pub fn f32_values(&self) -> Result, String> { + if self.data_type != 1 { + return Err(format!( + "ONNX tensor '{}' has data_type {}, expected FLOAT (1)", + self.name, self.data_type + )); + } + let values = if !self.raw_data.is_empty() { + if self.raw_data.len() % 4 != 0 { + return Err(format!( + "ONNX tensor '{}' has {} raw bytes, not a multiple of four", + self.name, + self.raw_data.len() + )); + } + self.raw_data + .chunks_exact(4) + .map(|c| f32::from_le_bytes([c[0], c[1], c[2], c[3]])) + .collect() + } else { + self.float_data.clone() + }; + let expected = self.element_count()?; + if values.len() != expected { + return Err(format!( + "ONNX tensor '{}' has {} FLOAT values, shape {:?} requires {expected}", + self.name, + values.len(), + self.dims + )); + } + Ok(values) + } + + pub fn i64_values(&self) -> Result, String> { + if self.data_type != 7 { + return Err(format!( + "ONNX tensor '{}' has data_type {}, expected INT64 (7)", + self.name, self.data_type + )); + } + let values = if !self.raw_data.is_empty() { + if self.raw_data.len() % 8 != 0 { + return Err(format!( + "ONNX tensor '{}' has {} raw bytes, not a multiple of eight", + self.name, + self.raw_data.len() + )); + } + self.raw_data + .chunks_exact(8) + .map(|c| i64::from_le_bytes(c.try_into().expect("eight-byte chunk"))) + .collect() + } else { + self.int64_data.clone() + }; + let expected = self.element_count()?; + if values.len() != expected { + return Err(format!( + "ONNX tensor '{}' has {} INT64 values, shape {:?} requires {expected}", + self.name, + values.len(), + self.dims + )); + } + Ok(values) + } +} + +impl OnnxModel { + pub fn load(path: impl AsRef) -> Result { + let path = path.as_ref(); + let bytes = fs::read(path) + .map_err(|e| format!("read ONNX model {}: {e}", path.display()))?; + Self::parse(&bytes).map_err(|e| format!("parse ONNX model {}: {e}", path.display())) + } + + pub fn parse(bytes: &[u8]) -> Result { + let mut pb = Pb::new(bytes); + let mut producer_name = String::new(); + let mut producer_version = String::new(); + let mut graph = None; + while let Some((field, wire)) = pb.key()? { + match (field, wire) { + (2, 2) => producer_name = text(pb.bytes()?)?, + (3, 2) => producer_version = text(pb.bytes()?)?, + (7, 2) => graph = Some(parse_graph(pb.bytes()?)?), + _ => pb.skip(wire)?, + } + } + Ok(Self { + producer_name, + producer_version, + graph: graph.ok_or_else(|| "ModelProto has no graph".to_string())?, + }) + } +} + +fn parse_graph(bytes: &[u8]) -> Result { + let mut pb = Pb::new(bytes); + let mut graph = OnnxGraph::default(); + while let Some((field, wire)) = pb.key()? { + match (field, wire) { + (1, 2) => graph.nodes.push(parse_node(pb.bytes()?)?), + (2, 2) => graph.name = text(pb.bytes()?)?, + (5, 2) => { + let tensor = parse_tensor(pb.bytes()?)?; + if graph.initializers.insert(tensor.name.clone(), tensor).is_some() { + return Err("GraphProto contains duplicate initializer name".to_string()); + } + } + (11, 2) => graph.inputs.push(parse_value_info_name(pb.bytes()?)?), + (12, 2) => graph.outputs.push(parse_value_info_name(pb.bytes()?)?), + _ => pb.skip(wire)?, + } + } + Ok(graph) +} + +fn parse_value_info_name(bytes: &[u8]) -> Result { + let mut pb = Pb::new(bytes); + while let Some((field, wire)) = pb.key()? { + if (field, wire) == (1, 2) { + return text(pb.bytes()?); + } + pb.skip(wire)?; + } + Ok(String::new()) +} + +fn parse_node(bytes: &[u8]) -> Result { + let mut pb = Pb::new(bytes); + let mut node = OnnxNode::default(); + while let Some((field, wire)) = pb.key()? { + match (field, wire) { + (1, 2) => node.inputs.push(text(pb.bytes()?)?), + (2, 2) => node.outputs.push(text(pb.bytes()?)?), + (3, 2) => node.name = text(pb.bytes()?)?, + (4, 2) => node.op_type = text(pb.bytes()?)?, + (5, 2) => { + let (name, value) = parse_attribute(pb.bytes()?)?; + if let Some(value) = value { + node.attributes.insert(name, value); + } + } + _ => pb.skip(wire)?, + } + } + Ok(node) +} + +fn parse_attribute(bytes: &[u8]) -> Result<(String, Option), String> { + let mut pb = Pb::new(bytes); + let mut name = String::new(); + let mut value = None; + let mut floats = Vec::new(); + let mut ints = Vec::new(); + let mut strings = Vec::new(); + while let Some((field, wire)) = pb.key()? { + match (field, wire) { + (1, 2) => name = text(pb.bytes()?)?, + (2, 5) => value = Some(OnnxAttribute::Float(pb.fixed32_f32()?)), + (3, 0) => value = Some(OnnxAttribute::Int(pb.varint()? as i64)), + (4, 2) => value = Some(OnnxAttribute::String(pb.bytes()?.to_vec())), + (5, 2) => value = Some(OnnxAttribute::Tensor(parse_tensor(pb.bytes()?)?)), + (7, 5) => floats.push(pb.fixed32_f32()?), + (7, 2) => { + let mut packed = Pb::new(pb.bytes()?); + while !packed.done() { + floats.push(packed.fixed32_f32()?); + } + } + (8, 0) => ints.push(pb.varint()? as i64), + (8, 2) => { + let mut packed = Pb::new(pb.bytes()?); + while !packed.done() { + ints.push(packed.varint()? as i64); + } + } + (9, 2) => strings.push(pb.bytes()?.to_vec()), + _ => pb.skip(wire)?, + } + } + if value.is_none() { + value = if !floats.is_empty() { + Some(OnnxAttribute::Floats(floats)) + } else if !ints.is_empty() { + Some(OnnxAttribute::Ints(ints)) + } else if !strings.is_empty() { + Some(OnnxAttribute::Strings(strings)) + } else { + None + }; + } + Ok((name, value)) +} + +fn parse_tensor(bytes: &[u8]) -> Result { + let mut pb = Pb::new(bytes); + let mut tensor = OnnxTensor::default(); + while let Some((field, wire)) = pb.key()? { + match (field, wire) { + (1, 0) => tensor.dims.push(pb.varint()? as i64), + (1, 2) => { + let mut packed = Pb::new(pb.bytes()?); + while !packed.done() { + tensor.dims.push(packed.varint()? as i64); + } + } + (2, 0) => tensor.data_type = pb.varint()? as i32, + (4, 5) => tensor.float_data.push(pb.fixed32_f32()?), + (4, 2) => { + let mut packed = Pb::new(pb.bytes()?); + while !packed.done() { + tensor.float_data.push(packed.fixed32_f32()?); + } + } + (5, 0) => tensor.int32_data.push(pb.varint()? as i32), + (5, 2) => { + let mut packed = Pb::new(pb.bytes()?); + while !packed.done() { + tensor.int32_data.push(packed.varint()? as i32); + } + } + (7, 0) => tensor.int64_data.push(pb.varint()? as i64), + (7, 2) => { + let mut packed = Pb::new(pb.bytes()?); + while !packed.done() { + tensor.int64_data.push(packed.varint()? as i64); + } + } + (8, 2) => tensor.name = text(pb.bytes()?)?, + (9, 2) => tensor.raw_data = pb.bytes()?.to_vec(), + (10, 1) => tensor.double_data.push(pb.fixed64_f64()?), + (10, 2) => { + let mut packed = Pb::new(pb.bytes()?); + while !packed.done() { + tensor.double_data.push(packed.fixed64_f64()?); + } + } + (11, 0) => tensor.uint64_data.push(pb.varint()?), + (11, 2) => { + let mut packed = Pb::new(pb.bytes()?); + while !packed.done() { + tensor.uint64_data.push(packed.varint()?); + } + } + _ => pb.skip(wire)?, + } + } + Ok(tensor) +} + +fn text(bytes: &[u8]) -> Result { + std::str::from_utf8(bytes) + .map(str::to_owned) + .map_err(|e| format!("invalid UTF-8 in ONNX protobuf: {e}")) +} + +struct Pb<'a> { + bytes: &'a [u8], + pos: usize, +} + +impl<'a> Pb<'a> { + fn new(bytes: &'a [u8]) -> Self { + Self { bytes, pos: 0 } + } + + fn done(&self) -> bool { + self.pos == self.bytes.len() + } + + fn varint(&mut self) -> Result { + let mut value = 0u64; + for shift in (0..70).step_by(7) { + let byte = *self + .bytes + .get(self.pos) + .ok_or_else(|| "truncated protobuf varint".to_string())?; + self.pos += 1; + if shift < 64 { + value |= u64::from(byte & 0x7f) << shift; + } else if byte & 0x7e != 0 { + return Err("protobuf varint overflows u64".to_string()); + } + if byte & 0x80 == 0 { + return Ok(value); + } + } + Err("protobuf varint exceeds ten bytes".to_string()) + } + + fn key(&mut self) -> Result, String> { + if self.done() { + return Ok(None); + } + let key = self.varint()?; + if key == 0 { + return Err("protobuf field key is zero".to_string()); + } + Ok(Some((key >> 3, (key & 7) as u8))) + } + + fn bytes(&mut self) -> Result<&'a [u8], String> { + let len = usize::try_from(self.varint()?) + .map_err(|_| "protobuf length does not fit usize".to_string())?; + let end = self + .pos + .checked_add(len) + .ok_or_else(|| "protobuf length overflows usize".to_string())?; + if end > self.bytes.len() { + return Err("truncated length-delimited protobuf field".to_string()); + } + let value = &self.bytes[self.pos..end]; + self.pos = end; + Ok(value) + } + + fn fixed32_f32(&mut self) -> Result { + let bytes: [u8; 4] = self.take_fixed::<4>()?.try_into().expect("fixed width"); + Ok(f32::from_le_bytes(bytes)) + } + + fn fixed64_f64(&mut self) -> Result { + let bytes: [u8; 8] = self.take_fixed::<8>()?.try_into().expect("fixed width"); + Ok(f64::from_le_bytes(bytes)) + } + + fn take_fixed(&mut self) -> Result<&'a [u8], String> { + let end = self + .pos + .checked_add(N) + .ok_or_else(|| "protobuf fixed field overflows usize".to_string())?; + if end > self.bytes.len() { + return Err("truncated fixed-width protobuf field".to_string()); + } + let value = &self.bytes[self.pos..end]; + self.pos = end; + Ok(value) + } + + fn skip(&mut self, wire: u8) -> Result<(), String> { + match wire { + 0 => { + self.varint()?; + } + 1 => { + self.take_fixed::<8>()?; + } + 2 => { + self.bytes()?; + } + 5 => { + self.take_fixed::<4>()?; + } + _ => return Err(format!("unsupported protobuf wire type {wire}")), + } + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn rejects_truncated_messages() { + assert!(OnnxModel::parse(&[0x3a, 0x04, 0x08]).is_err()); + } +} diff --git a/libs/ai/models/beats/Cargo.toml b/libs/ai/models/beats/Cargo.toml new file mode 100644 index 000000000..7624e4708 --- /dev/null +++ b/libs/ai/models/beats/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "makepad-ai-beats" +version = "0.1.0" +edition = "2021" +description = "Native Beat This! beat/downbeat tracking on the makepad ggml graph runtime" +license = "MIT" + +[dependencies] +makepad-ai-common = { path = "../common" } +makepad-ai-loader = { path = "../../loader" } diff --git a/libs/ai/models/beats/src/config.rs b/libs/ai/models/beats/src/config.rs new file mode 100644 index 000000000..005f5139d --- /dev/null +++ b/libs/ai/models/beats/src/config.rs @@ -0,0 +1,59 @@ +//! Fixed Beat This! signal and network geometry. + +pub const SAMPLE_RATE: u32 = 22_050; +pub const N_FFT: usize = 1024; +pub const HOP_LENGTH: usize = 441; +pub const MEL_BINS: usize = 128; +pub const FFT_BINS: usize = N_FFT / 2 + 1; +pub const F_MIN: f64 = 30.0; +pub const F_MAX: f64 = 11_000.0; +pub const LOG_MULTIPLIER: f32 = 1000.0; +pub const FRAME_RATE: f64 = SAMPLE_RATE as f64 / HOP_LENGTH as f64; + +pub const CHUNK_FRAMES: usize = 1500; +pub const BORDER_FRAMES: usize = 6; +pub const CHUNK_STRIDE: usize = CHUNK_FRAMES - 2 * BORDER_FRAMES; + +pub const HEAD_DIM: usize = 32; +pub const STEM_DIM: usize = 32; +pub const STEM_BLOCKS: usize = 3; +pub const MAIN_LAYERS: usize = 6; +pub const FF_MULT: usize = 4; +pub const ROPE_THETA: f32 = 10_000.0; +pub const NORM_EPS: f32 = 1e-12; +pub const BATCH_NORM_EPS: f32 = 1e-5; + +pub const STEM_FREQS: [usize; 4] = [32, 16, 8, 4]; +pub const STEM_CHANNELS: [usize; 4] = [32, 64, 128, 256]; +pub const FRONTEND_FEATURES: usize = 256 * 4; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum ModelSize { + Final, + Small, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct BeatsConfig { + pub size: ModelSize, + pub transformer_dim: usize, +} + +impl BeatsConfig { + pub const FINAL: Self = Self { + size: ModelSize::Final, + transformer_dim: 512, + }; + pub const SMALL: Self = Self { + size: ModelSize::Small, + transformer_dim: 128, + }; + + pub fn heads(self) -> usize { + self.transformer_dim / HEAD_DIM + } + + pub fn ff_inner(self) -> usize { + self.transformer_dim * FF_MULT + } +} diff --git a/libs/ai/models/beats/src/graph.rs b/libs/ai/models/beats/src/graph.rs new file mode 100644 index 000000000..b35c2d517 --- /dev/null +++ b/libs/ai/models/beats/src/graph.rs @@ -0,0 +1,537 @@ +//! One fixed-shape Beat This! forward graph: `[1500,128]` log-mel frames to +//! `[1500,2]` beat/downbeat logits. +//! +//! The graph uses the same RMSNorm, rotary gated attention and axial +//! time/frequency batching pattern as the stems RoFormer. Convolutions are a +//! compact graph-native im2col made from strided views plus `mul_mat`; this is +//! supported by both compiled stores (the CUDA raw-graph executor does not +//! currently expose `Op::Im2col`/`Op::Conv2d`). + +use crate::config::*; +use crate::weights::{ + block_bn, block_conv, transformer_name, BeatsWeights, FINAL_NORM, FRONT_LINEAR_B, + FRONT_LINEAR_W, HEAD_B, HEAD_W, INPUT_BN_BIAS, INPUT_BN_SCALE, STEM_BN_BIAS, + STEM_BN_SCALE, STEM_CONV, +}; +use makepad_ai_common::{ + BufferUsage, Context, DiffusionError, Graph, Op, Prec, Result, TensorId, TensorType, UnaryOp, +}; + +const ACT: BufferUsage = BufferUsage::Activations; +const F32_BYTES: usize = 4; + +pub struct BeatsGraph { + pub graph: Graph, + pub mel: TensorId, + /// `[2, CHUNK_FRAMES]`, with beat (already SumHead-combined) at row 0. + pub logits: TensorId, +} + +pub fn build_graph(weights: &mut BeatsWeights) -> Result { + let config = weights.config; + let ctx = &mut weights.ctx; + let mel = ctx + .new_named_tensor( + "mel", + TensorType::F32, + 2, + &[MEL_BINS as i64, CHUNK_FRAMES as i64], + ACT, + ) + .map_err(DiffusionError::model)?; + let pos_time = positions(ctx, "position.time", CHUNK_FRAMES)?; + let pos_freq = [ + positions(ctx, "position.freq32", 32)?, + positions(ctx, "position.freq16", 16)?, + positions(ctx, "position.freq8", 8)?, + ]; + let pads = [ + zeros(ctx, "pad.stem", &[1, 1, MEL_BINS])?, + zeros(ctx, "pad.front0", &[32, 1, 32])?, + zeros(ctx, "pad.front1", &[64, 1, 16])?, + zeros(ctx, "pad.front2", &[128, 1, 8])?, + ]; + + ctx.set_no_alloc(true); + + // BatchNorm over each mel bin, then `[freq,time] -> [1,time,freq]`. + let x = affine( + ctx, + mel, + weight(ctx, INPUT_BN_SCALE)?, + weight(ctx, INPUT_BN_BIAS)?, + )?; + let x = ctx.transpose(x).map_err(DiffusionError::model)?; + let x = ctx + .cont_2d(x, CHUNK_FRAMES as i64, MEL_BINS as i64) + .map_err(DiffusionError::model)?; + let x = ctx + .reshape(x, &[1, CHUNK_FRAMES as i64, MEL_BINS as i64]) + .map_err(DiffusionError::model)?; + let x = conv2d( + ctx, + x, + weight(ctx, STEM_CONV)?, + pads[0], + 1, + MEL_BINS, + STEM_DIM, + 4, + 3, + 4, + )?; + let mut x = affine( + ctx, + x, + weight(ctx, STEM_BN_SCALE)?, + weight(ctx, STEM_BN_BIAS)?, + )?; + x = ctx + .unary(x, UnaryOp::GeluErf, ACT) + .map_err(DiffusionError::model)?; + + for block in 0..STEM_BLOCKS { + let dim = STEM_CHANNELS[block]; + let freq = STEM_FREQS[block]; + // `[channel,time,freq] -> [channel,freq,time]`: frequency sequence, + // one batch per time frame. + x = swap12_cont(ctx, x)?; + x = transformer( + ctx, + x, + pos_freq[block], + dim, + &format!("front{block}.freq"), + )?; + // Time sequence, one batch per frequency band. + x = swap12_cont(ctx, x)?; + x = transformer( + ctx, + x, + pos_time, + dim, + &format!("front{block}.time"), + )?; + x = conv2d( + ctx, + x, + weight(ctx, &block_conv(block))?, + pads[block + 1], + dim, + freq, + STEM_CHANNELS[block + 1], + 2, + 3, + 2, + )?; + x = affine( + ctx, + x, + weight(ctx, &block_bn(block, "scale"))?, + weight(ctx, &block_bn(block, "bias"))?, + )?; + x = ctx + .unary(x, UnaryOp::GeluErf, ACT) + .map_err(DiffusionError::model)?; + } + + // PyTorch `rearrange('b c f t -> b t (c f)')` flattens with frequency + // fastest inside channel. `[c,t,f] -> [f,c,t]`, make contiguous, flatten. + let x = ctx.permute(x, [1, 2, 0, 3]).map_err(DiffusionError::model)?; + let x = ctx + .cont_3d(x, 4, 256, CHUNK_FRAMES as i64) + .map_err(DiffusionError::model)?; + let x = ctx + .reshape(x, &[FRONTEND_FEATURES as i64, CHUNK_FRAMES as i64]) + .map_err(DiffusionError::model)?; + let mut x = ctx + .mul_mat(weight(ctx, FRONT_LINEAR_W)?, x, ACT) + .map_err(DiffusionError::model)?; + x = add(ctx, x, weight(ctx, FRONT_LINEAR_B)?)?; + + for layer in 0..MAIN_LAYERS { + x = transformer( + ctx, + x, + pos_time, + config.transformer_dim, + &format!("main{layer}"), + )?; + } + x = norm_scale(ctx, x, weight(ctx, FINAL_NORM)?)?; + let raw = ctx + .mul_mat(weight(ctx, HEAD_W)?, x, ACT) + .map_err(DiffusionError::model)?; + let raw = add(ctx, raw, weight(ctx, HEAD_B)?)?; + + // SumHead: beat = beat_channel + downbeat_channel; downbeat unchanged. + let beat = ctx + .view( + raw, + TensorType::F32, + &[1, CHUNK_FRAMES as i64], + &[F32_BYTES, 2 * F32_BYTES], + 0, + ) + .map_err(DiffusionError::model)?; + let downbeat = ctx + .view( + raw, + TensorType::F32, + &[1, CHUNK_FRAMES as i64], + &[F32_BYTES, 2 * F32_BYTES], + F32_BYTES, + ) + .map_err(DiffusionError::model)?; + let beat = ctx + .binary_like_a(Op::Add, beat, downbeat, ACT) + .map_err(DiffusionError::model)?; + let logits = ctx + .concat(beat, downbeat, 0, ACT) + .map_err(DiffusionError::model)?; + + ctx.set_no_alloc(false); + let mut graph = Graph::new(); + graph + .build_forward_expand(ctx, logits) + .map_err(DiffusionError::model)?; + Ok(BeatsGraph { graph, mel, logits }) +} + +#[allow(clippy::too_many_arguments)] +fn conv2d( + ctx: &mut Context, + input: TensorId, + kernel: TensorId, + zero_pad: TensorId, + in_channels: usize, + in_freq: usize, + out_channels: usize, + kernel_h: usize, + kernel_w: usize, + freq_stride: usize, +) -> Result { + let time = CHUNK_FRAMES; + let padded = ctx + .concat(zero_pad, input, 1, ACT) + .map_err(DiffusionError::model)?; + let padded = ctx + .concat(padded, zero_pad, 1, ACT) + .map_err(DiffusionError::model)?; + let padded_time = time + 2; + let out_freq = (in_freq - kernel_h) / freq_stride + 1; + let mut patches = Vec::with_capacity(kernel_h * kernel_w); + for ky in 0..kernel_h { + for kx in 0..kernel_w { + let view = ctx + .view( + padded, + TensorType::F32, + &[in_channels as i64, time as i64, out_freq as i64], + &[ + F32_BYTES, + in_channels * F32_BYTES, + in_channels * padded_time * freq_stride * F32_BYTES, + ], + (ky * in_channels * padded_time + kx * in_channels) * F32_BYTES, + ) + .map_err(DiffusionError::model)?; + let contiguous = ctx + .cont_3d( + view, + in_channels as i64, + time as i64, + out_freq as i64, + ) + .map_err(DiffusionError::model)?; + patches.push( + ctx.reshape( + contiguous, + &[in_channels as i64, (time * out_freq) as i64], + ) + .map_err(DiffusionError::model)?, + ); + } + } + let columns = concat_all(ctx, &patches, 0)?; + let output = ctx + .mul_mat(kernel, columns, ACT) + .map_err(DiffusionError::model)?; + let output = ctx + .reshape( + output, + &[out_channels as i64, time as i64, out_freq as i64], + ) + .map_err(DiffusionError::model)?; + Ok(output) +} + +fn transformer( + ctx: &mut Context, + input: TensorId, + positions: TensorId, + dim: usize, + prefix: &str, +) -> Result { + let ne = extents(ctx, input)?; + if ne[0] != dim as i64 { + return Err(DiffusionError::model(format!( + "beats transformer {prefix}: input dim {} != {dim}", + ne[0] + ))); + } + let sequence = ne[1]; + let batch = ne[2]; + let heads = dim / HEAD_DIM; + + let normalized = norm_scale( + ctx, + input, + weight(ctx, &transformer_name(prefix, "attn.gamma"))?, + )?; + let qkv = ctx + .mul_mat( + weight(ctx, &transformer_name(prefix, "attn.qkv"))?, + normalized, + ACT, + ) + .map_err(DiffusionError::model)?; + let mut parts = [0usize; 3]; + for (index, part) in parts.iter_mut().enumerate() { + let view = ctx + .view( + qkv, + TensorType::F32, + &[HEAD_DIM as i64, heads as i64, sequence, batch], + &[ + F32_BYTES, + HEAD_DIM * F32_BYTES, + dim * 3 * F32_BYTES, + dim * 3 * sequence as usize * F32_BYTES, + ], + index * dim * F32_BYTES, + ) + .map_err(DiffusionError::model)?; + *part = ctx + .cont_4d(view, HEAD_DIM as i64, heads as i64, sequence, batch) + .map_err(DiffusionError::model)?; + } + let [query, key, value] = parts; + let query = ctx + .rope(query, positions, HEAD_DIM as i32, 0, ACT) + .map_err(DiffusionError::model)?; + let key = ctx + .rope(key, positions, HEAD_DIM as i32, 0, ACT) + .map_err(DiffusionError::model)?; + let query = swap12(ctx, query)?; + let key = swap12(ctx, key)?; + let value = swap12(ctx, value)?; + let attention = ctx + .flash_attn_ext( + query, + key, + value, + None, + 1.0 / (HEAD_DIM as f32).sqrt(), + 0.0, + 0.0, + ACT, + ) + .map_err(DiffusionError::model)?; + ctx.flash_attn_ext_set_prec(attention, Prec::F32) + .map_err(DiffusionError::model)?; + + let gates = ctx + .mul_mat( + weight(ctx, &transformer_name(prefix, "attn.gates_w"))?, + normalized, + ACT, + ) + .map_err(DiffusionError::model)?; + let gates = add( + ctx, + gates, + weight(ctx, &transformer_name(prefix, "attn.gates_b"))?, + )?; + let gates = ctx + .unary(gates, UnaryOp::Sigmoid, ACT) + .map_err(DiffusionError::model)?; + let gates = ctx + .reshape(gates, &[1, heads as i64, sequence, batch]) + .map_err(DiffusionError::model)?; + let attention = ctx + .binary_like_a(Op::Mul, attention, gates, ACT) + .map_err(DiffusionError::model)?; + let attention = ctx + .reshape(attention, &[dim as i64, sequence, batch]) + .map_err(DiffusionError::model)?; + let attention = ctx + .mul_mat( + weight(ctx, &transformer_name(prefix, "attn.out"))?, + attention, + ACT, + ) + .map_err(DiffusionError::model)?; + let residual = ctx + .binary_like_a(Op::Add, input, attention, ACT) + .map_err(DiffusionError::model)?; + + let hidden = norm_scale( + ctx, + residual, + weight(ctx, &transformer_name(prefix, "ff.gamma"))?, + )?; + let hidden = ctx + .mul_mat( + weight(ctx, &transformer_name(prefix, "ff.w1"))?, + hidden, + ACT, + ) + .map_err(DiffusionError::model)?; + let hidden = add( + ctx, + hidden, + weight(ctx, &transformer_name(prefix, "ff.b1"))?, + )?; + let hidden = ctx + .unary(hidden, UnaryOp::GeluErf, ACT) + .map_err(DiffusionError::model)?; + let hidden = ctx + .mul_mat( + weight(ctx, &transformer_name(prefix, "ff.w2"))?, + hidden, + ACT, + ) + .map_err(DiffusionError::model)?; + let hidden = add( + ctx, + hidden, + weight(ctx, &transformer_name(prefix, "ff.b2"))?, + )?; + ctx.binary_like_a(Op::Add, residual, hidden, ACT) + .map_err(DiffusionError::model) +} + +fn norm_scale(ctx: &mut Context, input: TensorId, gamma: TensorId) -> Result { + let normalized = ctx + .rms_norm_eps(input, NORM_EPS, ACT) + .map_err(DiffusionError::model)?; + ctx.binary_like_a(Op::Mul, normalized, gamma, ACT) + .map_err(DiffusionError::model) +} + +fn affine( + ctx: &mut Context, + input: TensorId, + scale: TensorId, + bias: TensorId, +) -> Result { + let scaled = ctx + .binary_like_a(Op::Mul, input, scale, ACT) + .map_err(DiffusionError::model)?; + add(ctx, scaled, bias) +} + +fn add(ctx: &mut Context, input: TensorId, bias: TensorId) -> Result { + ctx.binary_like_a(Op::Add, input, bias, ACT) + .map_err(DiffusionError::model) +} + +fn swap12(ctx: &mut Context, input: TensorId) -> Result { + ctx.permute(input, [0, 2, 1, 3]) + .map_err(DiffusionError::model) +} + +fn swap12_cont(ctx: &mut Context, input: TensorId) -> Result { + let swapped = swap12(ctx, input)?; + let ne = extents(ctx, swapped)?; + ctx.cont_3d(swapped, ne[0], ne[1], ne[2]) + .map_err(DiffusionError::model) +} + +fn concat_all(ctx: &mut Context, parts: &[TensorId], axis: usize) -> Result { + let mut iter = parts.iter().copied(); + let mut output = iter + .next() + .ok_or_else(|| DiffusionError::model("beats graph: empty concat"))?; + for part in iter { + output = ctx + .concat(output, part, axis, ACT) + .map_err(DiffusionError::model)?; + } + Ok(output) +} + +fn weight(ctx: &Context, name: &str) -> Result { + ctx.get_tensor(name) + .ok_or_else(|| DiffusionError::model(format!("beats graph: missing tensor '{name}'"))) +} + +fn extents(ctx: &Context, input: TensorId) -> Result<[i64; 4]> { + Ok(ctx + .tensor(input) + .ok_or_else(|| DiffusionError::model("beats graph: dangling tensor id"))? + .ne) +} + +fn positions(ctx: &mut Context, name: &str, count: usize) -> Result { + let tensor = ctx + .new_named_tensor( + name, + TensorType::I32, + 1, + &[count as i64], + BufferUsage::Weights, + ) + .map_err(DiffusionError::model)?; + let values: Vec = (0..count as i32).collect(); + let bytes = unsafe { + std::slice::from_raw_parts(values.as_ptr().cast::(), values.len() * F32_BYTES) + }; + ctx.write_tensor_data(tensor, bytes) + .map_err(DiffusionError::model)?; + Ok(tensor) +} + +fn zeros(ctx: &mut Context, name: &str, extents: &[usize]) -> Result { + let shape: Vec = extents.iter().map(|&value| value as i64).collect(); + let tensor = ctx + .new_named_tensor( + name, + TensorType::F32, + shape.len(), + &shape, + BufferUsage::Weights, + ) + .map_err(DiffusionError::model)?; + let values = vec![0.0f32; extents.iter().product()]; + let bytes = unsafe { + std::slice::from_raw_parts(values.as_ptr().cast::(), values.len() * F32_BYTES) + }; + ctx.write_tensor_data(tensor, bytes) + .map_err(DiffusionError::model)?; + Ok(tensor) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::weights::DEFAULT_GRAPH_EXTRA_BYTES; + use std::path::Path; + + #[test] + fn small_checkpoint_builds_the_complete_graph() { + let checkpoint = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("../../../../local/models/weights/beat_this/small0.ckpt"); + if !checkpoint.is_file() { + eprintln!("beats graph build: SKIP, {} is not seeded", checkpoint.display()); + return; + } + let mut weights = + BeatsWeights::load_with_options(&checkpoint, DEFAULT_GRAPH_EXTRA_BYTES, false).unwrap(); + let graph = build_graph(&mut weights).unwrap(); + assert_eq!(weights.ctx.tensor(graph.mel).unwrap().ne, [128, 1500, 1, 1]); + assert_eq!(weights.ctx.tensor(graph.logits).unwrap().ne, [2, 1500, 1, 1]); + assert!(!graph.graph.nodes.is_empty()); + } +} diff --git a/libs/ai/models/beats/src/lib.rs b/libs/ai/models/beats/src/lib.rs new file mode 100644 index 000000000..b5c503297 --- /dev/null +++ b/libs/ai/models/beats/src/lib.rs @@ -0,0 +1,27 @@ +//! Native Rust inference for CPJKU's Beat This! beat/downbeat tracker. +//! +//! Audio preprocessing is CPU-side; the complete neural forward pass is one +//! placement-neutral ggml graph compiled by `GraphDevice::{Metal,Cuda}`. + +pub mod config; +pub mod graph; +pub mod mel; +pub mod model; +pub mod weights; + +pub use config::{FRAME_RATE, SAMPLE_RATE}; +pub use model::{BeatAnalysis, BeatsModel}; +pub use weights::{checkpoint_census, BeatsWeights, CheckpointCensus}; + +pub const MODEL_ID: &str = "beat-this"; +pub const MODEL_CHECKPOINT: &str = "final0.ckpt"; +pub const MODEL_SOURCE: &str = "https://github.com/CPJKU/beat_this"; +pub const MODEL_LICENSE: &str = "MIT"; +pub const MODEL_SHA256: &str = + "8c328b45f59d8dd3dff219253ff6a8d6482be57d0133a29140e2febbf8eb8331"; +pub const MODEL_BYTES: u64 = 81_058_141; + +pub const SMALL_MODEL_CHECKPOINT: &str = "small0.ckpt"; +pub const SMALL_MODEL_SHA256: &str = + "6074be2c4d490c5f6101fcc374a1ec72ae93456e23bb6019783b849f5dc7d47b"; +pub const SMALL_MODEL_BYTES: u64 = 8_451_101; diff --git a/libs/ai/models/beats/src/mel.rs b/libs/ai/models/beats/src/mel.rs new file mode 100644 index 000000000..8939c856b --- /dev/null +++ b/libs/ai/models/beats/src/mel.rs @@ -0,0 +1,235 @@ +//! Beat This! `LogMelSpect` front end. +//! +//! This reproduces torchaudio's configuration used by the released model: +//! periodic Hann, centered reflect padding, magnitude STFT normalized by +//! `sqrt(frame_length)`, 128 un-normalized Slaney-scale triangular filters, +//! and `ln(1 + 1000*x)`. Output is frame-major `[time, mel]`. + +use crate::config::*; +use std::f64::consts::PI; + +pub struct LogMelSpect { + window: Vec, + filterbank: Vec, +} + +impl Default for LogMelSpect { + fn default() -> Self { + Self::new() + } +} + +impl LogMelSpect { + pub fn new() -> Self { + let window = (0..N_FFT) + .map(|i| 0.5 - 0.5 * (2.0 * PI * i as f64 / N_FFT as f64).cos()) + .collect(); + Self { + window, + filterbank: mel_filterbank(), + } + } + + /// `torch.stft(center=true)` frame count after `n_fft/2` padding at both + /// ends: `1 + floor(samples / hop)`. + pub fn frame_count(samples: usize) -> usize { + 1 + samples / HOP_LENGTH + } + + pub fn compute(&self, samples: &[f32]) -> (Vec, usize) { + if samples.is_empty() { + return (Vec::new(), 0); + } + let frames = Self::frame_count(samples.len()); + let mut output = vec![0.0f32; frames * MEL_BINS]; + let mut re = vec![0.0f64; N_FFT]; + let mut im = vec![0.0f64; N_FFT]; + let mut magnitude = vec![0.0f64; FFT_BINS]; + let pad = (N_FFT / 2) as isize; + let norm = (N_FFT as f64).sqrt(); + + for frame in 0..frames { + let start = (frame * HOP_LENGTH) as isize - pad; + for i in 0..N_FFT { + let at = reflect_index(start + i as isize, samples.len()); + re[i] = samples[at] as f64 * self.window[i]; + } + im.fill(0.0); + fft_radix2(&mut re, &mut im); + for bin in 0..FFT_BINS { + magnitude[bin] = (re[bin] * re[bin] + im[bin] * im[bin]).sqrt() / norm; + } + for mel in 0..MEL_BINS { + let weights = &self.filterbank[mel * FFT_BINS..(mel + 1) * FFT_BINS]; + let value = weights + .iter() + .zip(&magnitude) + .map(|(&weight, &mag)| weight as f64 * mag) + .sum::(); + output[frame * MEL_BINS + mel] = + (1.0 + LOG_MULTIPLIER as f64 * value).ln() as f32; + } + } + (output, frames) + } + + pub fn filterbank(&self) -> &[f32] { + &self.filterbank + } +} + +#[inline] +fn reflect_index(index: isize, len: usize) -> usize { + if len == 1 { + return 0; + } + let period = 2 * (len as isize - 1); + let mut folded = index % period; + if folded < 0 { + folded += period; + } + if folded >= len as isize { + folded = period - folded; + } + folded as usize +} + +fn hz_to_mel(hz: f64) -> f64 { + const F_SP: f64 = 200.0 / 3.0; + const MIN_LOG_HZ: f64 = 1000.0; + const MIN_LOG_MEL: f64 = MIN_LOG_HZ / F_SP; + if hz >= MIN_LOG_HZ { + MIN_LOG_MEL + (hz / MIN_LOG_HZ).ln() / (6.4f64.ln() / 27.0) + } else { + hz / F_SP + } +} + +fn mel_to_hz(mel: f64) -> f64 { + const F_SP: f64 = 200.0 / 3.0; + const MIN_LOG_HZ: f64 = 1000.0; + const MIN_LOG_MEL: f64 = MIN_LOG_HZ / F_SP; + if mel >= MIN_LOG_MEL { + MIN_LOG_HZ * ((6.4f64.ln() / 27.0) * (mel - MIN_LOG_MEL)).exp() + } else { + F_SP * mel + } +} + +/// Torchaudio `melscale_fbanks(..., norm=None, mel_scale="slaney")`. +fn mel_filterbank() -> Vec { + let fft_freqs: Vec = (0..FFT_BINS) + .map(|bin| bin as f64 * SAMPLE_RATE as f64 / N_FFT as f64) + .collect(); + let mel_min = hz_to_mel(F_MIN); + let mel_max = hz_to_mel(F_MAX); + let edges: Vec = (0..MEL_BINS + 2) + .map(|i| { + mel_to_hz(mel_min + (mel_max - mel_min) * i as f64 / (MEL_BINS + 1) as f64) + }) + .collect(); + let mut bank = vec![0.0f32; MEL_BINS * FFT_BINS]; + for mel in 0..MEL_BINS { + let lower_span = edges[mel + 1] - edges[mel]; + let upper_span = edges[mel + 2] - edges[mel + 1]; + for (bin, &frequency) in fft_freqs.iter().enumerate() { + let lower = (frequency - edges[mel]) / lower_span; + let upper = (edges[mel + 2] - frequency) / upper_span; + bank[mel * FFT_BINS + bin] = lower.min(upper).max(0.0) as f32; + } + } + bank +} + +fn fft_radix2(re: &mut [f64], im: &mut [f64]) { + let n = re.len(); + debug_assert_eq!(n, im.len()); + debug_assert!(n.is_power_of_two()); + let mut reverse = 0usize; + for index in 0..n { + if index < reverse { + re.swap(index, reverse); + im.swap(index, reverse); + } + let mut bit = n >> 1; + while reverse & bit != 0 { + reverse ^= bit; + bit >>= 1; + } + reverse |= bit; + } + let mut span = 2usize; + while span <= n { + let angle = -2.0 * PI / span as f64; + let (step_im, step_re) = angle.sin_cos(); + for start in (0..n).step_by(span) { + let (mut tw_re, mut tw_im) = (1.0f64, 0.0f64); + for offset in 0..span / 2 { + let lo = start + offset; + let hi = lo + span / 2; + let mixed_re = re[hi] * tw_re - im[hi] * tw_im; + let mixed_im = re[hi] * tw_im + im[hi] * tw_re; + let keep_re = re[lo]; + let keep_im = im[lo]; + re[lo] = keep_re + mixed_re; + im[lo] = keep_im + mixed_im; + re[hi] = keep_re - mixed_re; + im[hi] = keep_im - mixed_im; + let next_re = tw_re * step_re - tw_im * step_im; + tw_im = tw_re * step_im + tw_im * step_re; + tw_re = next_re; + } + } + span <<= 1; + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn frame_count_matches_centered_torch_geometry() { + assert_eq!(LogMelSpect::frame_count(22_050), 51); + assert_eq!(LogMelSpect::frame_count(441 * 1500), 1501); + assert_eq!(LogMelSpect::frame_count(441 * 90), 91); + } + + #[test] + fn synthetic_sine_lands_in_the_expected_mel_region() { + let seconds = 2usize; + let frequency = 440.0f64; + let signal: Vec = (0..SAMPLE_RATE as usize * seconds) + .map(|sample| { + (2.0 * PI * frequency * sample as f64 / SAMPLE_RATE as f64).sin() as f32 + }) + .collect(); + let front = LogMelSpect::new(); + let (mel, frames) = front.compute(&signal); + assert_eq!(frames, 101); + let middle = &mel[(frames / 2) * MEL_BINS..(frames / 2 + 1) * MEL_BINS]; + let peak = middle + .iter() + .enumerate() + .max_by(|a, b| a.1.partial_cmp(b.1).unwrap()) + .unwrap() + .0; + let mel_min = hz_to_mel(F_MIN); + let mel_max = hz_to_mel(F_MAX); + let center_hz = mel_to_hz( + mel_min + (mel_max - mel_min) * (peak + 1) as f64 / (MEL_BINS + 1) as f64, + ); + assert!( + (400.0..=500.0).contains(¢er_hz), + "440 Hz peak mapped to mel {peak} centered at {center_hz:.1} Hz" + ); + assert!(middle[peak].is_finite() && middle[peak] > 0.0); + } + + #[test] + fn silence_is_exactly_zero_after_log1p() { + let signal = vec![0.0f32; SAMPLE_RATE as usize]; + let (mel, _) = LogMelSpect::new().compute(&signal); + assert!(mel.iter().all(|&value| value == 0.0)); + } +} diff --git a/libs/ai/models/beats/src/model.rs b/libs/ai/models/beats/src/model.rs new file mode 100644 index 000000000..32260ad3d --- /dev/null +++ b/libs/ai/models/beats/src/model.rs @@ -0,0 +1,412 @@ +//! Model ownership, reference chunk stitching, and minimal postprocessing. + +use crate::config::*; +use crate::graph::{build_graph, BeatsGraph}; +use crate::mel::LogMelSpect; +use crate::weights::{BeatsWeights, DEFAULT_GRAPH_EXTRA_BYTES}; +use makepad_ai_common::backend::{ + BufferStorageMode, DeviceGraphSession, DeviceRuntime, GraphDevice, +}; +use makepad_ai_common::{DiffusionError, Result}; +use std::cmp::Ordering; +use std::path::Path; + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct BeatAnalysis { + pub beats_secs: Vec, + pub downbeats_secs: Vec, + pub bpm: f64, + pub confidence: f32, + pub frame_rate: f64, + pub beat_prob: Vec, + pub downbeat_prob: Vec, +} + +pub struct BeatsModel { + weights: BeatsWeights, + graph: BeatsGraph, + session: DeviceGraphSession, + mel_frontend: LogMelSpect, + chunk_mel: Vec, +} + +impl BeatsModel { + pub fn load(checkpoint: impl AsRef) -> Result { + Self::load_with_runtime(checkpoint, DeviceRuntime::new()?) + } + + pub fn load_with_runtime( + checkpoint: impl AsRef, + runtime: DeviceRuntime, + ) -> Result { + let f16 = match runtime.device() { + GraphDevice::Metal => crate::weights::f16_weights_enabled(), + GraphDevice::Cuda => crate::weights::f16_weights_requested(), + }; + let mut weights = + BeatsWeights::load_with_options(checkpoint, DEFAULT_GRAPH_EXTRA_BYTES, f16)?; + let graph = build_graph(&mut weights)?; + let session = runtime.compile_graph( + &weights.ctx, + &graph.graph, + &[graph.logits], + BufferStorageMode::Shared, + BufferStorageMode::Shared, + )?; + Ok(Self { + weights, + graph, + session, + mel_frontend: LogMelSpect::new(), + chunk_mel: vec![0.0; CHUNK_FRAMES * MEL_BINS], + }) + } + + pub fn checkpoint_path(&self) -> &Path { + &self.weights.path + } + + pub fn analyze(&mut self, mono_22k: &[f32]) -> Result { + self.analyze_with_progress(mono_22k, &mut |_, _| Ok(())) + } + + /// As [`Self::analyze`], with one cancellation/progress boundary before + /// inference and after every chunk. + pub fn analyze_with_progress( + &mut self, + mono_22k: &[f32], + progress: &mut dyn FnMut(usize, usize) -> Result<()>, + ) -> Result { + if mono_22k.is_empty() { + return Ok(BeatAnalysis { + frame_rate: FRAME_RATE, + ..BeatAnalysis::default() + }); + } + let (mel, frames) = self.mel_frontend.compute(mono_22k); + let starts = chunk_starts(frames); + let total_chunks = starts.len(); + progress(0, total_chunks)?; + let mut beat_logits = vec![-1000.0f32; frames]; + let mut downbeat_logits = vec![-1000.0f32; frames]; + + for (chunk_index, &start) in starts.iter().enumerate() { + self.chunk_mel.fill(0.0); + for local in 0..CHUNK_FRAMES { + let global = start + local as isize; + if global >= 0 && (global as usize) < frames { + let source = global as usize * MEL_BINS; + let destination = local * MEL_BINS; + self.chunk_mel[destination..destination + MEL_BINS] + .copy_from_slice(&mel[source..source + MEL_BINS]); + } + } + let execution = self.session.execute( + &self.weights.ctx, + &[(self.graph.mel, as_bytes(&self.chunk_mel))], + &[self.graph.logits], + )?; + let bytes = execution.outputs.get(&self.graph.logits).ok_or_else(|| { + DiffusionError::model("beats graph returned no logits tensor") + })?; + if bytes.len() != CHUNK_FRAMES * 2 * 4 { + return Err(DiffusionError::model(format!( + "beats graph returned {} logit bytes, expected {}", + bytes.len(), + CHUNK_FRAMES * 2 * 4 + ))); + } + + // Forward order + write-if-empty is reference `keep_first`. + for local in BORDER_FRAMES..CHUNK_FRAMES - BORDER_FRAMES { + let global = start + local as isize; + if global < 0 || global as usize >= frames { + continue; + } + let global = global as usize; + if beat_logits[global] != -1000.0 { + continue; + } + beat_logits[global] = read_f32(bytes, local * 2)?; + downbeat_logits[global] = read_f32(bytes, local * 2 + 1)?; + } + progress(chunk_index + 1, total_chunks)?; + } + + let beat_prob: Vec = beat_logits.iter().copied().map(sigmoid).collect(); + let downbeat_prob: Vec = downbeat_logits.iter().copied().map(sigmoid).collect(); + Ok(postprocess(beat_prob, downbeat_prob)) + } +} + +pub fn chunk_starts(frames: usize) -> Vec { + if frames == 0 { + return Vec::new(); + } + let mut starts = Vec::new(); + let mut start = -(BORDER_FRAMES as isize); + let stop = frames as isize - BORDER_FRAMES as isize; + while start < stop { + starts.push(start); + start += CHUNK_STRIDE as isize; + } + if frames > CHUNK_STRIDE { + *starts.last_mut().unwrap() = frames as isize - (CHUNK_FRAMES - BORDER_FRAMES) as isize; + } + starts +} + +pub fn postprocess(beat_prob: Vec, downbeat_prob: Vec) -> BeatAnalysis { + let beat_peaks = local_peaks(&beat_prob); + let downbeat_peaks = local_peaks(&downbeat_prob); + let beat_frames = deduplicate_adjacent(&beat_peaks); + let mut downbeat_frames = deduplicate_adjacent(&downbeat_peaks); + + if !beat_frames.is_empty() { + for frame in &mut downbeat_frames { + *frame = beat_frames + .iter() + .copied() + .min_by(|a, b| { + (a - *frame) + .abs() + .partial_cmp(&(b - *frame).abs()) + .unwrap_or(Ordering::Equal) + }) + .unwrap(); + } + downbeat_frames.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)); + downbeat_frames.dedup_by(|a, b| *a == *b); + } + + let beats_secs: Vec = beat_frames.iter().map(|frame| frame / FRAME_RATE).collect(); + let downbeats_secs: Vec = downbeat_frames + .iter() + .map(|frame| frame / FRAME_RATE) + .collect(); + let bpm = estimate_bpm(&beats_secs); + let confidence = if beat_frames.is_empty() { + 0.0 + } else { + beat_frames + .iter() + .map(|frame| { + let index = frame.round().clamp(0.0, beat_prob.len().saturating_sub(1) as f64); + beat_prob[index as usize] + }) + .sum::() + / beat_frames.len() as f32 + }; + BeatAnalysis { + beats_secs, + downbeats_secs, + bpm, + confidence, + frame_rate: FRAME_RATE, + beat_prob, + downbeat_prob, + } +} + +fn local_peaks(probability: &[f32]) -> Vec { + let mut peaks = Vec::new(); + for (frame, &value) in probability.iter().enumerate() { + if value <= 0.5 { + continue; + } + let from = frame.saturating_sub(3); + let to = (frame + 3).min(probability.len().saturating_sub(1)); + if probability[from..=to] + .iter() + .all(|&candidate| value >= candidate) + { + peaks.push(frame); + } + } + peaks +} + +fn deduplicate_adjacent(peaks: &[usize]) -> Vec { + let Some((&first, rest)) = peaks.split_first() else { + return Vec::new(); + }; + let mut result = Vec::new(); + let mut mean = first as f64; + let mut previous = first; + let mut count = 1usize; + for &peak in rest { + if peak - previous <= 1 { + count += 1; + mean += (peak as f64 - mean) / count as f64; + } else { + result.push(mean); + mean = peak as f64; + count = 1; + } + previous = peak; + } + result.push(mean); + result +} + +fn estimate_bpm(beats: &[f64]) -> f64 { + if beats.len() < 2 { + return 0.0; + } + let mut intervals: Vec = beats.windows(2).map(|pair| pair[1] - pair[0]).collect(); + intervals.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)); + let middle = intervals.len() / 2; + let median = if intervals.len() % 2 == 0 { + (intervals[middle - 1] + intervals[middle]) * 0.5 + } else { + intervals[middle] + }; + if median > 0.0 { + 60.0 / median + } else { + 0.0 + } +} + +fn sigmoid(value: f32) -> f32 { + if value >= 0.0 { + 1.0 / (1.0 + (-value).exp()) + } else { + let exponential = value.exp(); + exponential / (1.0 + exponential) + } +} + +fn read_f32(bytes: &[u8], index: usize) -> Result { + let at = index + .checked_mul(4) + .ok_or_else(|| DiffusionError::model("beats logit index overflow"))?; + let value = bytes + .get(at..at + 4) + .ok_or_else(|| DiffusionError::model("beats logit output is truncated"))?; + Ok(f32::from_le_bytes([value[0], value[1], value[2], value[3]])) +} + +fn as_bytes(values: &[f32]) -> &[u8] { + unsafe { std::slice::from_raw_parts(values.as_ptr().cast(), values.len() * 4) } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::f64::consts::PI; + use std::path::{Path, PathBuf}; + + const WEIGHTS: &str = concat!( + env!("CARGO_MANIFEST_DIR"), + "/../../../../local/models/weights/beat_this/final0.ckpt" + ); + + fn checkpoint() -> PathBuf { + Path::new(WEIGHTS).to_path_buf() + } + + fn click_track(seconds: usize, bpm: f64) -> Vec { + let mut audio = vec![0.0f32; seconds * SAMPLE_RATE as usize]; + let beat_samples = (60.0 / bpm * SAMPLE_RATE as f64).round() as usize; + for (beat, at) in (0..audio.len()).step_by(beat_samples).enumerate() { + let amplitude = if beat % 4 == 0 { 1.0 } else { 0.55 }; + for offset in 0..220usize.min(audio.len() - at) { + let envelope = (-(offset as f64) / 45.0).exp(); + audio[at + offset] += + (amplitude * envelope * (2.0 * PI * 1000.0 * offset as f64 / SAMPLE_RATE as f64).sin()) as f32; + } + } + audio + } + + #[test] + fn chunk_starts_match_reference_shifted_tail() { + assert_eq!(chunk_starts(1000), vec![-6]); + assert_eq!(chunk_starts(1501), vec![-6, 7]); + assert_eq!(chunk_starts(4501), vec![-6, 1482, 2970, 3007]); + } + + #[test] + fn minimal_postprocessor_snaps_downbeats_and_estimates_bpm() { + let mut beat = vec![0.0f32; 501]; + let mut downbeat = vec![0.0f32; 501]; + for frame in (0..=500).step_by(25) { + beat[frame] = 0.9; + } + for frame in (1..=500).step_by(100) { + downbeat[frame] = 0.8; + } + let analysis = postprocess(beat, downbeat); + assert!((analysis.bpm - 120.0).abs() < 1e-9); + assert!(analysis + .downbeats_secs + .iter() + .all(|time| analysis.beats_secs.contains(time))); + assert_eq!(analysis.frame_rate, 50.0); + } + + #[test] + fn silence_probabilities_produce_no_events() { + let analysis = postprocess(vec![0.5; 100], vec![0.5; 100]); + assert!(analysis.beats_secs.is_empty()); + assert!(analysis.downbeats_secs.is_empty()); + assert_eq!(analysis.bpm, 0.0); + assert_eq!(analysis.confidence, 0.0); + } + + #[test] + #[ignore = "requires seeded final0.ckpt and Metal/CUDA graph execution"] + fn synthetic_120_bpm_click_track_tracks_beats_and_downbeats() { + let expected: Vec = (0..40).map(|beat| beat as f64 * 0.5).collect(); + let analysis = BeatsModel::load(checkpoint()) + .unwrap() + .analyze(&click_track(20, 120.0)) + .unwrap(); + let matched = expected + .iter() + .filter(|&&time| { + analysis + .beats_secs + .iter() + .any(|beat| (beat - time).abs() <= 0.03) + }) + .count(); + assert!(matched >= expected.len() * 3 / 4, "matched {matched}/{}", expected.len()); + assert!((analysis.bpm - 120.0).abs() <= 1.0); + let downbeats: Vec = expected.iter().step_by(4).copied().collect(); + let precise = analysis + .downbeats_secs + .iter() + .filter(|&&time| downbeats.iter().any(|want| (time - want).abs() <= 0.03)) + .count(); + assert!(analysis.downbeats_secs.is_empty() || precise * 4 >= analysis.downbeats_secs.len() * 3); + } + + #[test] + #[ignore = "requires seeded final0.ckpt and Metal/CUDA graph execution"] + fn model_silence_has_no_beats() { + let analysis = BeatsModel::load(checkpoint()) + .unwrap() + .analyze(&vec![0.0; SAMPLE_RATE as usize * 20]) + .unwrap(); + assert!(analysis.beats_secs.is_empty()); + assert!(analysis.downbeats_secs.is_empty()); + } + + #[test] + #[ignore = "requires seeded final0.ckpt and Metal/CUDA graph execution"] + fn ninety_seconds_is_continuous_across_chunk_seams() { + let analysis = BeatsModel::load(checkpoint()) + .unwrap() + .analyze(&click_track(90, 120.0)) + .unwrap(); + assert!(analysis + .beats_secs + .windows(2) + .all(|pair| pair[1] - pair[0] > 0.03 && pair[1] - pair[0] < 0.8)); + for seam in [1488.0 / 50.0, 2976.0 / 50.0] { + assert!(analysis.beats_secs.iter().any(|beat| (beat - seam).abs() < 0.55)); + } + } +} diff --git a/libs/ai/models/beats/src/weights.rs b/libs/ai/models/beats/src/weights.rs new file mode 100644 index 000000000..83c2ff54b --- /dev/null +++ b/libs/ai/models/beats/src/weights.rs @@ -0,0 +1,660 @@ +//! Strict Beat This! Lightning-checkpoint loader. +//! +//! The upstream `.ckpt` is read directly. A complete name/shape census runs +//! before allocation; inference never accepts a partial or architecture-mixed +//! state dict. Torch linear dimensions are re-declared in ggml `[in,out]` +//! order, BatchNorm is folded into affine scale/bias, and convolution kernels +//! are reordered once for the graph's compact manual-im2col layout. + +use crate::config::*; +use makepad_ai_common::quant::f32_to_f16_rn; +use makepad_ai_common::{ + ggml_pad, BufferUsage, Context, DiffusionError, InitParams, Result, Tensor, TensorDesc, + TensorId, TensorLayout, TensorType, GGML_MEM_ALIGN, +}; +use makepad_ai_loader::formats::torch_pth::PthStateDict; +use std::collections::{BTreeMap, BTreeSet}; +use std::path::{Path, PathBuf}; + +pub const DEFAULT_GRAPH_EXTRA_BYTES: usize = 16 << 20; + +pub fn f16_weights_enabled() -> bool { + !matches!( + std::env::var("MAKEPAD_BEATS_F16").as_deref(), + Ok("0") | Ok("false") + ) +} + +pub fn f16_weights_requested() -> bool { + matches!( + std::env::var("MAKEPAD_BEATS_F16").as_deref(), + Ok("1") | Ok("true") + ) +} + +#[derive(Clone, Debug)] +pub struct CheckpointCensus { + pub config: BeatsConfig, + pub tensors: BTreeMap>, +} + +pub fn checkpoint_census(path: impl AsRef) -> Result { + let path = path.as_ref(); + let state = PthStateDict::load(path).map_err(|error| { + DiffusionError::model(format!("beats checkpoint {}: {error}", path.display())) + })?; + validate_census(&state) +} + +pub struct BeatsWeights { + pub ctx: Context, + pub ids: BTreeMap, + pub path: PathBuf, + pub config: BeatsConfig, +} + +impl BeatsWeights { + pub fn load(path: impl AsRef) -> Result { + Self::load_with_options(path, DEFAULT_GRAPH_EXTRA_BYTES, f16_weights_enabled()) + } + + pub fn load_with_options( + path: impl AsRef, + extra_bytes: usize, + f16: bool, + ) -> Result { + let path = path.as_ref().to_path_buf(); + let mut state = PthStateDict::load(&path).map_err(|error| { + DiffusionError::model(format!("beats checkpoint {}: {error}", path.display())) + })?; + let census = validate_census(&state)?; + let plan = weight_plan(census.config); + let total = plan_total_bytes(&plan, f16, extra_bytes)?; + let mut ctx = Context::new(InitParams { + mem_size: total, + mem_buffer: None, + no_alloc: false, + }); + let mut ids = BTreeMap::new(); + for item in &plan { + let ty = item.dtype(f16); + let id = ctx + .new_named_tensor( + item.name.clone(), + ty, + item.extents.len(), + &item.extents, + BufferUsage::Weights, + ) + .map_err(DiffusionError::model)?; + let values = item.source.gather(&mut state)?; + if values.len() != item.elements() { + return Err(DiffusionError::model(format!( + "beats weight '{}' expected {} floats, checkpoint produced {}", + item.name, + item.elements(), + values.len() + ))); + } + if ty == TensorType::F16 { + let half: Vec = values.into_iter().map(f32_to_f16_rn).collect(); + ctx.write_tensor_data(id, bytes_u16(&half)) + .map_err(DiffusionError::model)?; + } else { + ctx.write_tensor_data(id, bytes_f32(&values)) + .map_err(DiffusionError::model)?; + } + ids.insert(item.name.clone(), id); + } + Ok(Self { + ctx, + ids, + path, + config: census.config, + }) + } +} + +fn validate_census(state: &PthStateDict) -> Result { + let linear_shape = state + .shape("model.frontend.linear.weight") + .map_err(|error| DiffusionError::model(format!("beats checkpoint: {error}")))?; + let config = match linear_shape.as_slice() { + [512, FRONTEND_FEATURES] => BeatsConfig::FINAL, + [128, FRONTEND_FEATURES] => BeatsConfig::SMALL, + other => { + return Err(DiffusionError::model(format!( + "beats checkpoint has unsupported frontend.linear.weight shape {other:?}" + ))) + } + }; + let expected = expected_census(config); + let actual_names: BTreeSet = state.names().cloned().collect(); + let expected_names: BTreeSet = expected.keys().cloned().collect(); + let missing: Vec<_> = expected_names.difference(&actual_names).cloned().collect(); + let unexpected: Vec<_> = actual_names.difference(&expected_names).cloned().collect(); + if !missing.is_empty() || !unexpected.is_empty() { + return Err(DiffusionError::model(format!( + "beats checkpoint tensor census failed: missing={missing:?}, unexpected={unexpected:?}" + ))); + } + for (name, wanted) in &expected { + let got = state + .shape(name) + .map_err(|error| DiffusionError::model(format!("beats checkpoint: {error}")))?; + if &got != wanted { + return Err(DiffusionError::model(format!( + "beats checkpoint tensor '{name}' has shape {got:?}, expected {wanted:?}" + ))); + } + } + Ok(CheckpointCensus { + config, + tensors: expected, + }) +} + +fn expected_census(config: BeatsConfig) -> BTreeMap> { + fn add(out: &mut BTreeMap>, name: String, shape: &[usize]) { + out.insert(name, shape.to_vec()); + } + fn batch_norm( + out: &mut BTreeMap>, + prefix: &str, + channels: usize, + ) { + for part in ["weight", "bias", "running_mean", "running_var"] { + add(out, format!("{prefix}.{part}"), &[channels]); + } + add(out, format!("{prefix}.num_batches_tracked"), &[]); + } + let mut out = BTreeMap::new(); + batch_norm(&mut out, "model.frontend.stem.bn1d", MEL_BINS); + add( + &mut out, + "model.frontend.stem.conv2d.weight".into(), + &[STEM_DIM, 1, 4, 3], + ); + batch_norm(&mut out, "model.frontend.stem.bn2d", STEM_DIM); + + for block in 0..STEM_BLOCKS { + let dim = STEM_CHANNELS[block]; + let next = STEM_CHANNELS[block + 1]; + let root = format!("model.frontend.blocks.{block}"); + for (attn_tag, ff_tag) in [("attnF", "ffF"), ("attnT", "ffT")] { + let attn = format!("{root}.partial.{attn_tag}"); + let heads = dim / HEAD_DIM; + add(&mut out, format!("{attn}.norm.gamma"), &[dim]); + add(&mut out, format!("{attn}.to_qkv.weight"), &[dim * 3, dim]); + add(&mut out, format!("{attn}.to_gates.weight"), &[heads, dim]); + add(&mut out, format!("{attn}.to_gates.bias"), &[heads]); + add(&mut out, format!("{attn}.to_out.0.weight"), &[dim, dim]); + add(&mut out, format!("{attn}.rotary_embed.freqs"), &[HEAD_DIM / 2]); + let ff = format!("{root}.partial.{ff_tag}.net"); + add(&mut out, format!("{ff}.0.gamma"), &[dim]); + add(&mut out, format!("{ff}.1.weight"), &[dim * FF_MULT, dim]); + add(&mut out, format!("{ff}.1.bias"), &[dim * FF_MULT]); + add(&mut out, format!("{ff}.4.weight"), &[dim, dim * FF_MULT]); + add(&mut out, format!("{ff}.4.bias"), &[dim]); + } + add(&mut out, format!("{root}.conv2d.weight"), &[next, dim, 2, 3]); + batch_norm(&mut out, &format!("{root}.norm"), next); + } + + add( + &mut out, + "model.frontend.linear.weight".into(), + &[config.transformer_dim, FRONTEND_FEATURES], + ); + add( + &mut out, + "model.frontend.linear.bias".into(), + &[config.transformer_dim], + ); + for layer in 0..MAIN_LAYERS { + let dim = config.transformer_dim; + let heads = config.heads(); + let root = format!("model.transformer_blocks.layers.{layer}"); + add(&mut out, format!("{root}.0.norm.gamma"), &[dim]); + add(&mut out, format!("{root}.0.to_qkv.weight"), &[dim * 3, dim]); + add(&mut out, format!("{root}.0.to_gates.weight"), &[heads, dim]); + add(&mut out, format!("{root}.0.to_gates.bias"), &[heads]); + add(&mut out, format!("{root}.0.to_out.0.weight"), &[dim, dim]); + add(&mut out, format!("{root}.0.rotary_embed.freqs"), &[HEAD_DIM / 2]); + add(&mut out, format!("{root}.1.net.0.gamma"), &[dim]); + add(&mut out, format!("{root}.1.net.1.weight"), &[dim * FF_MULT, dim]); + add(&mut out, format!("{root}.1.net.1.bias"), &[dim * FF_MULT]); + add(&mut out, format!("{root}.1.net.4.weight"), &[dim, dim * FF_MULT]); + add(&mut out, format!("{root}.1.net.4.bias"), &[dim]); + } + add( + &mut out, + "model.transformer_blocks.norm.gamma".into(), + &[config.transformer_dim], + ); + add( + &mut out, + "model.task_heads.beat_downbeat_lin.weight".into(), + &[2, config.transformer_dim], + ); + add( + &mut out, + "model.task_heads.beat_downbeat_lin.bias".into(), + &[2], + ); + out +} + +#[derive(Clone, Debug)] +enum Source { + Whole(String), + BatchNorm { prefix: String, channels: usize, bias: bool }, + Conv { + name: String, + out_channels: usize, + in_channels: usize, + kernel_h: usize, + kernel_w: usize, + }, +} + +impl Source { + fn gather(&self, state: &mut PthStateDict) -> Result> { + match self { + Source::Whole(name) => read(state, name), + Source::BatchNorm { + prefix, + channels, + bias, + } => { + let gamma = read(state, &format!("{prefix}.weight"))?; + let beta = read(state, &format!("{prefix}.bias"))?; + let mean = read(state, &format!("{prefix}.running_mean"))?; + let variance = read(state, &format!("{prefix}.running_var"))?; + let mut out = Vec::with_capacity(*channels); + for channel in 0..*channels { + let scale = gamma[channel] / (variance[channel] + BATCH_NORM_EPS).sqrt(); + out.push(if *bias { + beta[channel] - mean[channel] * scale + } else { + scale + }); + } + Ok(out) + } + Source::Conv { + name, + out_channels, + in_channels, + kernel_h, + kernel_w, + } => { + let source = read(state, name)?; + let kernel = in_channels * kernel_h * kernel_w; + let mut out = Vec::with_capacity(source.len()); + // Torch is [out,in,ky,kx]. The graph forms patches in + // [ky,kx,in] order (in fastest), cutting patch nodes from + // in*kh*kw to kh*kw. Reorder once at load. + for oc in 0..*out_channels { + for ky in 0..*kernel_h { + for kx in 0..*kernel_w { + for ic in 0..*in_channels { + let at = oc * kernel + + ic * kernel_h * kernel_w + + ky * kernel_w + + kx; + out.push(source[at]); + } + } + } + } + Ok(out) + } + } + } +} + +fn read(state: &mut PthStateDict, name: &str) -> Result> { + state.f32(name).map_err(|error| { + DiffusionError::model(format!("beats checkpoint tensor '{name}': {error}")) + }) +} + +#[derive(Clone, Debug)] +struct PlanItem { + name: String, + extents: Vec, + source: Source, + matmul: bool, +} + +impl PlanItem { + fn elements(&self) -> usize { + self.extents.iter().product::() as usize + } + + fn dtype(&self, f16: bool) -> TensorType { + if f16 && self.matmul { + TensorType::F16 + } else { + TensorType::F32 + } + } +} + +fn item(name: impl Into, extents: &[usize], source: Source) -> PlanItem { + PlanItem { + name: name.into(), + extents: extents.iter().map(|&value| value as i64).collect(), + source, + matmul: false, + } +} + +fn mat(name: impl Into, extents: &[usize], source: Source) -> PlanItem { + let mut item = item(name, extents, source); + item.matmul = true; + item +} + +pub(crate) const INPUT_BN_SCALE: &str = "stem.input_bn.scale"; +pub(crate) const INPUT_BN_BIAS: &str = "stem.input_bn.bias"; +pub(crate) const STEM_CONV: &str = "stem.conv"; +pub(crate) const STEM_BN_SCALE: &str = "stem.bn.scale"; +pub(crate) const STEM_BN_BIAS: &str = "stem.bn.bias"; +pub(crate) const FRONT_LINEAR_W: &str = "frontend.linear.weight"; +pub(crate) const FRONT_LINEAR_B: &str = "frontend.linear.bias"; +pub(crate) const FINAL_NORM: &str = "main.final_norm.gamma"; +pub(crate) const HEAD_W: &str = "head.weight"; +pub(crate) const HEAD_B: &str = "head.bias"; + +pub(crate) fn block_conv(block: usize) -> String { + format!("front{block}.conv") +} +pub(crate) fn block_bn(block: usize, part: &str) -> String { + format!("front{block}.bn.{part}") +} +pub(crate) fn transformer_name(prefix: &str, part: &str) -> String { + format!("{prefix}.{part}") +} + +fn add_bn( + plan: &mut Vec, + graph_prefix: &str, + checkpoint_prefix: &str, + channels: usize, + rank3: bool, +) { + let shape = if rank3 { + vec![channels, 1, 1] + } else { + vec![channels] + }; + plan.push(item( + format!("{graph_prefix}.scale"), + &shape, + Source::BatchNorm { + prefix: checkpoint_prefix.into(), + channels, + bias: false, + }, + )); + plan.push(item( + format!("{graph_prefix}.bias"), + &shape, + Source::BatchNorm { + prefix: checkpoint_prefix.into(), + channels, + bias: true, + }, + )); +} + +fn add_transformer( + plan: &mut Vec, + graph_prefix: &str, + attn_prefix: &str, + ff_prefix: &str, + dim: usize, +) { + let heads = dim / HEAD_DIM; + plan.push(item( + transformer_name(graph_prefix, "attn.gamma"), + &[dim], + Source::Whole(format!("{attn_prefix}.norm.gamma")), + )); + plan.push(mat( + transformer_name(graph_prefix, "attn.qkv"), + &[dim, dim * 3], + Source::Whole(format!("{attn_prefix}.to_qkv.weight")), + )); + plan.push(mat( + transformer_name(graph_prefix, "attn.gates_w"), + &[dim, heads], + Source::Whole(format!("{attn_prefix}.to_gates.weight")), + )); + plan.push(item( + transformer_name(graph_prefix, "attn.gates_b"), + &[heads], + Source::Whole(format!("{attn_prefix}.to_gates.bias")), + )); + plan.push(mat( + transformer_name(graph_prefix, "attn.out"), + &[dim, dim], + Source::Whole(format!("{attn_prefix}.to_out.0.weight")), + )); + plan.push(item( + transformer_name(graph_prefix, "ff.gamma"), + &[dim], + Source::Whole(format!("{ff_prefix}.net.0.gamma")), + )); + plan.push(mat( + transformer_name(graph_prefix, "ff.w1"), + &[dim, dim * FF_MULT], + Source::Whole(format!("{ff_prefix}.net.1.weight")), + )); + plan.push(item( + transformer_name(graph_prefix, "ff.b1"), + &[dim * FF_MULT], + Source::Whole(format!("{ff_prefix}.net.1.bias")), + )); + plan.push(mat( + transformer_name(graph_prefix, "ff.w2"), + &[dim * FF_MULT, dim], + Source::Whole(format!("{ff_prefix}.net.4.weight")), + )); + plan.push(item( + transformer_name(graph_prefix, "ff.b2"), + &[dim], + Source::Whole(format!("{ff_prefix}.net.4.bias")), + )); +} + +fn weight_plan(config: BeatsConfig) -> Vec { + let mut plan = Vec::new(); + add_bn( + &mut plan, + "stem.input_bn", + "model.frontend.stem.bn1d", + MEL_BINS, + false, + ); + plan.push(mat( + STEM_CONV, + &[1 * 4 * 3, STEM_DIM], + Source::Conv { + name: "model.frontend.stem.conv2d.weight".into(), + out_channels: STEM_DIM, + in_channels: 1, + kernel_h: 4, + kernel_w: 3, + }, + )); + add_bn( + &mut plan, + "stem.bn", + "model.frontend.stem.bn2d", + STEM_DIM, + true, + ); + + for block in 0..STEM_BLOCKS { + let dim = STEM_CHANNELS[block]; + let next = STEM_CHANNELS[block + 1]; + let checkpoint = format!("model.frontend.blocks.{block}"); + add_transformer( + &mut plan, + &format!("front{block}.freq"), + &format!("{checkpoint}.partial.attnF"), + &format!("{checkpoint}.partial.ffF"), + dim, + ); + add_transformer( + &mut plan, + &format!("front{block}.time"), + &format!("{checkpoint}.partial.attnT"), + &format!("{checkpoint}.partial.ffT"), + dim, + ); + plan.push(mat( + block_conv(block), + &[dim * 2 * 3, next], + Source::Conv { + name: format!("{checkpoint}.conv2d.weight"), + out_channels: next, + in_channels: dim, + kernel_h: 2, + kernel_w: 3, + }, + )); + add_bn( + &mut plan, + &format!("front{block}.bn"), + &format!("{checkpoint}.norm"), + next, + true, + ); + } + + plan.push(mat( + FRONT_LINEAR_W, + &[FRONTEND_FEATURES, config.transformer_dim], + Source::Whole("model.frontend.linear.weight".into()), + )); + plan.push(item( + FRONT_LINEAR_B, + &[config.transformer_dim], + Source::Whole("model.frontend.linear.bias".into()), + )); + for layer in 0..MAIN_LAYERS { + let checkpoint = format!("model.transformer_blocks.layers.{layer}"); + add_transformer( + &mut plan, + &format!("main{layer}"), + &format!("{checkpoint}.0"), + &format!("{checkpoint}.1"), + config.transformer_dim, + ); + } + plan.push(item( + FINAL_NORM, + &[config.transformer_dim], + Source::Whole("model.transformer_blocks.norm.gamma".into()), + )); + plan.push(mat( + HEAD_W, + &[config.transformer_dim, 2], + Source::Whole("model.task_heads.beat_downbeat_lin.weight".into()), + )); + plan.push(item( + HEAD_B, + &[2], + Source::Whole("model.task_heads.beat_downbeat_lin.bias".into()), + )); + plan +} + +fn plan_total_bytes(plan: &[PlanItem], f16: bool, extra: usize) -> Result { + let mut total = 0usize; + for item in plan { + let ty = item.dtype(f16); + let layout = TensorLayout::for_ggml(ty, &item.extents).map_err(DiffusionError::model)?; + let bytes = Tensor::from_desc(0, TensorDesc::new(ty, layout, BufferUsage::Weights)).nbytes(); + total = ggml_pad(total, GGML_MEM_ALIGN) + .checked_add(bytes) + .ok_or_else(|| DiffusionError::model("beats weight arena overflow"))?; + } + ggml_pad(total, GGML_MEM_ALIGN) + .checked_add(extra) + .ok_or_else(|| DiffusionError::model("beats context arena overflow")) +} + +fn bytes_f32(values: &[f32]) -> &[u8] { + unsafe { std::slice::from_raw_parts(values.as_ptr().cast(), values.len() * 4) } +} + +fn bytes_u16(values: &[u16]) -> &[u8] { + unsafe { std::slice::from_raw_parts(values.as_ptr().cast(), values.len() * 2) } +} + +#[cfg(test)] +mod tests { + use super::*; + + const WEIGHTS: &str = concat!( + env!("CARGO_MANIFEST_DIR"), + "/../../../../local/models/weights/beat_this" + ); + + fn census_if_present(name: &str, want: BeatsConfig) { + let path = Path::new(WEIGHTS).join(name); + if !path.is_file() { + eprintln!("beats census: SKIP, {} is not seeded", path.display()); + return; + } + let census = checkpoint_census(&path).unwrap(); + assert_eq!(census.config, want); + assert_eq!(census.tensors.len(), 166); + assert_eq!( + census.tensors["model.frontend.stem.conv2d.weight"], + vec![32, 1, 4, 3] + ); + assert_eq!( + census.tensors["model.frontend.blocks.2.conv2d.weight"], + vec![256, 128, 2, 3] + ); + assert_eq!( + census.tensors["model.frontend.linear.weight"], + vec![want.transformer_dim, 1024] + ); + assert_eq!( + census.tensors["model.transformer_blocks.layers.5.0.to_qkv.weight"], + vec![want.transformer_dim * 3, want.transformer_dim] + ); + assert_eq!( + census.tensors["model.task_heads.beat_downbeat_lin.weight"], + vec![2, want.transformer_dim] + ); + } + + #[test] + fn final0_tensor_census_is_exact() { + census_if_present("final0.ckpt", BeatsConfig::FINAL); + } + + #[test] + fn small0_tensor_census_is_exact() { + census_if_present("small0.ckpt", BeatsConfig::SMALL); + } + + #[test] + fn plans_cover_both_model_widths() { + for config in [BeatsConfig::FINAL, BeatsConfig::SMALL] { + let plan = weight_plan(config); + let names: BTreeSet<_> = plan.iter().map(|item| &item.name).collect(); + assert_eq!(names.len(), plan.len()); + let head = plan.iter().find(|item| item.name == HEAD_W).unwrap(); + assert_eq!(head.extents, vec![config.transformer_dim as i64, 2]); + } + } +} diff --git a/libs/ai/models/notes/Cargo.toml b/libs/ai/models/notes/Cargo.toml new file mode 100644 index 000000000..2875ef71f --- /dev/null +++ b/libs/ai/models/notes/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "makepad-ai-notes" +version = "0.1.0" +edition = "2021" +description = "Native Spotify Basic Pitch polyphonic note transcription" +license = "MIT OR Apache-2.0" + +[dependencies] +makepad-ai-common = { path = "../common" } +makepad-ai-loader = { path = "../../loader" } +makepad-midi-file = { path = "../../../midi_file" } diff --git a/libs/ai/models/notes/src/config.rs b/libs/ai/models/notes/src/config.rs new file mode 100644 index 000000000..4d19dae77 --- /dev/null +++ b/libs/ai/models/notes/src/config.rs @@ -0,0 +1,54 @@ +//! Fixed geometry of Spotify's published ICASSP 2022 `nmp` checkpoint. + +pub const SAMPLE_RATE: usize = 22_050; +pub const FFT_HOP: usize = 256; +pub const AUDIO_WINDOW_SECONDS: usize = 2; +pub const AUDIO_N_SAMPLES: usize = SAMPLE_RATE * AUDIO_WINDOW_SECONDS - FFT_HOP; // 43,844 +pub const WINDOW_FRAMES: usize = 172; +pub const OVERLAP_FRAMES: usize = 30; +pub const OVERLAP_SAMPLES: usize = OVERLAP_FRAMES * FFT_HOP; +pub const WINDOW_HOP_SAMPLES: usize = AUDIO_N_SAMPLES - OVERLAP_SAMPLES; +pub const OUTPUT_FRAMES_PER_WINDOW: usize = WINDOW_FRAMES - OVERLAP_FRAMES; + +pub const NOTES: usize = 88; +pub const CONTOUR_BINS_PER_SEMITONE: usize = 3; +pub const CONTOUR_BINS: usize = NOTES * CONTOUR_BINS_PER_SEMITONE; +pub const CQT_BINS_PER_OCTAVE: usize = 12 * CONTOUR_BINS_PER_SEMITONE; +pub const CQT_BINS: usize = 309; +pub const CQT_KERNEL: usize = 256; +pub const CQT_OCTAVES: usize = 9; +pub const CQT_BLOCK_BINS: usize = CQT_BINS_PER_OCTAVE; +pub const BASE_FREQUENCY: f64 = 27.5; +pub const MIDI_OFFSET: i32 = 21; +pub const HARMONICS: [f64; 8] = [0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]; + +pub const ONSET_THRESHOLD: f32 = 0.5; +pub const FRAME_THRESHOLD: f32 = 0.3; +pub const MIN_NOTE_LEN: usize = 11; +pub const ENERGY_TOLERANCE: usize = 11; +pub const PITCH_BEND_TOLERANCE_BINS: isize = 25; + +/// Model-frame timing. The network emits one frame per 256 input samples. +pub const FRAME_RATE: f64 = SAMPLE_RATE as f64 / FFT_HOP as f64; + +pub fn frame_count(samples: usize) -> usize { + usize::from(samples != 0) + samples / FFT_HOP +} + +pub fn harmonic_shifts() -> [isize; HARMONICS.len()] { + HARMONICS.map(|harmonic| { + (12.0 * CONTOUR_BINS_PER_SEMITONE as f64 * harmonic.log2()).round() as isize + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn checkpoint_geometry() { + assert_eq!(AUDIO_N_SAMPLES, 43_844); + assert_eq!(frame_count(AUDIO_N_SAMPLES), WINDOW_FRAMES); + assert_eq!(harmonic_shifts(), [-36, 0, 36, 57, 72, 84, 93, 101]); + } +} diff --git a/libs/ai/models/notes/src/cqt.rs b/libs/ai/models/notes/src/cqt.rs new file mode 100644 index 000000000..11b889f47 --- /dev/null +++ b/libs/ai/models/notes/src/cqt.rs @@ -0,0 +1,235 @@ +//! nnAudio-style CQT and harmonic stacking used by the published checkpoint. +//! +//! The ONNX artifact contains the learned/exported 36-bin complex analysis +//! kernels and anti-alias downsampler. We execute that filter bank natively: +//! nine octave stages, reflection padding for analysis, octave-by-octave +//! low-pass/downsample, magnitude, `NormalizedLog`, scalar BatchNorm, then +//! the eight harmonic shifts. No ONNX runtime is involved. + +use crate::config::*; +use crate::weights::CqtWeights; + +#[derive(Clone, Debug)] +pub struct Cqt { + weights: CqtWeights, +} + +#[derive(Clone, Debug)] +pub struct CqtSpectrogram { + pub frames: usize, + pub bins: usize, + /// Time-major `[frame][bin]`, after NormalizedLog and input BatchNorm. + pub data: Vec, +} + +#[derive(Clone, Debug)] +pub struct HarmonicFeatures { + pub channels: usize, + pub frames: usize, + pub bins: usize, + /// Channel-major `[channel][frame][bin]`. + pub data: Vec, +} + +impl Cqt { + pub fn new(weights: CqtWeights) -> Self { + Self { weights } + } + + pub fn spectrogram(&self, audio: &[f32]) -> Result { + if audio.is_empty() { + return Ok(CqtSpectrogram { + frames: 0, + bins: CQT_BINS, + data: Vec::new(), + }); + } + let frames = frame_count(audio.len()); + let mut levels = Vec::with_capacity(CQT_OCTAVES); + let mut signal = audio.to_vec(); + for level in 0..CQT_OCTAVES { + let stride = FFT_HOP >> level; + if stride == 0 { + return Err("CQT octave count exceeds FFT hop".to_string()); + } + let mut block = vec![(0.0f32, 0.0f32); frames * CQT_BLOCK_BINS]; + let available = (signal.len() + FFT_HOP) // reflection pad: 128 each side + .saturating_sub(CQT_KERNEL) + / stride + + 1; + for frame in 0..frames.min(available) { + let origin = frame * stride; + for bin in 0..CQT_BLOCK_BINS { + let kernel = bin * CQT_KERNEL; + let mut real = self.weights.bias[bin]; + let mut imag = self.weights.bias[bin]; + for tap in 0..CQT_KERNEL { + let index = reflect_index(origin as isize + tap as isize - 128, signal.len()); + let sample = signal[index]; + real += sample * self.weights.real[kernel + tap]; + imag += sample * self.weights.imag[kernel + tap]; + } + block[frame * CQT_BLOCK_BINS + bin] = (real, imag); + } + } + levels.push(block); + if level + 1 < CQT_OCTAVES { + signal = downsample(&signal, &self.weights.downsample); + } + } + + // nnAudio concatenates the lowest octave first and crops the first 15 + // bins, leaving exactly the 309 bins whose first centre is 27.5 Hz. + let cropped = CQT_OCTAVES * CQT_BLOCK_BINS - CQT_BINS; + let mut data = vec![0.0f32; frames * CQT_BINS]; + for frame in 0..frames { + for bin in 0..CQT_BINS { + let all_bin = cropped + bin; + let reverse_level = all_bin / CQT_BLOCK_BINS; + let level = CQT_OCTAVES - 1 - reverse_level; + let local_bin = all_bin % CQT_BLOCK_BINS; + let (real, imag) = levels[level][frame * CQT_BLOCK_BINS + local_bin]; + let scale = self.weights.normalization[bin]; + let real = real * scale; + let imag = imag * scale; + data[frame * CQT_BINS + bin] = (real * real + imag * imag).sqrt(); + } + } + + normalized_log(&mut data); + for value in &mut data { + *value = *value * self.weights.input_bn_scale + self.weights.input_bn_bias; + } + Ok(CqtSpectrogram { + frames, + bins: CQT_BINS, + data, + }) + } + + pub fn transform(&self, audio: &[f32]) -> Result { + let cqt = self.spectrogram(audio)?; + let shifts = harmonic_shifts(); + let mut data = vec![0.0; shifts.len() * cqt.frames * CONTOUR_BINS]; + for (channel, shift) in shifts.into_iter().enumerate() { + for frame in 0..cqt.frames { + for bin in 0..CONTOUR_BINS { + let source = bin as isize + shift; + if (0..cqt.bins as isize).contains(&source) { + data[(channel * cqt.frames + frame) * CONTOUR_BINS + bin] = + cqt.data[frame * cqt.bins + source as usize]; + } + } + } + } + Ok(HarmonicFeatures { + channels: shifts.len(), + frames: cqt.frames, + bins: CONTOUR_BINS, + data, + }) + } +} + +fn reflect_index(index: isize, len: usize) -> usize { + if len <= 1 { + return 0; + } + let period = 2 * (len as isize - 1); + let mut index = index % period; + if index < 0 { + index += period; + } + if index >= len as isize { + index = period - index; + } + index as usize +} + +fn downsample(input: &[f32], kernel: &[f32]) -> Vec { + debug_assert_eq!(kernel.len(), CQT_KERNEL); + let mut output = vec![0.0f32; input.len() / 2]; + for (out_index, value) in output.iter_mut().enumerate() { + let origin = (out_index * 2) as isize - 127; + let mut sum = 0.0; + for (tap, &weight) in kernel.iter().enumerate() { + let index = origin + tap as isize; + if (0..input.len() as isize).contains(&index) { + sum += input[index as usize] * weight; + } + } + *value = sum; + } + output +} + +fn normalized_log(values: &mut [f32]) { + if values.is_empty() { + return; + } + let mut min = f32::INFINITY; + let mut max = f32::NEG_INFINITY; + for value in values.iter_mut() { + *value = 10.0 * (*value * *value + 1.0e-10).log10(); + min = min.min(*value); + max = max.max(*value); + } + let range = max - min; + if range > 0.0 && range.is_finite() { + for value in values { + *value = (*value - min) / range; + } + } else { + values.fill(0.0); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::weights::NotesWeights; + use std::path::Path; + + fn checkpoint() -> std::path::PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .join("../../../../local/models/weights/basic_pitch/nmp.onnx") + } + + #[test] + fn frame_count_matches_checkpoint_and_arbitrary_lengths() { + assert_eq!(frame_count(AUDIO_N_SAMPLES), 172); + assert_eq!(frame_count(22_050), 87); + assert_eq!(frame_count(256), 2); + assert_eq!(frame_count(257), 2); + } + + #[test] + fn sine_440_lights_a4_and_harmonic_stack_alignment() { + let weights = NotesWeights::load(checkpoint()).unwrap(); + let cqt = Cqt::new(weights.cqt); + let audio: Vec = (0..AUDIO_N_SAMPLES) + .map(|i| (std::f64::consts::TAU * 440.0 * i as f64 / SAMPLE_RATE as f64).sin() as f32) + .collect(); + let spectrum = cqt.spectrogram(&audio).unwrap(); + assert_eq!(spectrum.frames, WINDOW_FRAMES); + let mut energy = vec![0.0f32; CQT_BINS]; + for frame in 8..spectrum.frames - 8 { + for bin in 0..CQT_BINS { + energy[bin] += spectrum.data[frame * CQT_BINS + bin]; + } + } + let peak = energy + .iter() + .enumerate() + .max_by(|a, b| a.1.total_cmp(b.1)) + .unwrap() + .0; + assert!((peak as isize - 144).abs() <= 1, "A4 CQT peak was bin {peak}"); + + let stacked = cqt.transform(&audio).unwrap(); + let frame = WINDOW_FRAMES / 2; + let fundamental = stacked.data[(WINDOW_FRAMES + frame) * CONTOUR_BINS + 144]; + let h2_at_a3 = stacked.data[(2 * WINDOW_FRAMES + frame) * CONTOUR_BINS + 108]; + assert!((fundamental - h2_at_a3).abs() < 1e-6); + } +} diff --git a/libs/ai/models/notes/src/graph.rs b/libs/ai/models/notes/src/graph.rs new file mode 100644 index 000000000..1d7d90db2 --- /dev/null +++ b/libs/ai/models/notes/src/graph.rs @@ -0,0 +1,469 @@ +//! The three Basic Pitch heads. +//! +//! [`NotesGraph`] is the portable f32 oracle and normal fallback. The same +//! six convolutions are also described by [`DeviceNotesGraph`] as one ggml +//! graph, compiled through `GraphDevice::{Metal,Cuda}`. Constructing the +//! latter is explicit so CPU-only hosts never probe or touch a GPU. + +use crate::config::{CONTOUR_BINS, WINDOW_FRAMES}; +use crate::cqt::HarmonicFeatures; +use crate::weights::{ConvWeights, NotesWeights}; + +#[derive(Clone, Debug)] +struct Tensor3 { + channels: usize, + height: usize, + width: usize, + data: Vec, +} + +#[derive(Clone, Debug)] +pub struct HeadOutput { + /// `[time][264 contour bins]`. + pub contours: Vec, + /// `[time][88 notes]`. + pub notes: Vec, + /// `[time][88 notes]`. + pub onsets: Vec, +} + +#[derive(Clone, Debug)] +pub struct NotesGraph { + contour: ConvWeights, + contour_out: ConvWeights, + note: ConvWeights, + note_out: ConvWeights, + onset: ConvWeights, + onset_out: ConvWeights, +} + +impl NotesGraph { + pub fn new(weights: &NotesWeights) -> Self { + Self { + contour: weights.contour.clone(), + contour_out: weights.contour_out.clone(), + note: weights.note.clone(), + note_out: weights.note_out.clone(), + onset: weights.onset.clone(), + onset_out: weights.onset_out.clone(), + } + } + + pub fn forward(&self, features: &HarmonicFeatures) -> Result { + if features.channels != 8 || features.bins != CONTOUR_BINS { + return Err(format!( + "Basic Pitch graph expected [8,T,{CONTOUR_BINS}], got [{},{},{}]", + features.channels, features.frames, features.bins + )); + } + let input = Tensor3 { + channels: features.channels, + height: features.frames, + width: features.bins, + data: features.data.clone(), + }; + let mut contour_hidden = conv2d(&input, &self.contour, 1, 1, 1, 19)?; + relu(&mut contour_hidden.data); + let mut contours = conv2d(&contour_hidden, &self.contour_out, 1, 1, 2, 2)?; + sigmoid(&mut contours.data); + + let mut note_hidden = conv2d(&contours, &self.note, 1, 3, 3, 2)?; + relu(&mut note_hidden.data); + let mut notes = conv2d(¬e_hidden, &self.note_out, 1, 1, 3, 1)?; + sigmoid(&mut notes.data); + + let mut onset_hidden = conv2d(&input, &self.onset, 1, 3, 2, 1)?; + relu(&mut onset_hidden.data); + let joined = concat_channels(¬es, &onset_hidden)?; + let mut onsets = conv2d(&joined, &self.onset_out, 1, 1, 1, 1)?; + sigmoid(&mut onsets.data); + + Ok(HeadOutput { + contours: contours.data, + notes: notes.data, + onsets: onsets.data, + }) + } +} + +fn conv2d( + input: &Tensor3, + layer: &ConvWeights, + stride_time: usize, + stride_freq: usize, + pad_time: usize, + pad_freq: usize, +) -> Result { + if input.channels != layer.in_channels { + return Err(format!( + "conv input has {} channels, weights require {}", + input.channels, layer.in_channels + )); + } + let out_h = (input.height + 2 * pad_time - layer.kernel_time) / stride_time + 1; + let out_w = (input.width + 2 * pad_freq - layer.kernel_freq) / stride_freq + 1; + let plane = out_h * out_w; + let mut output = vec![0.0f32; layer.out_channels * plane]; + let workers = std::thread::available_parallelism() + .map(|n| n.get()) + .unwrap_or(1) + .min(layer.out_channels); + let channels_per_worker = layer.out_channels.div_ceil(workers); + std::thread::scope(|scope| { + for (chunk_index, chunk) in output + .chunks_mut(channels_per_worker * plane) + .enumerate() + { + let first_channel = chunk_index * channels_per_worker; + scope.spawn(move || { + for local_channel in 0..chunk.len() / plane { + let out_channel = first_channel + local_channel; + let out = &mut chunk[local_channel * plane..(local_channel + 1) * plane]; + out.fill(layer.bias[out_channel]); + for in_channel in 0..input.channels { + for ky in 0..layer.kernel_time { + for kx in 0..layer.kernel_freq { + let weight_index = (((out_channel * layer.in_channels + in_channel) + * layer.kernel_time + + ky) + * layer.kernel_freq) + + kx; + let weight = layer.values[weight_index]; + for oy in 0..out_h { + let padded_y = oy * stride_time + ky; + if padded_y < pad_time { + continue; + } + let iy = padded_y - pad_time; + if iy >= input.height { + continue; + } + let input_row = + (in_channel * input.height + iy) * input.width; + let output_row = oy * out_w; + for ox in 0..out_w { + let padded_x = ox * stride_freq + kx; + if padded_x < pad_freq { + continue; + } + let ix = padded_x - pad_freq; + if ix < input.width { + out[output_row + ox] += + input.data[input_row + ix] * weight; + } + } + } + } + } + } + } + }); + } + }); + Ok(Tensor3 { + channels: layer.out_channels, + height: out_h, + width: out_w, + data: output, + }) +} + +fn concat_channels(a: &Tensor3, b: &Tensor3) -> Result { + if a.height != b.height || a.width != b.width { + return Err("cannot concatenate Basic Pitch features with different geometry".to_string()); + } + let mut data = Vec::with_capacity(a.data.len() + b.data.len()); + data.extend_from_slice(&a.data); + data.extend_from_slice(&b.data); + Ok(Tensor3 { + channels: a.channels + b.channels, + height: a.height, + width: a.width, + data, + }) +} + +fn relu(values: &mut [f32]) { + for value in values { + *value = value.max(0.0); + } +} + +fn sigmoid(values: &mut [f32]) { + for value in values { + *value = if *value >= 0.0 { + 1.0 / (1.0 + (-*value).exp()) + } else { + let e = value.exp(); + e / (1.0 + e) + }; + } +} + +// ------------------------------------------------------------------------- +// Device graph. This is compiled only when a caller explicitly asks for it. + +use makepad_ai_common::backend::{ + BufferStorageMode, DeviceGraphSession, DeviceRuntime, GraphDevice, +}; +use makepad_ai_common::{ + BufferUsage, Context, Graph, InitParams, Op, TensorId, TensorType, + UnaryOp, +}; + +pub struct DeviceNotesGraph { + ctx: Context, + session: DeviceGraphSession, + input: TensorId, + contours: TensorId, + notes: TensorId, + onsets: TensorId, +} + +impl DeviceNotesGraph { + pub fn load(weights: &NotesWeights) -> Result { + let runtime = DeviceRuntime::new().map_err(|e| e.to_string())?; + Self::load_with_runtime(weights, runtime) + } + + pub fn load_with_runtime( + weights: &NotesWeights, + runtime: DeviceRuntime, + ) -> Result { + let mut ctx = Context::new(InitParams { + mem_size: 4 << 20, + mem_buffer: None, + no_alloc: false, + }); + let input = ctx + .new_named_tensor( + "notes.input", + TensorType::F32, + 4, + &[CONTOUR_BINS as i64, WINDOW_FRAMES as i64, 8, 1], + BufferUsage::Activations, + ) + .map_err(|e| e.to_string())?; + let contour = device_layer(&mut ctx, "notes.contour", &weights.contour)?; + let contour_out = device_layer(&mut ctx, "notes.contour_out", &weights.contour_out)?; + let note = device_layer(&mut ctx, "notes.note", &weights.note)?; + let note_out = device_layer(&mut ctx, "notes.note_out", &weights.note_out)?; + let onset = device_layer(&mut ctx, "notes.onset", &weights.onset)?; + let onset_out = device_layer(&mut ctx, "notes.onset_out", &weights.onset_out)?; + ctx.set_no_alloc(true); + + let contour_hidden = device_conv(&mut ctx, input, contour, 1, 1, 19, 1)?; + let contour_hidden = ctx + .unary(contour_hidden, UnaryOp::Relu, BufferUsage::Activations) + .map_err(|e| e.to_string())?; + let contours = device_conv(&mut ctx, contour_hidden, contour_out, 1, 1, 2, 2)?; + let contours = ctx + .unary(contours, UnaryOp::Sigmoid, BufferUsage::Activations) + .map_err(|e| e.to_string())?; + + let note_hidden = device_conv(&mut ctx, contours, note, 3, 1, 2, 3)?; + let note_hidden = ctx + .unary(note_hidden, UnaryOp::Relu, BufferUsage::Activations) + .map_err(|e| e.to_string())?; + let notes = device_conv(&mut ctx, note_hidden, note_out, 1, 1, 1, 3)?; + let notes = ctx + .unary(notes, UnaryOp::Sigmoid, BufferUsage::Activations) + .map_err(|e| e.to_string())?; + + let onset_hidden = device_conv(&mut ctx, input, onset, 3, 1, 1, 2)?; + let onset_hidden = ctx + .unary(onset_hidden, UnaryOp::Relu, BufferUsage::Activations) + .map_err(|e| e.to_string())?; + let joined = ctx + .concat(notes, onset_hidden, 2, BufferUsage::Activations) + .map_err(|e| e.to_string())?; + let onsets = device_conv(&mut ctx, joined, onset_out, 1, 1, 1, 1)?; + let onsets = ctx + .unary(onsets, UnaryOp::Sigmoid, BufferUsage::Activations) + .map_err(|e| e.to_string())?; + + ctx.set_no_alloc(false); + let mut graph = Graph::new(); + for output in [contours, notes, onsets] { + graph + .build_forward_expand(&ctx, output) + .map_err(|e| e.to_string())?; + } + let session = runtime + .compile_graph( + &ctx, + &graph, + &[contours, notes, onsets], + BufferStorageMode::Shared, + BufferStorageMode::Shared, + ) + .map_err(|e| e.to_string())?; + Ok(Self { + ctx, + session, + input, + contours, + notes, + onsets, + }) + } + + pub fn device(&self) -> GraphDevice { + self.session.device() + } + + pub fn forward(&self, features: &HarmonicFeatures) -> Result { + if (features.channels, features.frames, features.bins) + != (8, WINDOW_FRAMES, CONTOUR_BINS) + { + return Err("device Basic Pitch graph requires one 172-frame window".to_string()); + } + let bytes = bytes_of_f32(&features.data); + let execution = self + .session + .execute( + &self.ctx, + &[(self.input, bytes)], + &[self.contours, self.notes, self.onsets], + ) + .map_err(|e| e.to_string())?; + Ok(HeadOutput { + contours: output_f32(&execution.outputs, self.contours)?, + notes: output_f32(&execution.outputs, self.notes)?, + onsets: output_f32(&execution.outputs, self.onsets)?, + }) + } +} + +#[derive(Clone, Copy)] +struct DeviceLayer { + weight: TensorId, + bias: TensorId, + out_channels: usize, +} + +fn device_layer( + ctx: &mut Context, + name: &str, + layer: &ConvWeights, +) -> Result { + let weight = ctx + .new_named_tensor( + format!("{name}.weight"), + TensorType::F32, + 4, + &[ + layer.kernel_freq as i64, + layer.kernel_time as i64, + layer.in_channels as i64, + layer.out_channels as i64, + ], + BufferUsage::Weights, + ) + .map_err(|e| e.to_string())?; + ctx.write_tensor_data(weight, bytes_of_f32(&layer.values)) + .map_err(|e| e.to_string())?; + let bias = ctx + .new_named_tensor( + format!("{name}.bias"), + TensorType::F32, + 1, + &[layer.out_channels as i64], + BufferUsage::Weights, + ) + .map_err(|e| e.to_string())?; + ctx.write_tensor_data(bias, bytes_of_f32(&layer.bias)) + .map_err(|e| e.to_string())?; + Ok(DeviceLayer { + weight, + bias, + out_channels: layer.out_channels, + }) +} + +fn device_conv( + ctx: &mut Context, + input: TensorId, + layer: DeviceLayer, + stride_freq: i32, + stride_time: i32, + pad_freq: i32, + pad_time: i32, +) -> Result { + let output = ctx + .conv_2d( + layer.weight, + input, + stride_freq, + stride_time, + pad_freq, + pad_time, + 1, + 1, + BufferUsage::Activations, + ) + .map_err(|e| e.to_string())?; + let bias = ctx + .reshape(layer.bias, &[1, 1, layer.out_channels as i64, 1]) + .map_err(|e| e.to_string())?; + let bias = ctx + .repeat(bias, output, BufferUsage::Activations) + .map_err(|e| e.to_string())?; + ctx.binary_like_a(Op::Add, output, bias, BufferUsage::Activations) + .map_err(|e| e.to_string()) +} + +fn bytes_of_f32(values: &[f32]) -> &[u8] { + // f32 has no padding and every bit pattern is valid. + unsafe { std::slice::from_raw_parts(values.as_ptr().cast::(), values.len() * 4) } +} + +fn output_f32( + outputs: &std::collections::BTreeMap>, + id: TensorId, +) -> Result, String> { + let bytes = outputs + .get(&id) + .ok_or_else(|| format!("device graph did not return output tensor {id}"))?; + if bytes.len() % 4 != 0 { + return Err("device graph returned a non-f32-aligned output".to_string()); + } + Ok(bytes + .chunks_exact(4) + .map(|c| f32::from_le_bytes([c[0], c[1], c[2], c[3]])) + .collect()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn pointwise_conv_and_channel_order() { + let input = Tensor3 { + channels: 2, + height: 1, + width: 2, + data: vec![1.0, 2.0, 3.0, 4.0], + }; + let layer = ConvWeights { + out_channels: 1, + in_channels: 2, + kernel_time: 1, + kernel_freq: 1, + values: vec![2.0, 10.0], + bias: vec![0.5], + }; + let out = conv2d(&input, &layer, 1, 1, 0, 0).unwrap(); + assert_eq!(out.data, vec![32.5, 44.5]); + } + + #[test] + #[ignore = "requires an available Metal or CUDA device; CPU graph is the test oracle"] + fn device_graph_builds() { + let checkpoint = std::path::Path::new(env!("CARGO_MANIFEST_DIR")) + .join("../../../../local/models/weights/basic_pitch/nmp.onnx"); + let weights = NotesWeights::load(checkpoint).unwrap(); + let _ = DeviceNotesGraph::load(&weights).unwrap(); + } +} diff --git a/libs/ai/models/notes/src/lib.rs b/libs/ai/models/notes/src/lib.rs new file mode 100644 index 000000000..b97ddc0e2 --- /dev/null +++ b/libs/ai/models/notes/src/lib.rs @@ -0,0 +1,24 @@ +//! Native Rust port of Spotify Basic Pitch (Bittner et al., ICASSP 2022). +//! +//! The model code and published `nmp.onnx` weights are Apache-2.0. This port +//! is a from-scratch implementation of the documented architecture and the +//! Apache-licensed reference algorithms; no Python runtime or ONNX runtime is +//! required. + +pub mod config; +pub mod cqt; +pub mod graph; +pub mod model; +pub mod weights; + +pub use config::{FRAME_RATE, SAMPLE_RATE}; +pub use model::{create_notes, to_midi_bytes, NoteEvent, NoteTranscription, NotesModel}; +pub use weights::{NotesWeights, WeightCensus}; + +pub const MODEL_ID: &str = "basic-pitch"; +pub const MODEL_LICENSE: &str = "Apache-2.0"; +pub const MODEL_SOURCE: &str = "https://github.com/spotify/basic-pitch"; +pub const MODEL_FILE: &str = "basic_pitch_nmp.onnx"; +pub const MODEL_BYTES: u64 = 230_444; +pub const MODEL_SHA256: &str = + "2c3c1d144bfa61ad236e92e169c13535c880469a12a047d4e73451f2c059a0ec"; diff --git a/libs/ai/models/notes/src/model.rs b/libs/ai/models/notes/src/model.rs new file mode 100644 index 000000000..76e9aa0d1 --- /dev/null +++ b/libs/ai/models/notes/src/model.rs @@ -0,0 +1,580 @@ +//! Windowed inference and Basic Pitch note creation. + +use crate::config::*; +use crate::cqt::Cqt; +use crate::graph::NotesGraph; +use crate::weights::{NotesWeights, WeightCensus}; +use std::path::Path; + +#[derive(Clone, Debug, PartialEq)] +pub struct NoteEvent { + pub start_secs: f64, + pub end_secs: f64, + pub midi: u8, + pub amplitude: f32, + /// One estimate per active model frame, in semitones relative to `midi`. + pub bends: Vec, +} + +#[derive(Clone, Debug, PartialEq)] +pub struct NoteTranscription { + pub notes: Vec, + pub frame_rate: f64, + /// Row-major onset posteriorgram, `[time][88]`. + pub onsets: Vec, +} + +pub struct NotesModel { + cqt: Cqt, + graph: NotesGraph, + census: WeightCensus, +} + +impl NotesModel { + pub fn load(path: impl AsRef) -> Result { + let weights = NotesWeights::load(path)?; + Ok(Self { + cqt: Cqt::new(weights.cqt.clone()), + graph: NotesGraph::new(&weights), + census: weights.census, + }) + } + + pub fn census(&self) -> &WeightCensus { + &self.census + } + + pub fn transcribe(&mut self, mono_22k: &[f32]) -> Result { + self.transcribe_with_progress(mono_22k, |_, _| true) + } + + /// As [`Self::transcribe`], with a callback after each completed window. + /// Returning false cancels before the next window begins. + pub fn transcribe_with_progress( + &mut self, + mono_22k: &[f32], + mut progress: F, + ) -> Result + where + F: FnMut(usize, usize) -> bool, + { + if mono_22k.is_empty() { + return Ok(empty_transcription()); + } + let total_windows = (mono_22k.len() + OVERLAP_SAMPLES / 2).div_ceil(WINDOW_HOP_SAMPLES); + // Avoid the non-zero folded biases turning exact digital silence into + // low posterior noise, and avoid doing hundreds of millions of MACs. + if mono_22k.iter().all(|sample| sample.abs() <= 1.0e-8) { + progress(total_windows, total_windows); + return Ok(empty_transcription()); + } + + let mut padded = vec![0.0f32; OVERLAP_SAMPLES / 2]; + padded.extend_from_slice(mono_22k); + let mut contour_windows = Vec::with_capacity(total_windows); + let mut note_windows = Vec::with_capacity(total_windows); + let mut onset_windows = Vec::with_capacity(total_windows); + for window_index in 0..total_windows { + if window_index > 0 && !progress(window_index, total_windows) { + return Err("Basic Pitch transcription cancelled".to_string()); + } + let start = window_index * WINDOW_HOP_SAMPLES; + let mut window = vec![0.0f32; AUDIO_N_SAMPLES]; + if start < padded.len() { + let count = AUDIO_N_SAMPLES.min(padded.len() - start); + window[..count].copy_from_slice(&padded[start..start + count]); + } + let features = self.cqt.transform(&window)?; + if features.frames != WINDOW_FRAMES { + return Err(format!( + "CQT returned {} frames for one checkpoint window, expected {WINDOW_FRAMES}", + features.frames + )); + } + let output = self.graph.forward(&features)?; + contour_windows.push(output.contours); + note_windows.push(output.notes); + onset_windows.push(output.onsets); + } + progress(total_windows, total_windows); + + let expected_frames = ((mono_22k.len() as f64 / WINDOW_HOP_SAMPLES as f64) + * OUTPUT_FRAMES_PER_WINDOW as f64) as usize; + let contours = unwrap_windows(&contour_windows, CONTOUR_BINS, expected_frames)?; + let frames = unwrap_windows(¬e_windows, NOTES, expected_frames)?; + let onsets = unwrap_windows(&onset_windows, NOTES, expected_frames)?; + let mut notes = create_notes(&frames, &onsets, &contours, true)?; + align_leading_edge_onsets(&mut notes, mono_22k); + Ok(NoteTranscription { + notes, + frame_rate: FRAME_RATE, + onsets, + }) + } +} + +/// Relative-max onset decoding cannot select frame zero. For a clip whose +/// first audible event is within the CQT's leading context, Melodia recovers +/// the pitch but can place that first event up to one minimum-note span late. +/// Snap only that boundary chord back to the measured waveform onset; all +/// interior events remain the reference postprocessor's exact frame times. +fn align_leading_edge_onsets(notes: &mut [NoteEvent], audio: &[f32]) { + let peak = audio.iter().copied().map(f32::abs).fold(0.0f32, f32::max); + if peak <= 1.0e-8 || notes.is_empty() { + return; + } + let threshold = peak * 0.01; + let Some(first_sample) = audio.iter().position(|sample| sample.abs() >= threshold) else { + return; + }; + let waveform_start = first_sample as f64 / SAMPLE_RATE as f64; + let decoded_start = notes + .iter() + .map(|note| note.start_secs) + .min_by(f64::total_cmp) + .unwrap_or(waveform_start); + let lag = decoded_start - waveform_start; + if !(0.0..=(MIN_NOTE_LEN as f64 + 1.0) / FRAME_RATE).contains(&lag) { + return; + } + for note in notes + .iter_mut() + .filter(|note| note.start_secs <= decoded_start + 2.0 / FRAME_RATE) + { + let added = ((note.start_secs - waveform_start).max(0.0) * FRAME_RATE).round() as usize; + if let Some(&first_bend) = note.bends.first() { + let mut bends = vec![first_bend; added]; + bends.append(&mut note.bends); + note.bends = bends; + } + note.start_secs = waveform_start; + } +} + +fn empty_transcription() -> NoteTranscription { + NoteTranscription { + notes: Vec::new(), + frame_rate: FRAME_RATE, + onsets: Vec::new(), + } +} + +fn unwrap_windows( + windows: &[Vec], + width: usize, + expected_frames: usize, +) -> Result, String> { + let trim = OVERLAP_FRAMES / 2; + let mut output = Vec::with_capacity(windows.len() * OUTPUT_FRAMES_PER_WINDOW * width); + for window in windows { + if window.len() != WINDOW_FRAMES * width { + return Err(format!( + "Basic Pitch head returned {} values, expected {}", + window.len(), + WINDOW_FRAMES * width + )); + } + output.extend_from_slice(&window[trim * width..(WINDOW_FRAMES - trim) * width]); + } + output.truncate(expected_frames.min(output.len() / width) * width); + Ok(output) +} + +#[derive(Clone, Debug)] +struct FrameNote { + start: usize, + end: usize, + pitch: usize, + amplitude: f32, +} + +/// Decode already-unwrapped head outputs. Public primarily for model-oracle +/// tests and applications that retain posteriorgrams outside `NotesModel`. +pub fn create_notes( + frames: &[f32], + onsets: &[f32], + contours: &[f32], + melodia_trick: bool, +) -> Result, String> { + if frames.len() != onsets.len() || frames.len() % NOTES != 0 { + return Err("note and onset posteriorgrams must both have shape [T,88]".to_string()); + } + let n_frames = frames.len() / NOTES; + if contours.len() != n_frames * CONTOUR_BINS { + return Err("contour posteriorgram must have shape [T,264]".to_string()); + } + if n_frames == 0 { + return Ok(Vec::new()); + } + let inferred_onsets = infer_onsets(onsets, frames, n_frames); + let mut peaks = Vec::new(); + for time in 1..n_frames.saturating_sub(1) { + for pitch in 0..NOTES { + let value = inferred_onsets[time * NOTES + pitch]; + if value >= ONSET_THRESHOLD + && value > inferred_onsets[(time - 1) * NOTES + pitch] + && value > inferred_onsets[(time + 1) * NOTES + pitch] + { + peaks.push((time, pitch)); + } + } + } + peaks.reverse(); + let mut remaining = frames.to_vec(); + let mut decoded = Vec::new(); + for (start, pitch) in peaks { + if start >= n_frames - 1 { + continue; + } + let mut end = start + 1; + let mut below = 0usize; + while end < n_frames - 1 && below < ENERGY_TOLERANCE { + if remaining[end * NOTES + pitch] < FRAME_THRESHOLD { + below += 1; + } else { + below = 0; + } + end += 1; + } + end -= below; + if end - start <= MIN_NOTE_LEN { + continue; + } + clear_energy(&mut remaining, n_frames, start, end, pitch); + decoded.push(FrameNote { + start, + end, + pitch, + amplitude: mean_pitch(frames, start, end, pitch), + }); + } + + if melodia_trick { + loop { + let Some((middle_index, &maximum)) = remaining + .iter() + .enumerate() + .max_by(|a, b| a.1.total_cmp(b.1)) + else { + break; + }; + if maximum <= FRAME_THRESHOLD { + break; + } + let middle = middle_index / NOTES; + let pitch = middle_index % NOTES; + remaining[middle_index] = 0.0; + + let mut cursor = middle + 1; + let mut below = 0usize; + while cursor < n_frames - 1 && below < ENERGY_TOLERANCE { + if remaining[cursor * NOTES + pitch] < FRAME_THRESHOLD { + below += 1; + } else { + below = 0; + } + clear_energy(&mut remaining, n_frames, cursor, cursor + 1, pitch); + cursor += 1; + } + let end = cursor.saturating_sub(1 + below); + + let mut cursor = middle.saturating_sub(1); + let mut below = 0usize; + while cursor > 0 && below < ENERGY_TOLERANCE { + if remaining[cursor * NOTES + pitch] < FRAME_THRESHOLD { + below += 1; + } else { + below = 0; + } + clear_energy(&mut remaining, n_frames, cursor, cursor + 1, pitch); + cursor -= 1; + } + let start = cursor + 1 + below; + if end > start && end - start > MIN_NOTE_LEN { + decoded.push(FrameNote { + start, + end, + pitch, + amplitude: mean_pitch(frames, start, end, pitch), + }); + } + } + } + + let mut notes: Vec<_> = decoded + .into_iter() + .map(|note| { + let midi = (note.pitch as i32 + MIDI_OFFSET) as u8; + let bends = pitch_bends(contours, n_frames, ¬e); + NoteEvent { + start_secs: note.start as f64 / FRAME_RATE, + end_secs: note.end as f64 / FRAME_RATE, + midi, + amplitude: note.amplitude, + bends, + } + }) + .collect(); + notes.sort_by(|a, b| { + a.start_secs + .total_cmp(&b.start_secs) + .then_with(|| a.midi.cmp(&b.midi)) + }); + Ok(notes) +} + +fn infer_onsets(onsets: &[f32], frames: &[f32], n_frames: usize) -> Vec { + let mut difference = vec![0.0f32; onsets.len()]; + let mut max_difference = 0.0f32; + for time in 2..n_frames { + for pitch in 0..NOTES { + let current = frames[time * NOTES + pitch]; + let d1 = current - frames[(time - 1) * NOTES + pitch]; + let d2 = current - frames[(time - 2) * NOTES + pitch]; + let value = d1.min(d2).max(0.0); + difference[time * NOTES + pitch] = value; + max_difference = max_difference.max(value); + } + } + let max_onset = onsets.iter().copied().fold(0.0f32, f32::max); + let scale = if max_difference > 0.0 { + max_onset / max_difference + } else { + 0.0 + }; + onsets + .iter() + .zip(difference) + .map(|(&onset, difference)| onset.max(difference * scale)) + .collect() +} + +fn clear_energy( + remaining: &mut [f32], + n_frames: usize, + start: usize, + end: usize, + pitch: usize, +) { + for time in start..end.min(n_frames) { + remaining[time * NOTES + pitch] = 0.0; + if pitch > 0 { + remaining[time * NOTES + pitch - 1] = 0.0; + } + if pitch + 1 < NOTES { + remaining[time * NOTES + pitch + 1] = 0.0; + } + } +} + +fn mean_pitch(frames: &[f32], start: usize, end: usize, pitch: usize) -> f32 { + let sum: f32 = (start..end).map(|time| frames[time * NOTES + pitch]).sum(); + sum / (end - start) as f32 +} + +fn pitch_bends(contours: &[f32], n_frames: usize, note: &FrameNote) -> Vec { + let center = note.pitch as isize * CONTOUR_BINS_PER_SEMITONE as isize; + let first = (center - PITCH_BEND_TOLERANCE_BINS).max(0); + let last = (center + PITCH_BEND_TOLERANCE_BINS) + .min(CONTOUR_BINS as isize - 1); + let mut bends = Vec::with_capacity(note.end - note.start); + for time in note.start..note.end.min(n_frames) { + let mut best_bin = center; + let mut best_value = f32::NEG_INFINITY; + for bin in first..=last { + let offset = bin - center; + let gaussian = (-0.5 * (offset as f32 / 5.0).powi(2)).exp(); + let value = contours[time * CONTOUR_BINS + bin as usize] * gaussian; + if value > best_value { + best_value = value; + best_bin = bin; + } + } + bends.push((best_bin - center) as f32 / CONTOUR_BINS_PER_SEMITONE as f32); + } + bends +} + +/// Serialize a transcription as a format-0 Standard MIDI File. Polyphonic +/// notes are assigned independent channels where possible so pitch bends do +/// not leak between simultaneous notes; the General MIDI default bend range +/// is ±2 semitones. +pub fn to_midi_bytes(transcription: &NoteTranscription, bpm: Option) -> Vec { + use makepad_midi_file::{ + ChannelEvent, ChannelMessage, Division, EventKind, Format, Header, MetaEvent, + MidiFile, Track, TrackEvent, + }; + const TPQ: u16 = 480; + const CHANNELS: [u8; 15] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15]; + let bpm = bpm.filter(|value| value.is_finite() && *value > 0.0).unwrap_or(120.0); + let micros = (60_000_000.0 / bpm).round().clamp(1.0, 16_777_215.0) as u32; + let ticks_per_second = bpm / 60.0 * f64::from(TPQ); + let mut channel_free_at = [0.0f64; CHANNELS.len()]; + let mut events: Vec<(u64, u8, EventKind)> = vec![( + 0, + 0, + EventKind::Meta(MetaEvent::SetTempo(micros)), + )]; + for (index, &channel) in CHANNELS.iter().enumerate() { + events.push(( + 0, + 1, + EventKind::Channel(ChannelEvent { + channel, + message: ChannelMessage::ProgramChange { program: 4 }, + }), + )); + channel_free_at[index] = 0.0; + } + let mut notes = transcription.notes.clone(); + notes.sort_by(|a, b| a.start_secs.total_cmp(&b.start_secs)); + for note in ¬es { + let channel_index = channel_free_at + .iter() + .position(|&end| end <= note.start_secs) + .unwrap_or_else(|| { + channel_free_at + .iter() + .enumerate() + .min_by(|a, b| a.1.total_cmp(b.1)) + .map(|(index, _)| index) + .unwrap_or(0) + }); + channel_free_at[channel_index] = note.end_secs; + let channel = CHANNELS[channel_index]; + let start_tick = seconds_to_ticks(note.start_secs, ticks_per_second); + let end_tick = seconds_to_ticks(note.end_secs, ticks_per_second).max(start_tick + 1); + if !note.bends.is_empty() { + let denominator = note.bends.len().saturating_sub(1).max(1) as f64; + for (index, &bend) in note.bends.iter().enumerate() { + let fraction = index as f64 / denominator; + let tick = start_tick + ((end_tick - start_tick) as f64 * fraction).round() as u64; + let value = (8192.0 + bend.clamp(-2.0, 2.0) as f64 * 4096.0) + .round() + .clamp(0.0, 16_383.0) as u16; + events.push(( + tick, + 2, + EventKind::Channel(ChannelEvent { + channel, + message: ChannelMessage::PitchBend { value }, + }), + )); + } + } + events.push(( + start_tick, + 3, + EventKind::Channel(ChannelEvent { + channel, + message: ChannelMessage::NoteOn { + key: note.midi, + velocity: (note.amplitude.clamp(0.0, 1.0) * 127.0).round() as u8, + }, + }), + )); + events.push(( + end_tick, + 0, + EventKind::Channel(ChannelEvent { + channel, + message: ChannelMessage::NoteOff { + key: note.midi, + velocity: 0, + }, + }), + )); + events.push(( + end_tick, + 1, + EventKind::Channel(ChannelEvent { + channel, + message: ChannelMessage::PitchBend { value: 8192 }, + }), + )); + } + events.sort_by_key(|(tick, priority, _)| (*tick, *priority)); + let final_tick = events.last().map(|event| event.0).unwrap_or(0); + let mut track = Track::default(); + track.events = events + .into_iter() + .map(|(tick, _, kind)| TrackEvent { tick, kind }) + .collect(); + track.events.push(TrackEvent { + tick: final_tick, + kind: EventKind::Meta(MetaEvent::EndOfTrack), + }); + MidiFile { + header: Header { + format: Format::SingleTrack, + track_count: 1, + division: Division::TicksPerQuarter(TPQ), + extra_data: Vec::new(), + }, + tracks: vec![track], + unknown_chunks: Vec::new(), + } + .to_bytes() + .unwrap_or_default() +} + +fn seconds_to_ticks(seconds: f64, ticks_per_second: f64) -> u64 { + (seconds.max(0.0) * ticks_per_second).round() as u64 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn note_creation_extends_energy_and_reads_bends() { + let n = 40; + let pitch = 48usize; + let mut frames = vec![0.0; n * NOTES]; + let mut onsets = vec![0.0; n * NOTES]; + let mut contours = vec![0.0; n * CONTOUR_BINS]; + onsets[5 * NOTES + pitch] = 0.9; + for time in 5..30 { + frames[time * NOTES + pitch] = 0.8; + let bend = ((time - 5) / 8).min(2); + contours[time * CONTOUR_BINS + pitch * 3 + bend] = 1.0; + } + let notes = create_notes(&frames, &onsets, &contours, true).unwrap(); + assert_eq!(notes.len(), 1); + assert_eq!(notes[0].midi, 69); + assert!((notes[0].start_secs - 5.0 / FRAME_RATE).abs() < 1e-9); + assert!(notes[0].bends.windows(2).all(|pair| pair[0] <= pair[1])); + } + + #[test] + fn midi_contains_notes_and_pitch_bends() { + let transcription = NoteTranscription { + notes: vec![NoteEvent { + start_secs: 0.0, + end_secs: 0.5, + midi: 69, + amplitude: 0.8, + bends: vec![0.0, 0.5, 1.0], + }], + frame_rate: FRAME_RATE, + onsets: Vec::new(), + }; + let bytes = to_midi_bytes(&transcription, None); + let midi = makepad_midi_file::parse(&bytes).unwrap(); + let events = &midi.tracks[0].events; + assert!(events.iter().any(|event| matches!( + event.kind, + makepad_midi_file::EventKind::Channel(makepad_midi_file::ChannelEvent { + message: makepad_midi_file::ChannelMessage::NoteOn { key: 69, .. }, + .. + }) + ))); + assert!(events.iter().any(|event| matches!( + event.kind, + makepad_midi_file::EventKind::Channel(makepad_midi_file::ChannelEvent { + message: makepad_midi_file::ChannelMessage::PitchBend { .. }, + .. + }) + ))); + } +} diff --git a/libs/ai/models/notes/src/weights.rs b/libs/ai/models/notes/src/weights.rs new file mode 100644 index 000000000..5cbdefc73 --- /dev/null +++ b/libs/ai/models/notes/src/weights.rs @@ -0,0 +1,255 @@ +//! ONNX checkpoint census and tensor mapping. + +use makepad_ai_loader::formats::onnx::{OnnxAttribute, OnnxGraph, OnnxModel}; +use std::collections::BTreeMap; +use std::path::Path; + +#[derive(Clone, Debug)] +pub struct ConvWeights { + pub out_channels: usize, + pub in_channels: usize, + pub kernel_time: usize, + pub kernel_freq: usize, + /// ONNX NCHW order: `[out, in, time, frequency]`. + pub values: Vec, + pub bias: Vec, +} + +#[derive(Clone, Debug)] +pub struct CqtWeights { + pub real: Vec, + pub imag: Vec, + pub downsample: Vec, + pub normalization: Vec, + pub bias: Vec, + pub input_bn_scale: f32, + pub input_bn_bias: f32, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct WeightCensus { + pub initializer_count: usize, + pub node_count: usize, + pub op_counts: BTreeMap, + pub network_parameter_count: usize, + pub published_parameter_count: usize, +} + +#[derive(Clone, Debug)] +pub struct NotesWeights { + pub cqt: CqtWeights, + pub contour: ConvWeights, + pub contour_out: ConvWeights, + pub note: ConvWeights, + pub note_out: ConvWeights, + pub onset: ConvWeights, + pub onset_out: ConvWeights, + pub census: WeightCensus, +} + +const CQT_REAL: &str = "const_fold_opt__655"; +const CQT_IMAG: &str = "const_fold_opt__664"; +const CQT_DOWNSAMPLE: &str = "const_fold_opt__734"; +const CQT_NORM: &str = "model_1/cq_t2010v2_1/Sqrt;model_1/cq_t2010v2_1/Sqrt"; +const CQT_BIAS: &str = "model_1/cq_t2010v2_1/conv1d_25;model_1/cq_t2010v2_1/conv1d_25"; +const INPUT_BN_SCALE: &str = "model_1/batch_normalization/FusedBatchNormV3;model_1/batch_normalization/FusedBatchNormV3"; +const INPUT_BN_BIAS: &str = "model_1/batch_normalization/FusedBatchNormV3;model_1/batch_normalization/FusedBatchNormV31"; + +const CONTOUR_W: &str = "const_fold_opt__727"; +const CONTOUR_B: &str = "model_1/re_lu_1/Relu;model_1/re_lu_1/Relu;model_1/batch_normalization_2/FusedBatchNormV3;model_1/batch_normalization_2/FusedBatchNormV3;model_1/conv2d_1/BiasAdd/ReadVariableOp;model_1/conv2d_1/BiasAdd/ReadVariableOp;model_1/conv2d_1/BiasAdd;model_1/conv2d_1/BiasAdd;model_1/conv2d_1/Conv2D;model_1/conv2d_1/Conv2D"; +const CONTOUR_OUT_W: &str = "const_fold_opt__710"; +const CONTOUR_OUT_B: &str = "model_1/contours-reduced/BiasAdd/ReadVariableOp;model_1/contours-reduced/BiasAdd/ReadVariableOp"; +const NOTE_W: &str = "const_fold_opt__738"; +const NOTE_B: &str = "model_1/conv2d_2/BiasAdd/ReadVariableOp;model_1/conv2d_2/BiasAdd/ReadVariableOp"; +const NOTE_OUT_W: &str = "const_fold_opt__702"; +const NOTE_OUT_B: &str = "model_1/conv2d_3/BiasAdd/ReadVariableOp;model_1/conv2d_3/BiasAdd/ReadVariableOp"; +const ONSET_W: &str = "const_fold_opt__707"; +const ONSET_B: &str = "model_1/re_lu_3/Relu;model_1/re_lu_3/Relu;model_1/batch_normalization_3/FusedBatchNormV3;model_1/batch_normalization_3/FusedBatchNormV3;model_1/conv2d_4/BiasAdd/ReadVariableOp;model_1/conv2d_4/BiasAdd/ReadVariableOp;model_1/conv2d_4/BiasAdd;model_1/conv2d_4/BiasAdd;model_1/conv2d_2/Conv2D;model_1/conv2d_2/Conv2D;model_1/conv2d_4/Conv2D;model_1/conv2d_4/Conv2D"; +const ONSET_OUT_W: &str = "const_fold_opt__680"; +const ONSET_OUT_B: &str = "model_1/conv2d_5/BiasAdd/ReadVariableOp;model_1/conv2d_5/BiasAdd/ReadVariableOp"; + +impl NotesWeights { + pub fn load(path: impl AsRef) -> Result { + let model = OnnxModel::load(path)?; + validate_graph(&model.graph)?; + let g = &model.graph; + let cqt = CqtWeights { + real: tensor(g, CQT_REAL, &[36, 1, 1, 256])?, + imag: tensor(g, CQT_IMAG, &[36, 1, 1, 256])?, + downsample: tensor(g, CQT_DOWNSAMPLE, &[1, 1, 1, 256])?, + normalization: tensor(g, CQT_NORM, &[309, 1, 1])?, + bias: tensor(g, CQT_BIAS, &[36])?, + input_bn_scale: scalar(g, INPUT_BN_SCALE)?, + input_bn_bias: scalar(g, INPUT_BN_BIAS)?, + }; + let contour = conv(g, CONTOUR_W, CONTOUR_B, [8, 8, 3, 39])?; + let contour_out = conv(g, CONTOUR_OUT_W, CONTOUR_OUT_B, [1, 8, 5, 5])?; + let note = conv(g, NOTE_W, NOTE_B, [32, 1, 7, 7])?; + let note_out = conv(g, NOTE_OUT_W, NOTE_OUT_B, [1, 32, 7, 3])?; + let onset = conv(g, ONSET_W, ONSET_B, [32, 8, 5, 5])?; + let onset_out = conv(g, ONSET_OUT_W, ONSET_OUT_B, [1, 33, 3, 3])?; + let network_parameter_count = [ + &contour, + &contour_out, + ¬e, + ¬e_out, + &onset, + &onset_out, + ] + .iter() + .map(|layer| layer.values.len() + layer.bias.len()) + .sum(); + let mut op_counts = BTreeMap::new(); + for node in &g.nodes { + *op_counts.entry(node.op_type.clone()).or_insert(0) += 1; + } + let census = WeightCensus { + initializer_count: g.initializers.len(), + node_count: g.nodes.len(), + op_counts, + network_parameter_count, + // Keras includes gamma+beta for the three BatchNorm layers; + // tf2onnx folds those 82 trainable scalars into conv weights/biases. + published_parameter_count: network_parameter_count + 2 * (1 + 8 + 32), + }; + Ok(Self { + cqt, + contour, + contour_out, + note, + note_out, + onset, + onset_out, + census, + }) + } +} + +fn validate_graph(graph: &OnnxGraph) -> Result<(), String> { + if graph.inputs != ["serving_default_input_2:0"] { + return Err(format!("Basic Pitch ONNX input changed: {:?}", graph.inputs)); + } + if graph.outputs + != [ + "StatefulPartitionedCall:2", + "StatefulPartitionedCall:1", + "StatefulPartitionedCall:0", + ] + { + return Err(format!("Basic Pitch ONNX outputs changed: {:?}", graph.outputs)); + } + if graph.initializers.len() != 102 || graph.nodes.len() != 248 { + return Err(format!( + "Basic Pitch ONNX census changed: {} initializers, {} nodes", + graph.initializers.len(), + graph.nodes.len() + )); + } + let expected = [ + (CONTOUR_W, [3, 39].as_slice(), [1, 1].as_slice(), [1, 19, 1, 19].as_slice()), + (CONTOUR_OUT_W, [5, 5].as_slice(), [1, 1].as_slice(), [2, 2, 2, 2].as_slice()), + (NOTE_W, [7, 7].as_slice(), [1, 3].as_slice(), [3, 2, 3, 2].as_slice()), + (NOTE_OUT_W, [7, 3].as_slice(), [1, 1].as_slice(), [3, 1, 3, 1].as_slice()), + (ONSET_W, [5, 5].as_slice(), [1, 3].as_slice(), [2, 1, 2, 1].as_slice()), + (ONSET_OUT_W, [3, 3].as_slice(), [1, 1].as_slice(), [1, 1, 1, 1].as_slice()), + ]; + for (weight, kernel, stride, pads) in expected { + let found = graph.nodes.iter().any(|node| { + node.op_type == "Conv" + && node.inputs.iter().any(|input| input == weight) + && + matches!(node.attributes.get("kernel_shape"), Some(OnnxAttribute::Ints(v)) if v == kernel) + && matches!(node.attributes.get("strides"), Some(OnnxAttribute::Ints(v)) if v == stride) + && matches!(node.attributes.get("pads"), Some(OnnxAttribute::Ints(v)) if v == pads) + }); + if !found { + return Err(format!( + "Basic Pitch ONNX is missing Conv weight={weight:?} kernel={kernel:?} stride={stride:?} pads={pads:?}" + )); + } + } + Ok(()) +} + +fn tensor(graph: &OnnxGraph, name: &str, shape: &[i64]) -> Result, String> { + let value = graph + .initializers + .get(name) + .ok_or_else(|| format!("Basic Pitch ONNX missing initializer '{name}'"))?; + if value.dims != shape { + return Err(format!( + "Basic Pitch initializer '{name}' shape {:?}, expected {shape:?}", + value.dims + )); + } + value.f32_values() +} + +fn scalar(graph: &OnnxGraph, name: &str) -> Result { + let values = tensor(graph, name, &[1])?; + Ok(values[0]) +} + +fn conv( + graph: &OnnxGraph, + weight: &str, + bias: &str, + shape: [usize; 4], +) -> Result { + let dims: Vec = shape.iter().map(|&v| v as i64).collect(); + Ok(ConvWeights { + out_channels: shape[0], + in_channels: shape[1], + kernel_time: shape[2], + kernel_freq: shape[3], + values: tensor(graph, weight, &dims)?, + bias: tensor(graph, bias, &[shape[0] as i64])?, + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn checkpoint() -> std::path::PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .join("../../../../local/models/weights/basic_pitch/nmp.onnx") + } + + #[test] + fn official_checkpoint_census_and_shapes() { + let weights = NotesWeights::load(checkpoint()).expect("seeded Basic Pitch checkpoint"); + assert_eq!(weights.census.initializer_count, 102); + assert_eq!(weights.census.node_count, 248); + assert_eq!(weights.census.network_parameter_count, 16_700); + assert_eq!(weights.census.published_parameter_count, 16_782); + let expected_ops = BTreeMap::from([ + ("Add".to_string(), 2), + ("Cast".to_string(), 3), + ("Concat".to_string(), 20), + ("Conv".to_string(), 32), + ("Div".to_string(), 1), + ("Equal".to_string(), 1), + ("Log".to_string(), 1), + ("Mul".to_string(), 6), + ("Neg".to_string(), 9), + ("Pad".to_string(), 24), + ("ReduceMax".to_string(), 1), + ("ReduceMin".to_string(), 1), + ("ReduceSum".to_string(), 1), + ("Relu".to_string(), 3), + ("Reshape".to_string(), 67), + ("Shape".to_string(), 1), + ("Sigmoid".to_string(), 3), + ("Slice".to_string(), 11), + ("Sqrt".to_string(), 1), + ("Sub".to_string(), 1), + ("Transpose".to_string(), 21), + ("Unsqueeze".to_string(), 37), + ("Where".to_string(), 1), + ]); + assert_eq!(weights.census.op_counts, expected_ops); + assert_eq!(weights.contour.values.len(), 8 * 8 * 3 * 39); + assert_eq!(weights.onset_out.values.len(), 33 * 3 * 3); + } +} diff --git a/libs/ai/models/notes/tests/transcription.rs b/libs/ai/models/notes/tests/transcription.rs new file mode 100644 index 000000000..3c7b88645 --- /dev/null +++ b/libs/ai/models/notes/tests/transcription.rs @@ -0,0 +1,121 @@ +use makepad_ai_notes::config::{AUDIO_N_SAMPLES, SAMPLE_RATE}; +use makepad_ai_notes::{NotesModel, MODEL_FILE}; +use std::path::{Path, PathBuf}; + +fn checkpoint() -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .join("../../../../local/models/weights/basic_pitch/nmp.onnx") +} + +fn frequency(midi: f64) -> f64 { + 440.0 * 2.0f64.powf((midi - 69.0) / 12.0) +} + +fn attacked_sine(midi: f64, seconds: f64) -> Vec { + let samples = (seconds * SAMPLE_RATE as f64).round() as usize; + (0..samples) + .map(|index| { + let time = index as f64 / SAMPLE_RATE as f64; + let attack = (time / 0.008).min(1.0); + let release = ((seconds - time) / 0.015).clamp(0.0, 1.0); + (0.75 * attack * release + * (std::f64::consts::TAU * frequency(midi) * time).sin()) as f32 + }) + .collect() +} + +fn has_note_near(notes: &[makepad_ai_notes::NoteEvent], midi: u8, start: f64) -> bool { + notes + .iter() + .any(|note| note.midi == midi && (note.start_secs - start).abs() <= 0.040) +} + +#[test] +fn silence_produces_no_notes() { + let mut model = NotesModel::load(checkpoint()).unwrap(); + let result = model.transcribe(&vec![0.0; AUDIO_N_SAMPLES]).unwrap(); + assert!(result.notes.is_empty()); +} + +#[test] +fn four_note_bass_line_has_expected_pitches_and_onsets() { + let mut audio = Vec::new(); + for midi in [28.0, 33.0, 38.0, 43.0] { + audio.extend(attacked_sine(midi, 0.5)); + } + let mut model = NotesModel::load(checkpoint()).unwrap(); + let result = model.transcribe(&audio).unwrap(); + assert_eq!(result.notes.len(), 4, "unexpected bass notes: {:?}", result.notes); + for (midi, start) in [(28, 0.0), (33, 0.5), (38, 1.0), (43, 1.5)] { + assert!( + has_note_near(&result.notes, midi, start), + "missing MIDI {midi} near {start:.2}s; got {:?}", + result.notes + ); + } +} + +#[test] +fn c_major_triad_is_simultaneous() { + let voices = [attacked_sine(60.0, 0.7), attacked_sine(64.0, 0.7), attacked_sine(67.0, 0.7)]; + let mut audio = vec![0.0f32; voices[0].len()]; + for voice in voices { + for (sample, value) in audio.iter_mut().zip(voice) { + *sample += value / 3.0; + } + } + let mut model = NotesModel::load(checkpoint()).unwrap(); + let result = model.transcribe(&audio).unwrap(); + assert_eq!(result.notes.len(), 3, "unexpected triad notes: {:?}", result.notes); + for midi in [60, 64, 67] { + assert!( + has_note_near(&result.notes, midi, 0.0), + "missing triad MIDI {midi}; got {:?}", + result.notes + ); + } +} + +#[test] +fn one_semitone_glide_has_rising_bends() { + let seconds = 0.8; + let samples = (seconds * SAMPLE_RATE as f64) as usize; + let mut phase = 0.0f64; + let mut audio = Vec::with_capacity(samples); + for index in 0..samples { + let time = index as f64 / SAMPLE_RATE as f64; + let midi = 45.0 + time / seconds; + phase += std::f64::consts::TAU * frequency(midi) / SAMPLE_RATE as f64; + let envelope = (time / 0.008).min(1.0) * ((seconds - time) / 0.015).clamp(0.0, 1.0); + audio.push((0.75 * envelope * phase.sin()) as f32); + } + let mut model = NotesModel::load(checkpoint()).unwrap(); + let result = model.transcribe(&audio).unwrap(); + let note = result + .notes + .iter() + .filter(|note| note.midi == 45 || note.midi == 46) + .max_by(|a, b| a.end_secs.total_cmp(&b.end_secs)) + .unwrap_or_else(|| panic!("missing gliding A; got {:?}", result.notes)); + let reversals = note.bends.windows(2).filter(|pair| pair[1] < pair[0]).count(); + assert!(reversals <= 1, "non-rising bend trend: {:?}", note.bends); + assert!(note.bends.last().unwrap_or(&0.0) > note.bends.first().unwrap_or(&0.0)); +} + +#[test] +fn overlap_seam_does_not_duplicate_a_sustained_note() { + let audio = attacked_sine(45.0, 2.4); + let mut model = NotesModel::load(checkpoint()).unwrap(); + let result = model.transcribe(&audio).unwrap(); + let long_a_notes = result + .notes + .iter() + .filter(|note| note.midi == 45 && note.end_secs - note.start_secs > 0.4) + .count(); + assert_eq!(long_a_notes, 1, "seam duplicated A2: {:?}", result.notes); +} + +#[test] +fn model_file_constant_matches_registry_cache_name() { + assert_eq!(MODEL_FILE, "basic_pitch_nmp.onnx"); +} From 120b7e23ae2a01668650ceb254ef652157b7e597 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 02:51:44 +0200 Subject: [PATCH 047/417] score view: the engraver as a shared library, with drum and pitched score builders libs/score_view carries the engraving, spacing, font and document code out of the score app so any app can show notation: a ScoreView widget with width/page/content fits, pan and zoom, a playhead, a dark palette, drum-key labels, lyrics under melody notes, and builders for drum, pitched and bass-tab scores. The score app uses it. Vector glyphs no longer write depth for transparent fragments, and the Metal screenshot staging sizes itself from the source texture. Co-Authored-By: Claude Fable 5.1 --- apps/score/src/main.rs | 20 +- draw/src/shader/draw_vector.rs | 8 +- libs/score_ui/Cargo.toml | 5 +- libs/score_ui/src/document.rs | 41 +- libs/score_ui/src/engrave.rs | 1764 +------------- libs/score_ui/src/font.rs | 995 +------- libs/score_ui/src/lib.rs | 8 +- libs/score_ui/src/playback.rs | 278 +++ libs/score_ui/src/spacing.rs | 967 +------- libs/score_ui/src/state.rs | 2 +- libs/score_view/Cargo.toml | 24 + .../score_view}/resources/fonts/OFL.txt | 0 .../score_view}/resources/fonts/bravura.otf | Bin .../resources/fonts/bravura_metadata.json | 0 .../resources/fonts/glyphnames.json | 0 libs/score_view/src/build.rs | 932 +++++++ libs/score_view/src/document.rs | 565 +++++ libs/score_view/src/engrave.rs | 2170 +++++++++++++++++ libs/score_view/src/font.rs | 1018 ++++++++ libs/score_view/src/lib.rs | 27 + libs/score_view/src/spacing.rs | 1053 ++++++++ libs/{score_ui => score_view}/src/title.rs | 0 libs/score_view/src/view.rs | 951 ++++++++ libs/score_view/tests/embed_app/Cargo.toml | 8 + libs/score_view/tests/embed_app/src/main.rs | 177 ++ libs/score_view/tests/embedded.rs | 106 + platform/src/os/apple/metal.rs | 36 +- platform/src/os/cx_shared.rs | 2 +- 28 files changed, 7369 insertions(+), 3788 deletions(-) create mode 100644 libs/score_view/Cargo.toml rename {apps/score => libs/score_view}/resources/fonts/OFL.txt (100%) rename {apps/score => libs/score_view}/resources/fonts/bravura.otf (100%) rename {apps/score => libs/score_view}/resources/fonts/bravura_metadata.json (100%) rename {apps/score => libs/score_view}/resources/fonts/glyphnames.json (100%) create mode 100644 libs/score_view/src/build.rs create mode 100644 libs/score_view/src/document.rs create mode 100644 libs/score_view/src/engrave.rs create mode 100644 libs/score_view/src/font.rs create mode 100644 libs/score_view/src/lib.rs create mode 100644 libs/score_view/src/spacing.rs rename libs/{score_ui => score_view}/src/title.rs (100%) create mode 100644 libs/score_view/src/view.rs create mode 100644 libs/score_view/tests/embed_app/Cargo.toml create mode 100644 libs/score_view/tests/embed_app/src/main.rs create mode 100644 libs/score_view/tests/embedded.rs diff --git a/apps/score/src/main.rs b/apps/score/src/main.rs index d4c090d0d..285c9a76c 100644 --- a/apps/score/src/main.rs +++ b/apps/score/src/main.rs @@ -1,6 +1,6 @@ //! Thin desktop frontend for `makepad-score-ui`. -use score_ui::font::{set_embedded_music_font, EmbeddedFont}; +use score_ui::font::ensure_default_font; use score_ui::library::BundledPiece; use score_ui::{apply_score_action, key_action, ScoreAction, ScoreAppState}; use makepad_widgets::*; @@ -21,22 +21,6 @@ app_main!(App); /// `resources/performances/LICENSE-piano-midi-de.txt`. The ShareAlike term /// binds adaptations of these files and does not reach this application's own /// source. [`PERFORMER_CREDIT`] is shown whenever one of them is opened. -/// The notation font the application carries. -/// -/// Bravura, by Steinberg Media Technologies, under the SIL Open Font License -/// 1.1 — see `resources/fonts/OFL.txt`, which travels with it. It is the -/// reference SMuFL font, and it is embedded rather than looked up so that a -/// fresh checkout draws real notation on its first run instead of falling back -/// to the built-in outlines. `MAKEPAD_SCORE_MUSIC_FONT` still overrides it. -fn embedded_music_font() -> EmbeddedFont { - EmbeddedFont { - name: "Bravura", - otf: include_bytes!("../resources/fonts/bravura.otf"), - metadata: Some(include_bytes!("../resources/fonts/bravura_metadata.json")), - glyphnames: Some(include_bytes!("../resources/fonts/glyphnames.json")), - } -} - const PERFORMER_CREDIT: &str = "Performed by Bernd Krueger · piano-midi.de · CC BY-SA 3.0"; const PERFORMANCES: &[BundledPiece] = &[ @@ -264,7 +248,7 @@ impl AppMain for App { // the moment a document exists, and the application's own state builds // one during construction — registering the built-in font in the first // event would be a frame too late, and the font resolves exactly once. - set_embedded_music_font(embedded_music_font()); + ensure_default_font(); makepad_widgets::script_mod(vm); score_ui::script_mod(vm); self::script_mod(vm) diff --git a/draw/src/shader/draw_vector.rs b/draw/src/shader/draw_vector.rs index 0eeccb801..0770ef674 100644 --- a/draw/src/shader/draw_vector.rs +++ b/draw/src/shader/draw_vector.rs @@ -223,7 +223,13 @@ script_mod! { ); if local.x < clip.x || local.y < clip.y || local.x > clip.z || local.y > clip.w { - return vec4(0.0, 0.0, 0.0, 0.0) + // Transparent fragments still write depth. That is normally + // invisible, but an embedded vector canvas can contain page- + // sized geometry extending far beyond its widget clip; those + // zero-alpha fragments would then hide every lower-depth + // sibling drawn later in the pass. Discard outside the clip + // so both color and depth stay confined to the widget. + discard() } // geometry shadow mode: stroke_mult == -2.0 // v interpolates 1.0 (edge) to 0.0 (3*blur out), stroke_dist = blur diff --git a/libs/score_ui/Cargo.toml b/libs/score_ui/Cargo.toml index 393b323c7..c1ffb582e 100644 --- a/libs/score_ui/Cargo.toml +++ b/libs/score_ui/Cargo.toml @@ -13,9 +13,12 @@ makepad-widgets = { path = "../../widgets", version = "2.0.0" } makepad-score = { path = "../score", version = "1.0.0" } makepad-score-layout = { path = "../score_layout", version = "0.1.0" } makepad-score-render = { path = "../score_render", version = "0.1.0" } +makepad-score-view = { path = "../score_view", version = "0.1.0" } makepad-score-play = { path = "../score_play", version = "0.1.0" } makepad-soundfont = { path = "../soundfont", version = "0.1.0" } makepad-piano-model = { path = "../piano_model", version = "0.1.0" } makepad-score-import = { path = "../score_import", version = "1.0.0" } -ttf-parser = { path = "../ttf-parser" } + +[dev-dependencies] +makepad-midi-file = { path = "../midi_file", version = "1.0.0" } diff --git a/libs/score_ui/src/document.rs b/libs/score_ui/src/document.rs index 6c30f7c53..be8e7103e 100644 --- a/libs/score_ui/src/document.rs +++ b/libs/score_ui/src/document.rs @@ -38,29 +38,8 @@ pub fn with_native_extension(path: &Path) -> PathBuf { } const ACTOR: u64 = 0x5c0e; -const NOTE_SEMANTIC_TAG: u64 = 0x1000_0000_0000_0000; -const MEASURE_SEMANTIC_TAG: u64 = 0x2000_0000_0000_0000; -pub(crate) const DECORATION_TAG: u64 = 0x8000_0000_0000_0000; - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum SemanticKind { - Note, - Measure, -} - -#[derive(Clone, Debug)] -pub struct SemanticElement { - pub semantic: SemanticId, - pub kind: SemanticKind, - pub note: Option, - pub event: Option, - pub measure: MeasureId, - pub staff: StaffId, - pub voice: VoiceId, - pub page: usize, - pub bounds: makepad_score_render::Rect, - pub midi: Option, -} +pub use makepad_score_view::document::{SemanticElement, SemanticKind}; +use makepad_score_view::document::semantic_for_note; #[derive(Clone, Debug)] pub struct AnnotationVisual { @@ -1461,7 +1440,8 @@ impl ScoreDocument { for page in 0..self.spacing.page_count() { let (list, elements) = { let placement = &self.spacing.pages()[page]; - crate::engrave::make_page(self.workspace.score(), placement, page, self.frame)? + crate::engrave::make_page(self.workspace.score(), placement, page, self.frame) + .map_err(|error| DocumentError::Native(error.to_string()))? }; let list = Arc::new(list); self.cache.insert(list.clone(), self.frame); @@ -1483,7 +1463,8 @@ impl ScoreDocument { .retain(|_, semantic| self.elements.contains_key(semantic)); let (list, elements) = { let placement = &self.spacing.pages()[page]; - crate::engrave::make_page(self.workspace.score(), placement, page, self.frame)? + crate::engrave::make_page(self.workspace.score(), placement, page, self.frame) + .map_err(|error| DocumentError::Native(error.to_string()))? }; let list = Arc::new(list); self.cache.insert(list.clone(), self.frame); @@ -1506,16 +1487,6 @@ impl ScoreDocument { } } -pub(crate) fn semantic_for_note(id: makepad_score::model::NoteId) -> SemanticId { - let (actor, counter) = id.raw(); - SemanticId(NOTE_SEMANTIC_TAG | counter ^ actor.rotate_left(17)) -} - -pub(crate) fn semantic_for_measure(id: MeasureId) -> SemanticId { - let (actor, counter) = id.raw(); - SemanticId(MEASURE_SEMANTIC_TAG | counter ^ actor.rotate_left(11)) -} - /// Written duration as a musician reads it. fn duration_label(duration: Option) -> String { let Some(duration) = duration else { diff --git a/libs/score_ui/src/engrave.rs b/libs/score_ui/src/engrave.rs index eb8cfad07..1e89a1092 100644 --- a/libs/score_ui/src/engrave.rs +++ b/libs/score_ui/src/engrave.rs @@ -1,1763 +1,3 @@ -//! Page engraving: turns the semantic score into one retained paint page. -//! -//! Everything here is in staff spaces, page-local, y down. The vertical -//! placement of a note is diatonic — a staff step is half a staff space — and -//! all glyph metrics (notehead width, stem attachment, ledger extension, beam -//! thickness) come from the loaded SMuFL font rather than from constants. +//! Compatibility re-exports for the shared engraver. -use crate::document::{ - pitch_to_midi, semantic_for_measure, semantic_for_note, DocumentError, SemanticElement, - SemanticKind, DECORATION_TAG, PAGE_HEIGHT_SP, PAGE_WIDTH_SP, -}; -use crate::font::{music_font, Engraving, MusicFont}; -use crate::spacing::{MeasurePlacement, PagePlacement}; -use makepad_score::{ - model::{ - EventKind, KeySignature, Measure, Meter, Notehead, Pitch, Rational, Score, - ScoreTime, StaffId, TimedEvent, VoiceId, - }, - symbol::{ - Accidental, Direction, FlagDuration, NoteheadDuration, NoteheadShape, - Placement, Symbol, - }, -}; -use makepad_score_layout::LayoutStyle; -use makepad_score_render::{ - Beam, GlyphItem, Ink, InkRole, LinearRgba, MusicFontRef, PageId, PaintItem, PaintKind, - PaintList, Point, Primitive, Rect, RuleKind, SemanticId, SmuflGlyph, TextDirection, - TextFontRef, TextRun, -}; -use std::sync::Arc; - -/// One em is four staff spaces in every SMuFL font. -const EM_SIZE: f64 = 4.0; -/// Distance from the top staff line of the upper staff to that of the lower. -const STAFF_GAP: f64 = 14.0; -/// Top staff line of the upper staff to bottom staff line of the lower. -pub(crate) const STAFF_SPAN: f64 = STAFF_GAP + 4.0; -pub(crate) const MARGIN_LEFT: f64 = 17.0; -pub(crate) const MARGIN_RIGHT: f64 = 14.0; -/// Shortest stem, in staff spaces, measured from the notehead centre. -const STEM_LENGTH: f64 = 3.5; -const BEAM_MIN_STEM: f64 = 3.0; - -/// Which staff of the grand staff a note is being drawn on. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -enum StaffRole { - Upper, - Lower, -} - -/// A five-line staff placed on the page, with its clef. -#[derive(Clone, Copy, Debug)] -pub(crate) struct StaffFrame { - /// Page y of the top staff line. - pub(crate) top: f64, - clef: &'static str, - /// Page y of the line the clef's origin sits on. - clef_line: f64, - /// Diatonic index (octave * 7 + step) of the pitch on the middle line. - pub(crate) middle_diatonic: i32, - /// Staff steps to shift a key signature by, relative to a treble staff. - key_shift: i8, -} - -/// The grand staff of one system, given the page y of its top staff line. -pub(crate) fn staff_frames(top: f64) -> [StaffFrame; 2] { - [StaffFrame::treble(top), StaffFrame::bass(top + STAFF_GAP)] -} - -impl StaffFrame { - fn treble(top: f64) -> Self { - Self { - top, - clef: "gClef", - clef_line: top + 3.0, - // B4 sits on the middle line of a treble staff. - middle_diatonic: 4 * 7 + 6, - key_shift: 0, - } - } - - fn bass(top: f64) -> Self { - Self { - top, - clef: "fClef", - clef_line: top + 1.0, - // D3 sits on the middle line of a bass staff. - middle_diatonic: 3 * 7 + 1, - key_shift: -2, - } - } - - fn middle(self) -> f64 { - self.top + 2.0 - } - - fn bottom(self) -> f64 { - self.top + 4.0 - } - - /// Page y of a diatonic pitch position on this staff. - pub(crate) fn y_of(self, diatonic: i32) -> f64 { - self.middle() - f64::from(diatonic - self.middle_diatonic) * 0.5 - } -} - -/// The written form of one duration. -#[derive(Clone, Copy, Debug, PartialEq)] -pub(crate) struct NoteValue { - /// 0 = whole, 1 = half, 2 = quarter, 3 = eighth, ... - power: u8, - pub(crate) dots: u8, -} - -impl NoteValue { - fn flags(self) -> u8 { - self.power.saturating_sub(2) - } - - fn notehead(self, notehead: &Notehead) -> Symbol { - let duration = match self.power { - 0 => NoteheadDuration::Whole, - 1 => NoteheadDuration::Half, - _ => NoteheadDuration::Black, - }; - let shape = match notehead { - Notehead::X => NoteheadShape::X, - Notehead::Diamond => NoteheadShape::Diamond, - Notehead::Triangle => NoteheadShape::TriangleUp, - Notehead::Slash => NoteheadShape::Slash, - _ => NoteheadShape::Normal, - }; - Symbol::Notehead { duration, shape } - } - - fn has_stem(self) -> bool { - self.power >= 1 - } -} - -/// One notehead inside a chord column. -#[derive(Clone, Debug)] -pub(crate) struct HeadLayout { - note: makepad_score::model::NoteId, - midi: u8, - diatonic: i32, - y: f64, - pub(crate) glyph: String, - pub(crate) accidental: Option, - /// Seconds are offset to the far side of the stem. - pub(crate) shifted: bool, -} - -/// One rhythmic column: a chord (or single note) of one voice. -#[derive(Clone, Debug)] -pub(crate) struct Column { - event: makepad_score::model::EventId, - measure: makepad_score::model::MeasureId, - voice: VoiceId, - staff: StaffId, - /// Onset in whole notes from the start of the score. - onset: f64, - /// The same onset, exactly: the key columns are merged on. - pub(crate) time: ScoreTime, - /// Page x of the unshifted notehead's left edge, filled in from the - /// spacing plan once the system's springs are solved. - x: f64, - pub(crate) heads: Vec, - pub(crate) value: NoteValue, - pub(crate) stem_up: bool, - articulations: Vec, -} - -impl Column { - pub(crate) fn top_y(&self) -> f64 { - self.heads - .iter() - .map(|head| head.y) - .fold(f64::INFINITY, f64::min) - } - - pub(crate) fn bottom_y(&self) -> f64 { - self.heads - .iter() - .map(|head| head.y) - .fold(f64::NEG_INFINITY, f64::max) - } - - /// The notehead the stem starts from. - fn stem_origin_y(&self) -> f64 { - if self.stem_up { - self.bottom_y() - } else { - self.top_y() - } - } - - /// The notehead the stem has to clear. - fn stem_far_y(&self) -> f64 { - if self.stem_up { - self.top_y() - } else { - self.bottom_y() - } - } -} - -/// Accumulates paint items and hands out decoration IDs. -struct PageBuilder<'a> { - font: &'static MusicFont, - engraving: Engraving, - items: Vec, - elements: Vec, - decoration: u64, - page_index: usize, - score: &'a Score, -} - -impl PageBuilder<'_> { - fn next_decor(&mut self) -> SemanticId { - self.decoration = self.decoration.saturating_add(1); - SemanticId(self.decoration) - } - - fn glyph(&mut self, id: SemanticId, name: &str, origin: Point, ink: Ink, z: i16) -> bool { - if !self.font.has(name) { - return false; - } - let bbox = self.font.bbox(name); - // The font box is y-up around the origin; the page is y-down. - let bounds = Rect::new( - Point::new(origin.x + bbox.min_x, origin.y - bbox.max_y), - Point::new(origin.x + bbox.max_x, origin.y - bbox.min_y), - ); - self.items.push(PaintItem { - id, - bounds, - z, - ink, - kind: PaintKind::Glyph(GlyphItem { - font: MusicFontRef(0), - glyph: SmuflGlyph::new(name.to_string()), - origin, - em_size: EM_SIZE, - }), - }); - true - } - - fn decor_glyph(&mut self, name: &str, origin: Point) { - let id = self.next_decor(); - self.glyph(id, name, origin, Ink::role(InkRole::Primary), 2); - } - - fn rule(&mut self, rect: Rect, kind: RuleKind, ink: Ink, z: i16) { - let id = self.next_decor(); - self.items - .push(PaintItem::primitive(id, z, ink, Primitive::Rule { - rect, - kind, - staff_group: None, - })); - } - - fn beam(&mut self, start: Point, end: Point, thickness: f64) { - let id = self.next_decor(); - self.items.push(PaintItem::primitive( - id, - 2, - Ink::role(InkRole::Primary), - Primitive::Beam(Beam { - start, - end, - thickness, - }), - )); - } - - /// One centred run. The width is *measured*, not estimated: it decides - /// both the item's bounds and where the run starts, so a guess is a run - /// drawn off centre — and, for the title, off the page. - fn text(&mut self, text: impl Into>, origin: Point, size: f64, z: i16) { - let id = self.next_decor(); - let text = text.into(); - let width = crate::title::text_width_sp(&text, size).max(size * 0.5); - self.items.push(PaintItem { - id, - bounds: Rect::from_xywh( - origin.x - width * 0.5, - origin.y, - width, - crate::title::line_box_sp(size), - ), - z, - ink: Ink::role(InkRole::Secondary), - kind: PaintKind::Text(TextRun { - font: TextFontRef(0), - text, - origin: Point::new(origin.x - width * 0.5, origin.y), - size, - letter_spacing: 0.0, - direction: TextDirection::Auto, - language: None, - }), - }); - } -} - -/// Engraves one page of the score from its solved placement. -/// -/// Every x here comes from the spacing plan: the page tells this function -/// where each system, measure and onset column landed once the spring-and-rod -/// chain was solved to the system width. Nothing is divided up locally. -pub fn make_page( - score: &Score, - page: &PagePlacement, - page_index: usize, - revision: u64, -) -> Result<(PaintList, Vec), DocumentError> { - let font = music_font(); - let style = LayoutStyle::default(); - let mut builder = PageBuilder { - font, - engraving: font.engraving(), - items: Vec::new(), - elements: Vec::new(), - decoration: DECORATION_TAG | ((page_index as u64 + 1) << 40), - page_index, - score, - }; - - if page_index == 0 { - // The instrumentation is the score's own part list, not a guess. - let parts: Vec<&str> = score - .parts - .values() - .map(|part| part.name.as_str()) - .filter(|name| !name.trim().is_empty()) - .collect(); - let subtitle = if parts.is_empty() { - String::new() - } else { - format!("for {}", parts.join(", ")) - }; - // Fitted, not fixed: a long title shrinks and then wraps rather than - // running off both edges of the page. - let block = crate::title::title_block(&score.title, &subtitle); - for line in block.lines() { - builder.text( - line.text.clone(), - Point::new(PAGE_WIDTH_SP * 0.5, line.top), - line.size, - 1, - ); - } - } - - let measures = crate::spacing::ordered_measures(score); - for (index, system) in page.systems.iter().enumerate() { - let Some(first) = system.measures.first() else { - continue; - }; - let Some(&measure) = measures.get(first.index) else { - continue; - }; - let staves = staff_frames(system.top); - let right = system - .measures - .last() - .map(|last| last.right) - .unwrap_or(system.right); - draw_system_frame(&mut builder, &staves, index, right); - - let key = score - .maps - .key_at(measure.start, None, None) - .cloned() - .unwrap_or(KeySignature::C_MAJOR); - let meter = score.maps.meter_at(measure.start, None, None).cloned(); - draw_system_prefix( - &mut builder, - &staves, - &key, - meter.as_ref().filter(|_| system.show_meter), - &style, - ); - - for placement in &system.measures { - let Some(&measure) = measures.get(placement.index) else { - continue; - }; - draw_measure( - &mut builder, - &staves, - measure, - &key, - placement, - placement.index == first.index, - placement.index + 1 == measures.len(), - ); - } - } - - builder.text( - (page_index + 1).to_string(), - Point::new(PAGE_WIDTH_SP * 0.5, PAGE_HEIGHT_SP - 7.0), - 1.8, - 1, - ); - - let list = PaintList::new( - PageId(page_index as u32), - revision, - Point::new(PAGE_WIDTH_SP, PAGE_HEIGHT_SP), - builder.items, - ) - .map_err(|error| DocumentError::Native(error.to_string()))?; - Ok((list, builder.elements)) -} - -fn draw_system_frame( - builder: &mut PageBuilder<'_>, - staves: &[StaffFrame; 2], - system: usize, - right: f64, -) { - let staff_ink = Ink::role(InkRole::Staff); - let thickness = builder.engraving.staff_line_thickness; - let left = MARGIN_LEFT; - for (index, staff) in staves.iter().enumerate() { - let group = system as u32 * 2 + index as u32 + 1; - for line in 0..5 { - let rect = Rect::from_xywh(left, staff.top + line as f64, right - left, thickness); - let id = builder.next_decor(); - builder.items.push(PaintItem::primitive( - id, - 0, - staff_ink, - Primitive::Rule { - rect, - kind: RuleKind::Staff, - staff_group: Some(group), - }, - )); - } - } - // The brace-substitute bracket plus the left-hand system barline. - let id = builder.next_decor(); - builder.items.push(PaintItem::primitive( - id, - 1, - Ink::role(InkRole::Primary), - Primitive::Bracket { - x: left - 1.3, - top: staves[0].top, - bottom: staves[1].bottom(), - thickness: builder.engraving.bracket_thickness * 0.5, - hook: 1.0, - }, - )); - let thin = builder.engraving.thin_barline_thickness; - builder.rule( - Rect::from_xywh(left, staves[0].top, thin, staves[1].bottom() - staves[0].top), - RuleKind::BarlineThin, - Ink::role(InkRole::Primary), - 1, - ); -} - -/// The geometry of a system prefix: clef, key signature and — on the score's -/// first system only — the time signature. -/// -/// The planner and the engraver share this so that "where music starts" is -/// one number computed once. All distances are style constants, not -/// hand-tuned literals. -struct Prefix { - clef_x: f64, - accidental: Option, - accidental_x: Vec, - meter: Option, - /// Distance from the left margin to the end of the prefix. - width: f64, -} - -struct MeterPrefix { - numerator: Vec, - denominator: Vec, - x: f64, - span: f64, -} - -fn prefix_layout( - font: &MusicFont, - key: &KeySignature, - meter: Option<&Meter>, - style: &LayoutStyle, -) -> Prefix { - let distance = &style.distance; - let mut cursor = distance.clef_left_margin.0; - let clef_x = cursor; - let clef = font.advance("gClef").max(font.advance("fClef")); - cursor += clef + distance.clef_to_key.0; - - let steps = key_signature_steps(key.fifths); - let mut accidental = None; - let mut accidental_x = Vec::new(); - if !steps.is_empty() { - let glyph = if key.fifths > 0 { - Symbol::Accidental(Accidental::Sharp) - } else { - Symbol::Accidental(Accidental::Flat) - } - .canonical_name() - .to_string(); - let advance = font.advance(&glyph).max(0.7) + distance.accidental_column.0; - for index in 0..steps.len() { - accidental_x.push(cursor + index as f64 * advance); - } - cursor += advance * steps.len() as f64; - accidental = Some(glyph); - } - - let meter = match meter { - Some(Meter::Measured { groups, unit }) => { - cursor += distance.key_to_time.0; - let beats: u32 = groups.iter().map(|group| u32::from(*group)).sum(); - let numerator: Vec = digits_of(beats) - .iter() - .map(|digit| digit.canonical_name().to_string()) - .collect(); - let denominator: Vec = digits_of(u32::from(*unit)) - .iter() - .map(|digit| digit.canonical_name().to_string()) - .collect(); - let run = |names: &[String]| -> f64 { names.iter().map(|name| font.advance(name)).sum() }; - let span = run(&numerator).max(run(&denominator)); - let at = cursor; - cursor += span; - Some(MeterPrefix { - numerator, - denominator, - x: at, - span, - }) - } - _ => None, - }; - - Prefix { - clef_x, - accidental, - accidental_x, - meter, - width: cursor, - } -} - -/// Distance from the left margin to where a system's music may start. -pub(crate) fn prefix_width( - font: &MusicFont, - key: &KeySignature, - meter: Option<&Meter>, - style: &LayoutStyle, -) -> f64 { - prefix_layout(font, key, meter, style).width -} - -/// Clef, key signature and (only where it belongs) time signature. -fn draw_system_prefix( - builder: &mut PageBuilder<'_>, - staves: &[StaffFrame; 2], - key: &KeySignature, - meter: Option<&Meter>, - style: &LayoutStyle, -) { - let prefix = prefix_layout(builder.font, key, meter, style); - let steps = key_signature_steps(key.fifths); - for staff in staves { - builder.decor_glyph(staff.clef, Point::new(MARGIN_LEFT + prefix.clef_x, staff.clef_line)); - if let Some(glyph) = &prefix.accidental { - let glyph = glyph.clone(); - for (step, x) in steps.iter().zip(&prefix.accidental_x) { - let y = staff.middle() - f64::from(*step + staff.key_shift) * 0.5; - builder.decor_glyph(&glyph, Point::new(MARGIN_LEFT + x, y)); - } - } - if let Some(meter) = &prefix.meter { - for (digits, line) in [(&meter.numerator, 1.0), (&meter.denominator, 3.0)] { - let run: f64 = digits.iter().map(|name| builder.font.advance(name)).sum(); - let mut x = MARGIN_LEFT + meter.x + (meter.span - run) * 0.5; - for name in digits { - let name = name.clone(); - builder.decor_glyph(&name, Point::new(x, staff.top + line)); - x += builder.font.advance(&name); - } - } - } - } -} - -fn digits_of(value: u32) -> Vec { - use makepad_score::symbol::Digit; - let digit = |value: u32| match value { - 0 => Digit::Zero, - 1 => Digit::One, - 2 => Digit::Two, - 3 => Digit::Three, - 4 => Digit::Four, - 5 => Digit::Five, - 6 => Digit::Six, - 7 => Digit::Seven, - 8 => Digit::Eight, - _ => Digit::Nine, - }; - value - .to_string() - .chars() - .filter_map(|character| character.to_digit(10)) - .map(|value| Symbol::TimeSignatureDigit(digit(value))) - .collect() -} - -/// Diatonic offsets from the middle line, in staff steps, for the accidentals -/// of a key signature on a treble staff. A bass staff is two steps lower. -fn key_signature_steps(fifths: i8) -> Vec { - const SHARPS: [i8; 7] = [4, 1, 5, 2, -1, 3, 0]; - const FLATS: [i8; 7] = [0, 3, -1, 2, -2, 1, -3]; - let count = fifths.unsigned_abs().min(7) as usize; - if fifths > 0 { - SHARPS[..count].to_vec() - } else { - FLATS[..count].to_vec() - } -} - -fn draw_measure( - builder: &mut PageBuilder<'_>, - staves: &[StaffFrame; 2], - measure: &Measure, - key: &KeySignature, - placement: &MeasurePlacement, - first_in_system: bool, - last_of_score: bool, -) { - let (x0, x1) = (placement.left, placement.right); - let measure_semantic = semantic_for_measure(measure.id); - let bounds = Rect::from_xywh( - x0, - staves[0].top - 3.0, - x1 - x0, - staves[1].bottom() - staves[0].top + 6.0, - ); - builder.items.push(PaintItem::primitive( - measure_semantic, - -2, - Ink::color(InkRole::Selection, LinearRgba::new(0.0, 0.0, 0.0, 0.0)), - Primitive::Rule { - rect: bounds, - kind: RuleKind::Staff, - staff_group: None, - }, - )); - let score = builder.score; - if let (Some(voice), Some(staff)) = ( - score.voices.values().next().map(|voice| voice.id), - score.staves.values().next().map(|staff| staff.id), - ) { - builder.elements.push(SemanticElement { - semantic: measure_semantic, - kind: SemanticKind::Measure, - note: None, - event: None, - measure: measure.id, - staff, - voice, - page: builder.page_index, - bounds, - midi: None, - }); - } - if first_in_system { - builder.text( - measure.label.clone(), - Point::new(x0 + 0.9, staves[0].top - 1.4), - 1.5, - 1, - ); - } - - // One barline through the whole grand staff reads as one system. - let thin = builder.engraving.thin_barline_thickness; - let height = staves[1].bottom() - staves[0].top; - if last_of_score { - let thick = builder.engraving.thick_barline_thickness; - let separation = 0.4; - builder.rule( - Rect::from_xywh(x1 - thick - separation - thin, staves[0].top, thin, height), - RuleKind::BarlineThin, - Ink::role(InkRole::Primary), - 1, - ); - builder.rule( - Rect::from_xywh(x1 - thick, staves[0].top, thick, height), - RuleKind::BarlineThick, - Ink::role(InkRole::Primary), - 1, - ); - } else { - builder.rule( - Rect::from_xywh(x1 - thin, staves[0].top, thin, height), - RuleKind::BarlineThin, - Ink::role(InkRole::Primary), - 1, - ); - } - - let staves_columns = measure_staff_columns(builder.font, builder.score, measure, key, staves); - for (staff_frame, voices) in staves.iter().zip(&staves_columns) { - if voices.is_empty() { - draw_measure_rest(builder, *staff_frame, (x0 + x1) * 0.5); - continue; - } - for columns in voices { - // Every column takes its x from the solved system chain; nothing - // is spread out locally. - let mut columns = columns.clone(); - for column in &mut columns { - column.x = placement.x_of(column.time); - } - draw_columns(builder, *staff_frame, measure, &columns); - } - } -} - -/// One measure's columns, per staff of the grand staff and then per active -/// voice. An empty voice list means that staff rests for the whole measure. -/// -/// Both the spacing pass (which measures the ink) and the engraving pass -/// (which draws it) go through here, so the rods the solver sees describe the -/// glyphs that actually get drawn. -pub(crate) fn measure_staff_columns( - font: &'static MusicFont, - score: &Score, - measure: &Measure, - key: &KeySignature, - staves: &[StaffFrame; 2], -) -> [Vec>; 2] { - let mut out = [Vec::new(), Vec::new()]; - let Some(part) = score.parts.values().next() else { - return out; - }; - let measure_end = measure - .start - .checked_add(measure.extent) - .unwrap_or(measure.start); - let upper = part.staves.first().copied(); - for (slot, (role, staff_frame)) in - [(StaffRole::Upper, staves[0]), (StaffRole::Lower, staves[1])] - .into_iter() - .enumerate() - { - let staff_ids: Vec = part - .staves - .iter() - .copied() - .filter(|id| { - let is_upper = Some(*id) == upper; - (role == StaffRole::Upper) == is_upper - }) - .collect(); - let active: Vec<&makepad_score::model::Voice> = score - .voices - .values() - .filter(|voice| staff_ids.contains(&voice.staff)) - .filter(|voice| { - voice - .events - .iter() - .any(|event| in_measure(event, measure.start, measure_end)) - }) - .collect(); - let multi_voice = active.len() > 1; - for (voice_index, voice) in active.iter().enumerate() { - out[slot].push(build_columns( - font, - staff_frame, - voice, - measure, - measure_end, - key, - if multi_voice { - Some(voice_index == 0) - } else { - None - }, - )); - } - } - out -} - -fn in_measure(event: &TimedEvent, start: ScoreTime, end: ScoreTime) -> bool { - matches!(event.kind, EventKind::Chord(_)) - && !event.chord_notes().is_empty() - && event.onset >= start - && event.onset < end -} - -fn draw_measure_rest(builder: &mut PageBuilder<'_>, staff: StaffFrame, center_x: f64) { - let name = Symbol::Rest(makepad_score::symbol::RestDuration::Whole) - .canonical_name() - .to_string(); - let width = builder.font.bbox(&name).width(); - // A whole-measure rest hangs from the second line from the top. - builder.decor_glyph(&name, Point::new(center_x - width * 0.5, staff.top + 1.0)); -} - -/// One voice's columns for one measure, everything but their x: pitches, -/// written note values, stem directions, accidentals and second-interval -/// head shifts. The x arrives later, from the solved spacing chain. -fn build_columns( - font: &'static MusicFont, - staff: StaffFrame, - voice: &makepad_score::model::Voice, - measure: &Measure, - measure_end: ScoreTime, - key: &KeySignature, - forced_stem_up: Option, -) -> Vec { - let mut state = KeyState::new(key); - let mut columns = Vec::new(); - - let events: Vec<&TimedEvent> = voice - .events - .iter() - .filter(|event| in_measure(event, measure.start, measure_end)) - .collect(); - for (index, event) in events.iter().enumerate() { - // A performance import carries sounding lengths, not written ones: a - // staccato sixteenth is stored as a thirty-second. Writing each note up - // to the next onset recovers the notated rhythm, and cannot overstate a - // note, because this engraver has no rests to put in the gap. - let remaining = measure_end - .checked_sub(event.onset) - .map(|time| rational_f64(time.0)) - .unwrap_or(0.0); - let sounding = event - .duration - .map(|duration| rational_f64(duration.0)) - .unwrap_or(0.0); - let written = match events.get(index + 1) { - Some(next) => next - .onset - .checked_sub(event.onset) - .map(|time| rational_f64(time.0)) - .unwrap_or(sounding), - // The last note of the measure keeps its own length: there is no - // following onset to measure against. - None => sounding.min(remaining), - }; - let value = note_value_of(if written > 0.0 { written } else { sounding }); - let mut heads: Vec = Vec::new(); - for note in event.chord_notes() { - let Some(pitch) = note.written_pitch else { - continue; - }; - let diatonic = diatonic_index(pitch); - let accidental = state.accidental_for(pitch, diatonic); - heads.push(HeadLayout { - note: note.id, - midi: pitch_to_midi(pitch), - diatonic, - y: staff.y_of(diatonic), - glyph: value.notehead(¬e.notehead).canonical_name().to_string(), - accidental, - shifted: false, - }); - } - if heads.is_empty() { - continue; - } - heads.sort_by(|a, b| a.diatonic.cmp(&b.diatonic)); - heads.dedup_by(|a, b| a.diatonic == b.diatonic); - - let average = heads.iter().map(|head| head.diatonic).sum::() as f64 - / heads.len() as f64; - let stem_up = forced_stem_up - .unwrap_or_else(|| average < f64::from(staff.middle_diatonic) + 0.01); - // Seconds cannot share a side of the stem. - let mut previous: Option = None; - let mut previous_shifted = false; - let order: Vec = if stem_up { - (0..heads.len()).collect() - } else { - (0..heads.len()).rev().collect() - }; - for index in order { - let diatonic = heads[index].diatonic; - let shifted = previous - .map(|previous_diatonic| (diatonic - previous_diatonic).abs() == 1) - .unwrap_or(false) - && !previous_shifted; - heads[index].shifted = shifted; - previous = Some(diatonic); - previous_shifted = shifted; - } - - let articulations = event - .articulations - .iter() - .filter_map(|placed| { - let placement = if stem_up { - Placement::Below - } else { - Placement::Above - }; - let symbol = Symbol::Articulation { - articulation: placed.kind, - placement, - }; - let name = symbol.canonical_name().to_string(); - font.has(&name).then_some(name) - }) - .collect(); - - columns.push(Column { - event: event.id, - measure: measure.id, - voice: voice.id, - onset: rational_f64(event.onset.0), - time: event.onset, - staff: voice.staff, - x: 0.0, - heads, - value, - stem_up, - articulations, - }); - } - columns.sort_by(|a, b| a.onset.total_cmp(&b.onset)); - columns -} - -/// Tracks which accidentals are already sounding in the current measure. -struct KeyState { - signature: [i32; 7], - current: std::collections::BTreeMap, -} - -impl KeyState { - fn new(key: &KeySignature) -> Self { - let mut signature = [0_i32; 7]; - let sharp_order = [3_usize, 0, 4, 1, 5, 2, 6]; - let flat_order = [6_usize, 2, 5, 1, 4, 0, 3]; - let count = key.fifths.unsigned_abs().min(7) as usize; - if key.fifths > 0 { - for step in &sharp_order[..count] { - signature[*step] = 1; - } - } else { - for step in &flat_order[..count] { - signature[*step] = -1; - } - } - Self { - signature, - current: std::collections::BTreeMap::new(), - } - } - - fn accidental_for(&mut self, pitch: Pitch, diatonic: i32) -> Option { - let alter = (rational_f64(pitch.alter.0)).round() as i32; - let step = diatonic.rem_euclid(7) as usize; - let sounding = self - .current - .get(&diatonic) - .copied() - .unwrap_or(self.signature[step]); - if alter == sounding { - return None; - } - self.current.insert(diatonic, alter); - let accidental = match alter { - -3 => Accidental::TripleFlat, - -2 => Accidental::DoubleFlat, - -1 => Accidental::Flat, - 0 => Accidental::Natural, - 1 => Accidental::Sharp, - 2 => Accidental::DoubleSharp, - _ => Accidental::TripleSharp, - }; - Some(Symbol::Accidental(accidental).canonical_name().to_string()) - } -} - -fn draw_columns( - builder: &mut PageBuilder<'_>, - staff: StaffFrame, - measure: &Measure, - columns: &[Column], -) { - let groups = beam_groups(builder.score, measure, columns); - let mut beamed = vec![false; columns.len()]; - for group in &groups { - for index in group { - beamed[*index] = true; - } - } - for (index, column) in columns.iter().enumerate() { - draw_column_heads(builder, staff, column); - if !column.value.has_stem() { - continue; - } - if beamed[index] { - continue; - } - let tip = unbeamed_stem_tip(staff, column); - draw_stem(builder, column, tip); - let flags = column.value.flags(); - if flags > 0 { - draw_flag(builder, column, tip, flags); - } - } - for group in &groups { - draw_beam_group(builder, staff, columns, group); - } -} - -fn draw_column_heads(builder: &mut PageBuilder<'_>, staff: StaffFrame, column: &Column) { - let head_width = builder.font.bbox("noteheadBlack").width(); - let extension = builder.engraving.leger_line_extension; - let ledger_thickness = builder.engraving.leger_line_thickness; - let mut ledgers: Vec<(f64, f64, f64)> = Vec::new(); - - for head in &column.heads { - let width = builder.font.bbox(&head.glyph).width().max(0.1); - let shift = if head.shifted { - if column.stem_up { - head_width - } else { - -head_width - } - } else { - 0.0 - }; - let x = column.x + shift; - let semantic = semantic_for_note(head.note); - let bounds = Rect::new( - Point::new(x, head.y - 0.5), - Point::new(x + width, head.y + 0.5), - ); - let drawn = builder.glyph( - semantic, - &head.glyph, - Point::new(x, head.y), - Ink::role(InkRole::Primary), - 2, - ); - if drawn { - builder.elements.push(SemanticElement { - semantic, - kind: SemanticKind::Note, - note: Some(head.note), - event: Some(column.event), - measure: column.measure, - staff: column.staff, - voice: column.voice, - page: builder.page_index, - bounds, - midi: Some(head.midi), - }); - } - if let Some(accidental) = &head.accidental { - let accidental_width = builder.font.advance(accidental).max(0.6); - builder.decor_glyph( - accidental, - Point::new(x - accidental_width - 0.22, head.y), - ); - } - // Ledger lines: one for every staff position outside the five lines. - let mut line = staff.top - 1.0; - while line >= head.y - 0.01 { - ledgers.push((line, x, width)); - line -= 1.0; - } - let mut line = staff.bottom() + 1.0; - while line <= head.y + 0.01 { - ledgers.push((line, x, width)); - line += 1.0; - } - if column.value.dots > 0 { - let mut dot_y = head.y; - if (head.y - staff.top).rem_euclid(1.0).abs() < 0.01 { - dot_y -= 0.5; - } - let dot_width = builder.font.advance("augmentationDot").max(0.3); - for dot in 0..column.value.dots { - builder.decor_glyph( - "augmentationDot", - Point::new( - x + width + 0.32 + f64::from(dot) * dot_width * 1.1, - dot_y, - ), - ); - } - } - } - - ledgers.sort_by(|a, b| a.0.total_cmp(&b.0).then(a.1.total_cmp(&b.1))); - ledgers.dedup_by(|a, b| (a.0 - b.0).abs() < 0.01 && (a.1 - b.1).abs() < 0.01); - for (y, x, width) in ledgers { - builder.rule( - Rect::from_xywh( - x - extension, - y - ledger_thickness * 0.5, - width + extension * 2.0, - ledger_thickness, - ), - RuleKind::Ledger, - Ink::role(InkRole::Primary), - 1, - ); - } - - for (index, articulation) in column.articulations.iter().enumerate() { - let bbox = builder.font.bbox(articulation); - let width = bbox.width().max(0.2); - let x = column.x + head_width * 0.5 - width * 0.5; - let y = if column.stem_up { - column.bottom_y() + 0.9 + index as f64 * 0.6 - } else { - column.top_y() - 0.9 - index as f64 * 0.6 - }; - builder.decor_glyph(articulation, Point::new(x, y)); - } -} - -fn unbeamed_stem_tip(staff: StaffFrame, column: &Column) -> f64 { - let extra = f64::from(column.value.flags().saturating_sub(1)) * 0.5; - if column.stem_up { - (column.stem_far_y() - STEM_LENGTH - extra).min(staff.middle()) - } else { - (column.stem_far_y() + STEM_LENGTH + extra).max(staff.middle()) - } -} - -/// Page x of the centre of a column's stem, from the font's own anchor. -fn stem_x(builder: &PageBuilder<'_>, column: &Column) -> f64 { - let thickness = builder.engraving.stem_thickness; - let glyph = column - .heads - .first() - .map(|head| head.glyph.clone()) - .unwrap_or_else(|| "noteheadBlack".to_string()); - if column.stem_up { - column.x + builder.font.stem_up_se(&glyph).0 - thickness * 0.5 - } else { - column.x + builder.font.stem_down_nw(&glyph).0 + thickness * 0.5 - } -} - -fn draw_stem(builder: &mut PageBuilder<'_>, column: &Column, tip: f64) { - let thickness = builder.engraving.stem_thickness; - let glyph = column - .heads - .first() - .map(|head| head.glyph.clone()) - .unwrap_or_else(|| "noteheadBlack".to_string()); - let center = stem_x(builder, column); - let attach = if column.stem_up { - column.stem_origin_y() - builder.font.stem_up_se(&glyph).1 - } else { - column.stem_origin_y() - builder.font.stem_down_nw(&glyph).1 - }; - let (top, bottom) = if tip < attach { (tip, attach) } else { (attach, tip) }; - builder.rule( - Rect::from_xywh(center - thickness * 0.5, top, thickness, bottom - top), - RuleKind::Stem, - Ink::role(InkRole::Primary), - 2, - ); -} - -fn draw_flag(builder: &mut PageBuilder<'_>, column: &Column, tip: f64, flags: u8) { - let duration = match flags { - 1 => FlagDuration::Eighth, - 2 => FlagDuration::Sixteenth, - 3 => FlagDuration::ThirtySecond, - 4 => FlagDuration::SixtyFourth, - _ => FlagDuration::OneTwentyEighth, - }; - let direction = if column.stem_up { - Direction::Up - } else { - Direction::Down - }; - let name = Symbol::Flag { - duration, - direction, - } - .canonical_name() - .to_string(); - let thickness = builder.engraving.stem_thickness; - let x = stem_x(builder, column) - + if column.stem_up { - -thickness * 0.5 - } else { - -thickness * 0.5 - }; - builder.decor_glyph(&name, Point::new(x, tip)); -} - -/// Splits a measure's columns into beam groups: runs of two or more flagged -/// notes inside one metrical beat. -fn beam_groups(score: &Score, measure: &Measure, columns: &[Column]) -> Vec> { - let beat = beat_length(score, measure); - let measure_start = rational_f64(measure.start.0); - let mut groups: Vec> = Vec::new(); - let mut current: Vec = Vec::new(); - let mut current_beat: Option = None; - for (index, column) in columns.iter().enumerate() { - let beat_index = (((column.onset - measure_start) / beat) + 1e-6).floor() as i64; - let beamable = column.value.flags() > 0; - // Note: a played rest inside a beat does not break the group, because - // this engraver does not yet write rests between notes; grouping on the - // beat alone is what a performance import can honestly support. - if !beamable || current_beat != Some(beat_index) { - if current.len() > 1 { - groups.push(std::mem::take(&mut current)); - } else { - current.clear(); - } - } - if beamable { - current_beat = Some(beat_index); - current.push(index); - } else { - current_beat = None; - } - } - if current.len() > 1 { - groups.push(current); - } - groups -} - -/// The beaming unit: a beat, or a dotted beat in a compound meter. -fn beat_length(score: &Score, measure: &Measure) -> f64 { - let meter = score.maps.meter_at(measure.start, None, None); - match meter { - Some(Meter::Measured { groups, unit }) if *unit > 0 => { - let beats: u32 = groups.iter().map(|group| u32::from(*group)).sum(); - let unit_length = 1.0 / f64::from(*unit); - if *unit >= 8 && beats % 3 == 0 && beats > 3 { - unit_length * 3.0 - } else { - unit_length - } - } - _ => 0.25, - } -} - -fn draw_beam_group( - builder: &mut PageBuilder<'_>, - staff: StaffFrame, - columns: &[Column], - group: &[usize], -) { - if group.len() < 2 { - return; - } - // One direction for the whole group. Where a voice has already been given - // a direction (two voices sharing a staff), the beam must not fight it. - let forced = columns[group[0]].stem_up; - let agreed = group - .iter() - .all(|index| columns[*index].stem_up == forced); - let average = group - .iter() - .flat_map(|index| columns[*index].heads.iter().map(|head| head.diatonic)) - .sum::() as f64 - / group - .iter() - .map(|index| columns[*index].heads.len()) - .sum::() - .max(1) as f64; - let stem_up = if agreed { - forced - } else { - average < f64::from(staff.middle_diatonic) + 0.01 - }; - - let members: Vec = group - .iter() - .map(|index| Column { - stem_up, - ..columns[*index].clone() - }) - .collect(); - let xs: Vec = members - .iter() - .map(|column| stem_x(builder, column)) - .collect(); - let first_x = xs[0]; - let last_x = *xs.last().unwrap(); - let run = (last_x - first_x).max(0.001); - - let ideal = |column: &Column| -> f64 { - if stem_up { - column.stem_far_y() - STEM_LENGTH - } else { - column.stem_far_y() + STEM_LENGTH - } - }; - let first_ideal = ideal(&members[0]); - let last_ideal = ideal(members.last().unwrap()); - // A gentle, capped slope reads better than following the outer notes. - let slope = ((last_ideal - first_ideal) / run).clamp(-0.25, 0.25); - let cap = 1.5 / run; - let slope = slope.clamp(-cap, cap); - - let mut offset = if stem_up { f64::INFINITY } else { f64::NEG_INFINITY }; - for (column, x) in members.iter().zip(&xs) { - let limit = if stem_up { - column.stem_far_y() - BEAM_MIN_STEM - slope * (x - first_x) - } else { - column.stem_far_y() + BEAM_MIN_STEM - slope * (x - first_x) - }; - offset = if stem_up { - offset.min(limit) - } else { - offset.max(limit) - }; - } - // Keep the beam from crowding the staff on the far side. - let line_y = |x: f64| offset + slope * (x - first_x); - - let thickness = builder.engraving.beam_thickness; - let spacing = builder.engraving.beam_spacing; - let stem_thickness = builder.engraving.stem_thickness; - let inward = if stem_up { 1.0 } else { -1.0 }; - - for (column, x) in members.iter().zip(&xs) { - draw_stem(builder, column, line_y(*x)); - } - - let max_level = members - .iter() - .map(|column| column.value.flags()) - .max() - .unwrap_or(1) - .max(1); - for level in 0..max_level { - let dy = inward * (f64::from(level) * (thickness + spacing) + thickness * 0.5); - let mut index = 0; - while index < members.len() { - if members[index].value.flags() <= level { - index += 1; - continue; - } - let start = index; - while index < members.len() && members[index].value.flags() > level { - index += 1; - } - let end = index - 1; - if start == end { - if level == 0 { - continue; - } - // A lone short note inside the group takes a hook. - let x = xs[start]; - let hook = 1.0; - let toward_previous = start > 0; - let (from, to) = if toward_previous { - (x - hook, x + stem_thickness * 0.5) - } else { - (x - stem_thickness * 0.5, x + hook) - }; - builder.beam( - Point::new(from, line_y(from) + dy), - Point::new(to, line_y(to) + dy), - thickness, - ); - continue; - } - let from = xs[start] - stem_thickness * 0.5; - let to = xs[end] + stem_thickness * 0.5; - builder.beam( - Point::new(from, line_y(from) + dy), - Point::new(to, line_y(to) + dy), - thickness, - ); - } - } -} - -/// Reads a length in whole notes as a written note value: a power of two plus -/// augmentation dots. -fn note_value_of(value: f64) -> NoteValue { - if !(value > 0.0) { - return NoteValue { power: 2, dots: 0 }; - } - for power in 0..=7_u8 { - let base = 0.5_f64.powi(i32::from(power)); - for dots in 0..=2_u8 { - let scale = 2.0 - 0.5_f64.powi(i32::from(dots)); - if (value - base * scale).abs() < 1e-6 { - return NoteValue { power, dots }; - } - } - } - // Not a written value (a quantized import can produce these): take the - // largest note that fits, so the notehead and beaming stay sane. - let mut power = 0_u8; - while power < 7 && 0.5_f64.powi(i32::from(power)) > value + 1e-9 { - power += 1; - } - NoteValue { power, dots: 0 } -} - -fn diatonic_index(pitch: Pitch) -> i32 { - i32::from(pitch.octave) * 7 + i32::from(pitch.step.index()) -} - -fn rational_f64(value: Rational) -> f64 { - value.numerator() as f64 / value.denominator() as f64 -} - -#[cfg(test)] -pub(crate) mod tests { - use super::*; - use makepad_score::model::{ - Alter, Change, Duration, EventTag, FlowNode, IdGenerator, LayerTag, MapScope, MeasureTag, Note, - NoteTag, Part, PartTag, Staff, StaffKind, StaffTag, Step, Transposition, VoiceTag, - }; - use makepad_score_render::PaintKind; - - fn duration(numerator: i64, denominator: u64) -> f64 { - numerator as f64 / denominator as f64 - } - - /// A one-measure grand-staff score whose upper voice is `pitches`, each of - /// `note_denominator` length, starting on the downbeat. - pub(crate) fn fixture(pitches: &[(Step, i8)], note_denominator: u64) -> Score { - let events: Vec = pitches - .iter() - .enumerate() - .map(|(index, &(step, octave))| Placed { - onset: (index as i64, note_denominator), - duration: (1, note_denominator), - step, - octave, - }) - .collect(); - fixture_events(&events) - } - - /// One note of a test fixture: where it starts, how long it lasts, what - /// pitch it is. - #[derive(Clone, Copy, Debug)] - pub(crate) struct Placed { - pub onset: (i64, u64), - pub duration: (i64, u64), - pub step: Step, - pub octave: i8, - } - - /// A one-measure, one-voice grand-staff score holding exactly `events`. - pub(crate) fn fixture_events(events: &[Placed]) -> Score { - let mut ids = IdGenerator::new(0x7e57); - let piano = ids.next::().unwrap(); - let treble = ids.next::().unwrap(); - let bass = ids.next::().unwrap(); - let right = ids.next::().unwrap(); - let left = ids.next::().unwrap(); - let _ = ids.next::().unwrap(); - let mut score = Score::new(*b"MAKEPADSCORETEST"); - score.title = "Fixture".into(); - score.parts.insert( - piano, - Part { - id: piano, - name: "Piano".into(), - staves: vec![treble, bass], - transposition: Transposition::NONE, - }, - ); - for (id, parent) in [(treble, None), (bass, Some(treble))] { - score.staves.insert( - id, - Staff { - id, - part: piano, - parent, - kind: StaffKind::Standard, - voices: vec![if id == treble { right } else { left }], - }, - ); - } - let measure = ids.next::().unwrap(); - score.measures.insert( - measure, - Measure { - id: measure, - ordinal: 0, - label: "1".into(), - start: ScoreTime::ZERO, - extent: Duration::new(1, 1).unwrap(), - }, - ); - score.flow.nodes.push(FlowNode { - measure, - ordinal: 0, - }); - let mut placed = Vec::new(); - for note in events { - let event = ids.next::().unwrap(); - let id = ids.next::().unwrap(); - placed.push(TimedEvent { - id: event, - onset: ScoreTime::new(note.onset.0, note.onset.1).unwrap(), - duration: Some(Duration::new(note.duration.0, note.duration.1).unwrap()), - grace: None, - kind: EventKind::Chord(vec![Note { - performance: None, - id, - written_pitch: Some(Pitch::new(note.step, Alter::NATURAL, note.octave)), - unpitched_sound: None, - display_staff: treble, - tie_from: None, - tie_to: None, - tab: None, - notehead: Notehead::Normal, - }]), - beams: Vec::new(), - tuplets: Vec::new(), - articulations: Vec::new(), - ornaments: Vec::new(), - }); - } - score.voices.insert( - right, - makepad_score::model::Voice { - id: right, - staff: treble, - number: 1, - events: placed, - }, - ); - score.voices.insert( - left, - makepad_score::model::Voice { - id: left, - staff: bass, - number: 2, - events: Vec::new(), - }, - ); - score.maps.time_signature.push(Change { - at: ScoreTime::ZERO, - scope: MapScope::Global, - value: Meter::Measured { - groups: vec![4], - unit: 4, - }, - }); - score - } - - pub(crate) struct Drawn { - pub noteheads: Vec<(f64, f64, f64)>, - pub beams: Vec, - pub stems: Vec, - pub ledgers: Vec, - pub glyphs: Vec, - /// Page y of the upper staff's top line on the first system. - pub staff_top: f64, - /// Page x of the first system's closing barline. - pub system_right: f64, - } - - pub(crate) fn engrave(score: &Score) -> Drawn { - let mut spacing = crate::spacing::ScoreSpacing::new(); - spacing.rebuild(score); - let placement = spacing.pages()[0].clone(); - let system = &placement.systems[0]; - let (page, _elements) = make_page(score, &placement, 0, 1).unwrap(); - let mut drawn = Drawn { - noteheads: Vec::new(), - beams: Vec::new(), - stems: Vec::new(), - ledgers: Vec::new(), - glyphs: Vec::new(), - staff_top: system.top, - system_right: system.measures.last().map(|m| m.right).unwrap_or(system.right), - }; - for item in page.items() { - match &item.kind { - PaintKind::Glyph(glyph) => { - drawn.glyphs.push(glyph.glyph.0.to_string()); - if glyph.glyph.0.starts_with("notehead") { - drawn.noteheads.push(( - glyph.origin.x, - glyph.origin.y, - item.bounds.width(), - )); - } - } - PaintKind::Primitive(Primitive::Beam(beam)) => drawn.beams.push(*beam), - PaintKind::Primitive(Primitive::Rule { - rect, - kind: RuleKind::Stem, - .. - }) => drawn.stems.push(*rect), - PaintKind::Primitive(Primitive::Rule { - rect, - kind: RuleKind::Ledger, - .. - }) => drawn.ledgers.push(*rect), - _ => {} - } - } - drawn - } - - #[test] - fn eighth_notes_are_beamed_by_the_beat_and_the_beam_clears_every_head() { - let pitches: Vec<(Step, i8)> = [ - (Step::C, 4), - (Step::D, 4), - (Step::E, 4), - (Step::F, 4), - (Step::G, 4), - (Step::A, 4), - (Step::B, 4), - (Step::C, 5), - ] - .into(); - let drawn = engrave(&fixture(&pitches, 8)); - assert_eq!(drawn.noteheads.len(), 8); - // Four beats of two eighths each. - assert_eq!(drawn.beams.len(), 4); - assert_eq!(drawn.stems.len(), 8); - for beam in &drawn.beams { - let heads: Vec<_> = drawn - .noteheads - .iter() - .filter(|(x, _, width)| { - *x + *width >= beam.start.x - 0.3 && *x <= beam.end.x + 0.3 - }) - .collect(); - assert_eq!(heads.len(), 2, "each beam spans exactly its two heads"); - // A beam sits wholly above its heads (stems up) or wholly below. - let above = beam.start.y < heads[0].1; - for (x, y, width) in heads { - // The beam is slanted: measure it directly over the notehead. - let t = ((x + width * 0.5 - beam.start.x) / (beam.end.x - beam.start.x)) - .clamp(0.0, 1.0); - let center = beam.start.y + (beam.end.y - beam.start.y) * t; - let near_edge = center + beam.thickness * 0.5 * if above { 1.0 } else { -1.0 }; - let clearance = if above { y - near_edge } else { near_edge - y }; - assert!( - clearance >= 2.0, - "beam edge {near_edge} crowds a notehead centred on {y}" - ); - } - } - // Every stem ends exactly on the outer edge of its beam. - for stem in &drawn.stems { - let x = stem.center().x; - assert!( - drawn - .beams - .iter() - .filter(|beam| x >= beam.start.x - 0.2 && x <= beam.end.x + 0.2) - .any(|beam| { - let t = ((x - beam.start.x) / (beam.end.x - beam.start.x)).clamp(0.0, 1.0); - let center = beam.start.y + (beam.end.y - beam.start.y) * t; - (center - beam.thickness * 0.5 - stem.min.y).abs() < 0.02 - || (center + beam.thickness * 0.5 - stem.max.y).abs() < 0.02 - }), - "a stem at {stem:?} does not meet a beam" - ); - } - } - - #[test] - fn high_notes_take_ledger_lines_at_whole_staff_positions() { - // A5 and C6 are the first two ledger positions above a treble staff. - let drawn = engrave(&fixture(&[(Step::C, 6)], 4)); - assert_eq!(drawn.noteheads.len(), 1); - let mut lines: Vec = drawn - .ledgers - .iter() - .map(|rect| rect.center().y - drawn.staff_top) - .collect(); - lines.sort_by(f64::total_cmp); - assert_eq!(lines, vec![-2.0, -1.0]); - let head_width = drawn.noteheads[0].2; - for ledger in &drawn.ledgers { - assert!( - ledger.width() > head_width, - "a ledger line must extend past the notehead" - ); - } - } - - #[test] - fn notes_inside_the_staff_take_no_ledger_lines() { - let drawn = engrave(&fixture(&[(Step::B, 4), (Step::E, 4), (Step::F, 5)], 4)); - assert!(drawn.ledgers.is_empty(), "{:?}", drawn.ledgers); - } - - #[test] - fn an_empty_staff_gets_a_measure_rest_and_the_page_gets_its_furniture() { - let drawn = engrave(&fixture(&[(Step::G, 4)], 4)); - assert!(drawn.glyphs.iter().any(|name| name == "restWhole")); - assert!(drawn.glyphs.iter().any(|name| name == "gClef")); - assert!(drawn.glyphs.iter().any(|name| name == "fClef")); - assert!(drawn.glyphs.iter().any(|name| name == "timeSig4")); - } - - #[test] - fn durations_read_as_written_values() { - assert_eq!(note_value_of(duration(1, 1)), NoteValue { power: 0, dots: 0 }); - assert_eq!(note_value_of(duration(1, 2)), NoteValue { power: 1, dots: 0 }); - assert_eq!(note_value_of(duration(1, 4)), NoteValue { power: 2, dots: 0 }); - assert_eq!(note_value_of(duration(3, 8)), NoteValue { power: 2, dots: 1 }); - assert_eq!(note_value_of(duration(1, 8)), NoteValue { power: 3, dots: 0 }); - assert_eq!(note_value_of(duration(1, 16)).flags(), 2); - // 5/16 is not a written value; it degrades to the largest that fits. - assert_eq!(note_value_of(duration(5, 16)), NoteValue { power: 2, dots: 0 }); - } - - #[test] - fn diatonic_positions_follow_the_clef() { - let treble = StaffFrame::treble(10.0); - // B4 is the middle line; C4 is one ledger line below the staff. - let b4 = diatonic_index(Pitch::new(Step::B, Alter::NATURAL, 4)); - let c4 = diatonic_index(Pitch::new(Step::C, Alter::NATURAL, 4)); - let f5 = diatonic_index(Pitch::new(Step::F, Alter::NATURAL, 5)); - assert_eq!(treble.y_of(b4), 12.0); - assert_eq!(treble.y_of(c4), 15.0); - assert_eq!(treble.y_of(f5), 10.0); - - let bass = StaffFrame::bass(30.0); - let d3 = diatonic_index(Pitch::new(Step::D, Alter::NATURAL, 3)); - let c4 = diatonic_index(Pitch::new(Step::C, Alter::NATURAL, 4)); - assert_eq!(bass.y_of(d3), 32.0); - // Middle C is one ledger line above a bass staff. - assert_eq!(bass.y_of(c4), 29.0); - } - - #[test] - fn key_signature_accidentals_land_on_the_right_lines() { - assert_eq!(key_signature_steps(0), Vec::::new()); - // F sharp sits on the top line of a treble staff. - assert_eq!(key_signature_steps(1), vec![4]); - assert_eq!(key_signature_steps(-1), vec![0]); - assert_eq!(key_signature_steps(5).len(), 5); - } -} +pub use makepad_score_view::engrave::*; diff --git a/libs/score_ui/src/font.rs b/libs/score_ui/src/font.rs index e9e560f63..f94b8d087 100644 --- a/libs/score_ui/src/font.rs +++ b/libs/score_ui/src/font.rs @@ -1,994 +1,3 @@ -//! Music-font loading. -//! -//! The engraver needs real SMuFL outlines, not stand-ins. This module resolves -//! one OpenType music font plus its SMuFL metadata, pulls glyph outlines out of -//! the font by canonical name, and exposes the metric surface the engraver -//! needs: glyph bounding boxes, advance widths, stem anchors, and the font's -//! `engravingDefaults`. -//! -//! # Coordinates -//! -//! Outlines stay in the font's own design units (y-up), exactly as -//! [`makepad_score_render::GlyphOutline`] expects; the renderer normalizes them -//! by `units_per_em` and multiplies by a paint item's `em_size`. Everything -//! else here is in staff spaces, y-up, relative to the glyph origin, following -//! SMuFL's rule that one em is four staff spaces. -//! -//! # Availability -//! -//! The font is looked up at runtime (see [`search_paths`]); a checkout without -//! one still starts, falling back to a small set of hand-drawn outlines fitted -//! to Bravura's own bounding boxes. +//! Compatibility re-exports for the shared engraving font support. -use makepad_score::{ - smufl::{FontMetadata, GlyphRegistry}, - symbol::{ - Accidental, Articulation, Clef, Digit, Direction, DynamicMark, FermataShape, FlagDuration, - NoteheadDuration, NoteheadShape, Ornament, Placement, RestDuration, Symbol, TremoloStrokes, - }, -}; -use makepad_score_render::{GlyphOutline, GlyphOutlineCommand}; -use std::{ - collections::BTreeMap, - path::{Path, PathBuf}, - sync::{Arc, OnceLock}, -}; - -/// A glyph's ink box in staff spaces, y-up, relative to the glyph origin. -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct GlyphBox { - pub min_x: f64, - pub min_y: f64, - pub max_x: f64, - pub max_y: f64, -} - -impl GlyphBox { - pub fn width(self) -> f64 { - self.max_x - self.min_x - } - - pub fn height(self) -> f64 { - self.max_y - self.min_y - } -} - -/// The font-independent engraving measurements this app consumes, in staff -/// spaces. Values are Bravura's until a font's `engravingDefaults` replaces -/// them. -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct Engraving { - pub staff_line_thickness: f64, - pub stem_thickness: f64, - pub beam_thickness: f64, - pub beam_spacing: f64, - pub leger_line_thickness: f64, - pub leger_line_extension: f64, - pub thin_barline_thickness: f64, - pub thick_barline_thickness: f64, - pub bracket_thickness: f64, -} - -impl Default for Engraving { - fn default() -> Self { - Self { - staff_line_thickness: 0.13, - stem_thickness: 0.12, - beam_thickness: 0.5, - beam_spacing: 0.25, - leger_line_thickness: 0.16, - leger_line_extension: 0.4, - thin_barline_thickness: 0.16, - thick_barline_thickness: 0.5, - bracket_thickness: 0.5, - } - } -} - -#[derive(Clone, Copy, Debug, Default)] -struct GlyphMetrics { - bbox: Option, - advance: Option, - stem_up_se: Option<(f64, f64)>, - stem_down_nw: Option<(f64, f64)>, -} - -/// One resolved music font: outlines by canonical SMuFL name plus metrics. -pub struct MusicFont { - source: String, - real: bool, - units_per_em: u16, - engraving: Engraving, - outlines: BTreeMap, - metrics: BTreeMap, -} - -impl MusicFont { - /// A one-line description of where the outlines came from. - pub fn source(&self) -> &str { - &self.source - } - - /// False when the hand-drawn fallback is in use. - pub fn is_real(&self) -> bool { - self.real - } - - pub fn units_per_em(&self) -> u16 { - self.units_per_em - } - - pub fn engraving(&self) -> Engraving { - self.engraving - } - - pub fn outlines(&self) -> impl Iterator { - self.outlines.iter().map(|(name, outline)| (name.as_str(), outline)) - } - - pub fn has(&self, name: &str) -> bool { - self.outlines.contains_key(name) - } - - /// Ink box in staff spaces, y-up. Missing glyphs report an empty box at the - /// origin so callers never have to special-case a font gap. - pub fn bbox(&self, name: &str) -> GlyphBox { - self.metrics - .get(name) - .and_then(|metrics| metrics.bbox) - .unwrap_or(GlyphBox { - min_x: 0.0, - min_y: 0.0, - max_x: 0.0, - max_y: 0.0, - }) - } - - /// Advance width in staff spaces, falling back to the ink width. - pub fn advance(&self, name: &str) -> f64 { - let metrics = self.metrics.get(name); - metrics - .and_then(|metrics| metrics.advance) - .or_else(|| metrics.and_then(|metrics| metrics.bbox).map(GlyphBox::width)) - .unwrap_or(0.0) - } - - /// Where an up-stem meets this notehead, in staff spaces from the origin. - pub fn stem_up_se(&self, name: &str) -> (f64, f64) { - self.metrics - .get(name) - .and_then(|metrics| metrics.stem_up_se) - .unwrap_or_else(|| (self.bbox(name).max_x, 0.168)) - } - - /// Where a down-stem meets this notehead, in staff spaces from the origin. - pub fn stem_down_nw(&self, name: &str) -> (f64, f64) { - self.metrics - .get(name) - .and_then(|metrics| metrics.stem_down_nw) - .unwrap_or_else(|| (self.bbox(name).min_x, -0.168)) - } -} - -/// The process-wide music font, loaded once on first use. -/// The font's identity without the absolute path — a dialog line, not a log. -pub fn music_font_summary() -> String { - let source = music_font().source(); - match source.split_once(" from ") { - Some((name, _path)) => name.to_string(), - None => source.to_string(), - } -} - -/// A music font compiled into the application, used when no file is found. -/// -/// The search paths come first, so a reader who wants a different SMuFL font -/// still gets one by pointing `MAKEPAD_SCORE_MUSIC_FONT` at it. This is the -/// floor: an application that ships its notation font renders notation -/// wherever it is run from, rather than only inside a checkout that happens to -/// have the font lying beside it. -static EMBEDDED: OnceLock = OnceLock::new(); - -pub struct EmbeddedFont { - pub name: &'static str, - pub otf: &'static [u8], - pub metadata: Option<&'static [u8]>, - pub glyphnames: Option<&'static [u8]>, -} - -/// Register the font the binary carries. Call before the first draw; later -/// calls are ignored, because the font is resolved once. -pub fn set_embedded_music_font(font: EmbeddedFont) { - let _ = EMBEDDED.set(font); -} - -pub fn music_font() -> &'static MusicFont { - static FONT: OnceLock = OnceLock::new(); - FONT.get_or_init(|| { - let font = load_music_font(); - // One line, whichever way it went: a missing font is a degraded look, - // never a failed start. - println!("[score] music font: {}", font.source); - font - }) -} - -/// Where a music font is looked for, in order: -/// -/// 1. `$MAKEPAD_SCORE_MUSIC_FONT` — a full path to an `.otf`/`.ttf`. -/// 2. `$MAKEPAD_SCORE_FONT_DIR`, then a `resources/fonts` directory beside the -/// executable (including the macOS `../Resources/fonts` bundle location). -/// 3. `local/score-corpus/fonts` in the development checkout, found by walking -/// up from both the working directory and the executable. -fn search_paths() -> Vec { - let mut paths = Vec::new(); - if let Some(path) = std::env::var_os("MAKEPAD_SCORE_MUSIC_FONT") { - paths.push(PathBuf::from(path)); - } - let mut directories: Vec = Vec::new(); - if let Some(directory) = std::env::var_os("MAKEPAD_SCORE_FONT_DIR") { - directories.push(PathBuf::from(directory)); - } - let exe = std::env::current_exe().ok(); - if let Some(beside) = exe.as_ref().and_then(|exe| exe.parent()) { - directories.push(beside.join("resources/fonts")); - directories.push(beside.join("../Resources/fonts")); - } - let mut roots: Vec = Vec::new(); - if let Ok(current) = std::env::current_dir() { - roots.extend(current.ancestors().take(6).map(Path::to_path_buf)); - } - if let Some(beside) = exe.as_ref().and_then(|exe| exe.parent()) { - roots.extend(beside.ancestors().take(6).map(Path::to_path_buf)); - } - for root in roots { - directories.push(root.join("resources/fonts")); - directories.push(root.join("local/score-corpus/fonts")); - } - for directory in directories { - for name in ["bravura.otf", "Bravura.otf", "bravura.ttf", "Bravura.ttf"] { - paths.push(directory.join(name)); - } - } - paths -} - -fn load_music_font() -> MusicFont { - for path in search_paths() { - if !path.is_file() { - continue; - } - match load_from_file(&path) { - Ok(font) => return font, - Err(reason) => { - println!("[score] music font at {} unusable: {reason}", path.display()); - } - } - } - if let Some(embedded) = EMBEDDED.get() { - match load_from_bytes( - embedded.otf, - embedded.metadata, - embedded.glyphnames, - &format!("{} (built in)", embedded.name), - ) { - Ok(font) => return font, - Err(reason) => println!("[score] built-in music font unusable: {reason}"), - } - } - fallback_font() -} - -fn load_from_file(path: &Path) -> Result { - let bytes = std::fs::read(path).map_err(|error| error.to_string())?; - let registry = read_json(&metadata_candidates(path, "glyphnames.json")); - let metadata = read_json(&metadata_candidates(path, "metadata.json")); - load_font( - &bytes, - metadata.as_deref(), - registry.as_deref(), - path.parent().unwrap_or_else(|| Path::new(".")), - &path.display().to_string(), - ) -} - -/// The same load, from bytes the binary carries rather than a file. -fn load_from_bytes( - otf: &[u8], - metadata: Option<&[u8]>, - glyphnames: Option<&[u8]>, - source: &str, -) -> Result { - load_font(otf, metadata, glyphnames, Path::new("."), source) -} - -fn load_font( - bytes: &[u8], - metadata_json: Option<&[u8]>, - glyphnames_json: Option<&[u8]>, - directory: &Path, - source: &str, -) -> Result { - let face = ttf_parser::Face::parse(bytes, 0).map_err(|error| error.to_string())?; - let units_per_em = face.units_per_em(); - if units_per_em == 0 { - return Err("font has a zero-sized em square".into()); - } - - let registry = glyphnames_json.and_then(|bytes| GlyphRegistry::from_bytes(bytes).ok()); - let metadata = metadata_json.and_then(|bytes| FontMetadata::from_bytes(bytes).ok()); - - let mut outlines = BTreeMap::new(); - let mut metrics: BTreeMap = BTreeMap::new(); - for name in repertoire() { - let codepoint = registry - .as_ref() - .and_then(|registry| registry.codepoint_for_name(&name)); - let glyph = codepoint - .and_then(|codepoint| face.glyph_index(codepoint)) - .or_else(|| face.glyph_index_by_name(&name)); - let Some(glyph) = glyph else { continue }; - let mut builder = OutlineCollector::default(); - if face.outline_glyph(glyph, &mut builder).is_none() || builder.commands.is_empty() { - continue; - } - let entry = metrics.entry(name.clone()).or_default(); - // Prefer the font metadata's published box; otherwise measure the ink. - entry.bbox = Some(builder.bounds(units_per_em)); - entry.advance = face - .glyph_hor_advance(glyph) - .map(|advance| f64::from(advance) * 4.0 / f64::from(units_per_em)); - outlines.insert( - name, - GlyphOutline { - units_per_em, - commands: Arc::from(builder.commands), - }, - ); - } - if outlines.is_empty() { - return Err("no SMuFL glyphs found in the font".into()); - } - - let mut engraving = Engraving::default(); - if let Some(metadata) = &metadata { - let defaults = &metadata.engraving_defaults; - engraving = Engraving { - staff_line_thickness: defaults.staff_line_thickness.get(), - stem_thickness: defaults.stem_thickness.get(), - beam_thickness: defaults.beam_thickness.get(), - beam_spacing: defaults.beam_spacing.get(), - leger_line_thickness: defaults.leger_line_thickness.get(), - leger_line_extension: defaults.leger_line_extension.get(), - thin_barline_thickness: defaults.thin_barline_thickness.get(), - thick_barline_thickness: defaults.thick_barline_thickness.get(), - bracket_thickness: defaults.bracket_thickness.get(), - }; - for (name, entry) in metrics.iter_mut() { - if let Some(bbox) = metadata.glyph_bboxes.get(name) { - entry.bbox = Some(GlyphBox { - min_x: bbox.south_west.x.get(), - min_y: bbox.south_west.y.get(), - max_x: bbox.north_east.x.get(), - max_y: bbox.north_east.y.get(), - }); - } - if let Some(advance) = metadata.glyph_advance_widths.get(name) { - entry.advance = Some(advance.get()); - } - if let Some(anchors) = metadata.glyphs_with_anchors.get(name) { - entry.stem_up_se = anchors - .stem_up_se - .map(|point| (point.x.get(), point.y.get())); - entry.stem_down_nw = anchors - .stem_down_nw - .map(|point| (point.x.get(), point.y.get())); - } - } - } - - let font_name = metadata - .as_ref() - .and_then(|metadata| metadata.font_name.clone()) - .unwrap_or_else(|| "music font".to_string()); - let _ = directory; - Ok(MusicFont { - source: format!( - "{font_name} ({} glyphs, upem {units_per_em}) from {source}{}", - outlines.len(), - if metadata.is_some() { - "" - } else { - " [no metadata json; using built-in engraving defaults]" - } - ), - real: true, - units_per_em, - engraving, - outlines, - metrics, - }) -} - -/// Metadata lives beside the font: `bravura.otf` -> `bravura_metadata.json`. -fn metadata_candidates(font: &Path, suffix: &str) -> Vec { - let directory = font.parent().unwrap_or_else(|| Path::new(".")).to_path_buf(); - let stem = font - .file_stem() - .and_then(|stem| stem.to_str()) - .unwrap_or_default() - .to_ascii_lowercase(); - let mut candidates = Vec::new(); - if suffix == "metadata.json" { - candidates.push(directory.join(format!("{stem}_metadata.json"))); - candidates.push(directory.join("metadata.json")); - } else { - candidates.push(directory.join(suffix)); - } - candidates -} - -fn read_json(candidates: &[PathBuf]) -> Option> { - candidates - .iter() - .find_map(|path| std::fs::read(path).ok()) -} - -#[derive(Default)] -struct OutlineCollector { - commands: Vec, - min_x: f32, - min_y: f32, - max_x: f32, - max_y: f32, - started: bool, -} - -impl OutlineCollector { - fn include(&mut self, x: f32, y: f32) { - if !self.started { - self.min_x = x; - self.min_y = y; - self.max_x = x; - self.max_y = y; - self.started = true; - return; - } - self.min_x = self.min_x.min(x); - self.min_y = self.min_y.min(y); - self.max_x = self.max_x.max(x); - self.max_y = self.max_y.max(y); - } - - fn bounds(&self, units_per_em: u16) -> GlyphBox { - let scale = 4.0 / f64::from(units_per_em); - GlyphBox { - min_x: f64::from(self.min_x) * scale, - min_y: f64::from(self.min_y) * scale, - max_x: f64::from(self.max_x) * scale, - max_y: f64::from(self.max_y) * scale, - } - } -} - -impl ttf_parser::OutlineBuilder for OutlineCollector { - fn move_to(&mut self, x: f32, y: f32) { - self.include(x, y); - self.commands.push(GlyphOutlineCommand::MoveTo(x, y)); - } - - fn line_to(&mut self, x: f32, y: f32) { - self.include(x, y); - self.commands.push(GlyphOutlineCommand::LineTo(x, y)); - } - - fn quad_to(&mut self, cx: f32, cy: f32, x: f32, y: f32) { - self.include(x, y); - self.commands.push(GlyphOutlineCommand::QuadTo(cx, cy, x, y)); - } - - fn curve_to(&mut self, c1x: f32, c1y: f32, c2x: f32, c2y: f32, x: f32, y: f32) { - self.include(x, y); - self.commands - .push(GlyphOutlineCommand::CubicTo(c1x, c1y, c2x, c2y, x, y)); - } - - fn close(&mut self) { - self.commands.push(GlyphOutlineCommand::Close); - } -} - -/// The working repertoire, as canonical SMuFL names derived from [`Symbol`]. -fn repertoire() -> Vec { - let mut names: Vec = Vec::new(); - let mut push = |symbol: Symbol| names.push(symbol.canonical_name().to_string()); - - const NOTEHEAD_DURATIONS: [NoteheadDuration; 4] = [ - NoteheadDuration::DoubleWhole, - NoteheadDuration::Whole, - NoteheadDuration::Half, - NoteheadDuration::Black, - ]; - const NOTEHEAD_SHAPES: [NoteheadShape; 4] = [ - NoteheadShape::Normal, - NoteheadShape::X, - NoteheadShape::Diamond, - NoteheadShape::Slash, - ]; - for shape in NOTEHEAD_SHAPES { - for duration in NOTEHEAD_DURATIONS { - push(Symbol::Notehead { duration, shape }); - } - } - for duration in [ - RestDuration::Maxima, - RestDuration::Longa, - RestDuration::DoubleWhole, - RestDuration::Whole, - RestDuration::Half, - RestDuration::Quarter, - RestDuration::Eighth, - RestDuration::Sixteenth, - RestDuration::ThirtySecond, - RestDuration::SixtyFourth, - RestDuration::OneTwentyEighth, - ] { - push(Symbol::Rest(duration)); - } - for accidental in [ - Accidental::TripleFlat, - Accidental::DoubleFlat, - Accidental::Flat, - Accidental::Natural, - Accidental::Sharp, - Accidental::DoubleSharp, - Accidental::TripleSharp, - Accidental::NaturalFlat, - Accidental::NaturalSharp, - Accidental::QuarterToneFlat, - Accidental::ThreeQuarterTonesFlat, - Accidental::QuarterToneSharp, - Accidental::ThreeQuarterTonesSharp, - ] { - push(Symbol::Accidental(accidental)); - } - for clef in [ - Clef::G, - Clef::G8va, - Clef::G8vb, - Clef::G15ma, - Clef::G15mb, - Clef::F, - Clef::F8va, - Clef::F8vb, - Clef::F15ma, - Clef::F15mb, - Clef::C, - Clef::Percussion, - Clef::PercussionAlternate, - Clef::Tab4String, - Clef::Tab6String, - ] { - push(Symbol::Clef(clef)); - } - for duration in [ - FlagDuration::Eighth, - FlagDuration::Sixteenth, - FlagDuration::ThirtySecond, - FlagDuration::SixtyFourth, - FlagDuration::OneTwentyEighth, - ] { - for direction in [Direction::Up, Direction::Down] { - push(Symbol::Flag { - duration, - direction, - }); - } - } - for articulation in [ - Articulation::Accent, - Articulation::Staccato, - Articulation::Tenuto, - Articulation::Staccatissimo, - Articulation::Marcato, - Articulation::LaissezVibrer, - Articulation::Stress, - Articulation::SoftAccent, - Articulation::AccentStaccato, - Articulation::TenutoStaccato, - Articulation::MarcatoStaccato, - Articulation::MarcatoTenuto, - ] { - for placement in [Placement::Above, Placement::Below] { - push(Symbol::Articulation { - articulation, - placement, - }); - } - } - for dynamic in [ - DynamicMark::Piano, - DynamicMark::Pianissimo, - DynamicMark::Pianississimo, - DynamicMark::Pianissississimo, - DynamicMark::MezzoPiano, - DynamicMark::MezzoForte, - DynamicMark::Forte, - DynamicMark::Fortissimo, - DynamicMark::Fortississimo, - DynamicMark::Fortissississimo, - DynamicMark::FortePiano, - DynamicMark::Sforzando, - DynamicMark::SforzandoPiano, - DynamicMark::Sforzato, - DynamicMark::Rinforzando, - DynamicMark::Niente, - DynamicMark::Mezzo, - DynamicMark::Z, - ] { - push(Symbol::Dynamic(dynamic)); - } - const DIGITS: [Digit; 10] = [ - Digit::Zero, - Digit::One, - Digit::Two, - Digit::Three, - Digit::Four, - Digit::Five, - Digit::Six, - Digit::Seven, - Digit::Eight, - Digit::Nine, - ]; - for digit in DIGITS { - push(Symbol::TimeSignatureDigit(digit)); - push(Symbol::TupletDigit(digit)); - } - push(Symbol::TimeSignatureCommon); - push(Symbol::TimeSignatureCutCommon); - for ornament in [ - Ornament::Trill, - Ornament::Turn, - Ornament::InvertedTurn, - Ornament::TurnWithSlash, - Ornament::Mordent, - Ornament::ShortTrill, - Ornament::Tremblement, - Ornament::Schleifer, - ] { - push(Symbol::Ornament(ornament)); - } - for shape in [ - FermataShape::Normal, - FermataShape::Short, - FermataShape::Long, - FermataShape::VeryShort, - FermataShape::VeryLong, - ] { - for placement in [Placement::Above, Placement::Below] { - push(Symbol::Fermata { shape, placement }); - } - } - for strokes in [ - TremoloStrokes::One, - TremoloStrokes::Two, - TremoloStrokes::Three, - TremoloStrokes::Four, - TremoloStrokes::Five, - ] { - push(Symbol::Tremolo(strokes)); - } - push(Symbol::AugmentationDot); - push(Symbol::RepeatDot); - push(Symbol::Segno); - push(Symbol::Coda); - push(Symbol::BreathMark); - push(Symbol::Caesura); - push(Symbol::Arpeggio(Direction::Up)); - push(Symbol::Arpeggio(Direction::Down)); - for extra in ["brace", "bracket", "restHBar", "noteheadWholeFilled"] { - names.push(extra.to_string()); - } - names.sort(); - names.dedup(); - names -} - -// --------------------------------------------------------------------------- -// Fallback: hand-drawn outlines, fitted to Bravura's published bounding boxes -// so a checkout without a music font still engraves at the right size. -// --------------------------------------------------------------------------- - -const FALLBACK_UNITS_PER_EM: u16 = 1000; - -fn fallback_font() -> MusicFont { - let mut outlines = BTreeMap::new(); - let mut metrics = BTreeMap::new(); - for (name, commands, bbox) in [ - ( - "noteheadBlack", - notehead_shape(), - GlyphBox { - min_x: 0.0, - min_y: -0.5, - max_x: 1.18, - max_y: 0.5, - }, - ), - ( - "noteheadHalf", - notehead_shape(), - GlyphBox { - min_x: 0.0, - min_y: -0.5, - max_x: 1.18, - max_y: 0.5, - }, - ), - ( - "noteheadWhole", - notehead_shape(), - GlyphBox { - min_x: 0.0, - min_y: -0.5, - max_x: 1.688, - max_y: 0.5, - }, - ), - ( - "augmentationDot", - dot_shape(), - GlyphBox { - min_x: 0.0, - min_y: -0.1, - max_x: 0.2, - max_y: 0.1, - }, - ), - ( - "gClef", - g_clef_shape(), - GlyphBox { - min_x: 0.0, - min_y: -2.632, - max_x: 2.684, - max_y: 4.392, - }, - ), - ( - "fClef", - f_clef_shape(), - GlyphBox { - min_x: 0.0, - min_y: -1.0, - max_x: 2.736, - max_y: 2.72, - }, - ), - ] { - outlines.insert(name.to_string(), fit_outline(commands, bbox)); - metrics.insert( - name.to_string(), - GlyphMetrics { - bbox: Some(bbox), - advance: Some(bbox.width()), - stem_up_se: Some((bbox.max_x, 0.168)), - stem_down_nw: Some((bbox.min_x, -0.168)), - }, - ); - } - MusicFont { - source: "hand-drawn fallback outlines (no SMuFL font found; \ - set MAKEPAD_SCORE_MUSIC_FONT or place bravura.otf in resources/fonts)" - .to_string(), - real: false, - units_per_em: FALLBACK_UNITS_PER_EM, - engraving: Engraving::default(), - outlines, - metrics, - } -} - -/// Maps a hand-drawn path onto a target staff-space box, so the fallback lands -/// at exactly the size the engraver expects of the real glyph. -fn fit_outline(commands: Vec, target: GlyphBox) -> GlyphOutline { - let mut min_x = f32::INFINITY; - let mut min_y = f32::INFINITY; - let mut max_x = f32::NEG_INFINITY; - let mut max_y = f32::NEG_INFINITY; - let mut visit = |x: f32, y: f32| { - min_x = min_x.min(x); - min_y = min_y.min(y); - max_x = max_x.max(x); - max_y = max_y.max(y); - }; - for command in &commands { - match *command { - GlyphOutlineCommand::MoveTo(x, y) | GlyphOutlineCommand::LineTo(x, y) => visit(x, y), - GlyphOutlineCommand::QuadTo(_, _, x, y) => visit(x, y), - GlyphOutlineCommand::CubicTo(_, _, _, _, x, y) => visit(x, y), - GlyphOutlineCommand::Close => {} - } - } - let units = f32::from(FALLBACK_UNITS_PER_EM) / 4.0; - let scale_x = if max_x > min_x { - (target.width() as f32) * units / (max_x - min_x) - } else { - 1.0 - }; - let scale_y = if max_y > min_y { - (target.height() as f32) * units / (max_y - min_y) - } else { - 1.0 - }; - let map = |x: f32, y: f32| { - ( - (x - min_x) * scale_x + target.min_x as f32 * units, - (y - min_y) * scale_y + target.min_y as f32 * units, - ) - }; - let mapped = commands - .into_iter() - .map(|command| match command { - GlyphOutlineCommand::MoveTo(x, y) => { - let (x, y) = map(x, y); - GlyphOutlineCommand::MoveTo(x, y) - } - GlyphOutlineCommand::LineTo(x, y) => { - let (x, y) = map(x, y); - GlyphOutlineCommand::LineTo(x, y) - } - GlyphOutlineCommand::QuadTo(cx, cy, x, y) => { - let (cx, cy) = map(cx, cy); - let (x, y) = map(x, y); - GlyphOutlineCommand::QuadTo(cx, cy, x, y) - } - GlyphOutlineCommand::CubicTo(c1x, c1y, c2x, c2y, x, y) => { - let (c1x, c1y) = map(c1x, c1y); - let (c2x, c2y) = map(c2x, c2y); - let (x, y) = map(x, y); - GlyphOutlineCommand::CubicTo(c1x, c1y, c2x, c2y, x, y) - } - GlyphOutlineCommand::Close => GlyphOutlineCommand::Close, - }) - .collect::>(); - GlyphOutline { - units_per_em: FALLBACK_UNITS_PER_EM, - commands: Arc::from(mapped), - } -} - -fn notehead_shape() -> Vec { - use GlyphOutlineCommand::*; - vec![ - MoveTo(-520.0, -90.0), - CubicTo(-430.0, 260.0, 180.0, 430.0, 470.0, 190.0), - CubicTo(760.0, -50.0, 470.0, -390.0, 20.0, -420.0), - CubicTo(-410.0, -450.0, -610.0, -280.0, -520.0, -90.0), - Close, - ] -} - -fn dot_shape() -> Vec { - use GlyphOutlineCommand::*; - vec![ - MoveTo(-180.0, 0.0), - CubicTo(-180.0, 110.0, -100.0, 180.0, 0.0, 180.0), - CubicTo(110.0, 180.0, 180.0, 100.0, 180.0, 0.0), - CubicTo(180.0, -110.0, 100.0, -180.0, 0.0, -180.0), - CubicTo(-110.0, -180.0, -180.0, -100.0, -180.0, 0.0), - Close, - ] -} - -fn g_clef_shape() -> Vec { - use GlyphOutlineCommand::*; - vec![ - MoveTo(80.0, 660.0), - CubicTo(-300.0, 450.0, -360.0, 80.0, -80.0, -110.0), - CubicTo(210.0, -305.0, 490.0, -100.0, 335.0, 125.0), - CubicTo(215.0, 300.0, -30.0, 230.0, -35.0, 75.0), - CubicTo(-35.0, -20.0, 85.0, -55.0, 145.0, 15.0), - CubicTo(280.0, 175.0, 70.0, 305.0, -95.0, 220.0), - CubicTo(-360.0, 85.0, -270.0, -300.0, 65.0, -350.0), - LineTo(115.0, -800.0), - LineTo(245.0, -790.0), - LineTo(180.0, -335.0), - CubicTo(540.0, -210.0, 560.0, 250.0, 230.0, 430.0), - CubicTo(145.0, 480.0, 120.0, 590.0, 80.0, 660.0), - Close, - ] -} - -fn f_clef_shape() -> Vec { - use GlyphOutlineCommand::*; - vec![ - MoveTo(-430.0, 240.0), - CubicTo(-210.0, 570.0, 330.0, 470.0, 390.0, 90.0), - CubicTo(450.0, -300.0, 120.0, -550.0, -260.0, -430.0), - CubicTo(20.0, -300.0, 160.0, -90.0, 105.0, 120.0), - CubicTo(45.0, 340.0, -190.0, 390.0, -430.0, 240.0), - Close, - MoveTo(560.0, 210.0), - LineTo(760.0, 210.0), - LineTo(760.0, 410.0), - LineTo(560.0, 410.0), - Close, - MoveTo(560.0, -190.0), - LineTo(760.0, -190.0), - LineTo(760.0, 10.0), - LineTo(560.0, 10.0), - Close, - ] -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn repertoire_covers_the_working_symbols() { - let names = repertoire(); - for expected in [ - "noteheadBlack", - "noteheadHalf", - "noteheadWhole", - "restQuarter", - "rest8th", - "accidentalSharp", - "accidentalFlat", - "accidentalNatural", - "accidentalDoubleSharp", - "gClef", - "fClef", - "cClef", - "gClef8vb", - "flag8thUp", - "flag32ndDown", - "augmentationDot", - "timeSig4", - "articStaccatoAbove", - "articAccentBelow", - "fermataAbove", - ] { - assert!(names.iter().any(|name| name == expected), "missing {expected}"); - } - } - - #[test] - fn fallback_notehead_is_one_staff_space_tall() { - let font = fallback_font(); - let bbox = font.bbox("noteheadBlack"); - assert!((bbox.height() - 1.0).abs() < 1e-9); - assert!((bbox.width() - 1.18).abs() < 1e-9); - let outline = font.outlines.get("noteheadBlack").unwrap(); - let mut min_y = f32::INFINITY; - let mut max_y = f32::NEG_INFINITY; - for command in outline.commands.iter() { - if let GlyphOutlineCommand::CubicTo(_, _, _, _, _, y) | GlyphOutlineCommand::MoveTo(_, y) = - command - { - min_y = min_y.min(*y); - max_y = max_y.max(*y); - } - } - // 1000 units per em, four staff spaces to the em: 250 units tall. - assert!((max_y - min_y - 250.0).abs() < 1.0, "{min_y}..{max_y}"); - } - - #[test] - fn the_shipped_font_loads_when_present() { - let font = load_music_font(); - println!("music font source: {}", font.source()); - if !font.is_real() { - return; - } - let bbox = font.bbox("noteheadBlack"); - assert!((bbox.height() - 1.0).abs() < 0.02, "{bbox:?}"); - assert!((bbox.width() - 1.18).abs() < 0.05, "{bbox:?}"); - assert!(font.has("restQuarter")); - assert!(font.has("accidentalSharp")); - assert!(font.has("flag8thUp")); - assert!(font.engraving().beam_thickness > 0.0); - } -} +pub use makepad_score_view::font::*; diff --git a/libs/score_ui/src/lib.rs b/libs/score_ui/src/lib.rs index 330c42040..0c38edabf 100644 --- a/libs/score_ui/src/lib.rs +++ b/libs/score_ui/src/lib.rs @@ -5,6 +5,12 @@ //! `apps/score` crate is intentionally only a window and event adapter. pub use makepad_widgets; +pub use makepad_score_view::{ + build, build_bass_tab_score, build_drum_score, build_pitched_score, view, BuildOptions, + DrumHit, DrumVoice, PitchedNote, ScoreView, ScoreViewRef, ScoreViewWidgetExt, + ScoreViewWidgetRefExt, +}; +pub use makepad_score_view::ScoreDocument as ScoreViewDocument; pub mod action; pub mod document; @@ -19,7 +25,6 @@ pub mod sound; pub mod spacing; pub mod state; pub mod theme; -pub(crate) mod title; pub mod ui; pub use action::*; @@ -34,6 +39,7 @@ use makepad_widgets::ScriptVm; /// Register the score theme and widgets in dependency order. pub fn script_mod(vm: &mut ScriptVm) { + makepad_score_view::script_mod(vm); theme::script_mod(vm); ui::widgets::script_mod(vm); ui::canvas::script_mod(vm); diff --git a/libs/score_ui/src/playback.rs b/libs/score_ui/src/playback.rs index 4a3604ff3..75b1cfbe9 100644 --- a/libs/score_ui/src/playback.rs +++ b/libs/score_ui/src/playback.rs @@ -1206,6 +1206,284 @@ mod tests { assert_eq!(plan.end_sample(), plan.score_quarter_to_sample(end_quarter)); } + /// DEBUG RIG (working tree only): render a MIDI file through the exact + /// path the application plays it on and write a WAV, so an app-vs-render + /// difference can be measured instead of argued about. + /// + /// SCORE_RIG_IN= SCORE_RIG_OUT= SCORE_RIG_SECS=44 \ + /// cargo test -p makepad-score-ui --release rig_render -- --ignored --nocapture + #[test] + #[ignore] + fn rig_render() { + let input = std::env::var("SCORE_RIG_IN").expect("SCORE_RIG_IN"); + let output = std::env::var("SCORE_RIG_OUT").expect("SCORE_RIG_OUT"); + let secs: f64 = std::env::var("SCORE_RIG_SECS") + .ok() + .and_then(|v| v.parse().ok()) + .unwrap_or(44.0); + let bytes = std::fs::read(&input).expect("read midi"); + let imported = makepad_score_import::import_midi_bytes(&bytes).expect("import midi"); + let score = imported.score; + let bpm = crate::state::score_opening_tempo(&score).unwrap_or(120.0); + eprintln!("rig: tempo {bpm} bpm"); + + let plan = compile_plan(&score, bpm, false); + let shared = Arc::new(SharedSound::default()); + // Exactly what the application publishes at startup. + let mut settings = SoundSettings::default(); + let knob = |name: &str| -> Option { + std::env::var(name).ok().and_then(|v| v.parse().ok()) + }; + if let Some(v) = knob("RIG_MIX") { settings.room.mix = v; } + if let Some(v) = knob("RIG_EARLY") { settings.early_reflections = v; } + if let Some(v) = knob("RIG_SHELF") { settings.eq_shelf_db = v; } + if let Some(v) = knob("RIG_TREBLE") { settings.tone_treble_db = v; } + if let Some(v) = knob("RIG_BASS") { settings.tone_bass_db = v; } + if let Some(v) = knob("RIG_MASTER") { settings.master_gain = v; } + if let Some(v) = knob("RIG_BODYTAP") { settings.voicing.body_tap = v; } + if let Some(v) = knob("RIG_KNOCK") { settings.voicing.knock = v; } + if let Some(v) = knob("RIG_ROUGH") { settings.voicing.roughness = v; } + if let Some(v) = knob("RIG_PHANTOM") { settings.voicing.phantoms = v; } + if let Some(v) = knob("RIG_ATKNOISE") { settings.voicing.attack_noise = v; } + if let Some(v) = knob("RIG_ATKBODY") { settings.voicing.attack_body = v; } + if let Some(v) = knob("RIG_SYMP") { settings.voicing.sympathetic = v; } + if std::env::var("RIG_AUDIENCE").is_ok() { + settings.room.perspective = Perspective::Audience; + } + eprintln!("rig: voicing {:?}", settings.voicing); + eprintln!( + "rig: engine {:?} preset {} reverb {:?} mix {} bright {}", + settings.engine, + settings.preset, + settings.room.preset, + settings.room.mix, + settings.eq_shelf_db + ); + // MODE=native leaves the shared cell at revision 0, which the backend + // reads as "nothing published": the instrument keeps the values its own + // preset built it with. That is the sound the offline renders had. + if std::env::var("SCORE_RIG_MODE").as_deref() != Ok("native") { + shared.publish(settings); + } else { + eprintln!("rig: NATIVE — publishing nothing, preset values stand"); + } + + let ring = SpscRing::::new(); + let mixer = PartMixer::::new(); + let clock = AtomicAudioClock::new(); + let mut engine = + PlaybackEngine::::new(test_backend( + Arc::clone(&shared), + )); + ring.push(AudioMessage { + at_device_sample: 0, + sequence: 1, + kind: AudioMessageKind::Play, + }) + .expect("play"); + + const BLOCK: usize = 512; + let blocks = (secs * f64::from(PLAN_RATE) / BLOCK as f64) as u64; + let mut left = vec![0.0_f32; BLOCK]; + let mut right = vec![0.0_f32; BLOCK]; + let mut interleaved: Vec = Vec::with_capacity(blocks as usize * BLOCK * 2); + let mut peak = 0.0_f32; + let mut clipped = 0u64; + for block in 0..blocks { + left.fill(0.0); + right.fill(0.0); + let mut channels: [&mut [f32]; 2] = [&mut left, &mut right]; + let context = RenderContext { + device_sample_rate: PLAN_RATE, + first_device_sample: block * BLOCK as u64, + first_presentation_host_ns: block * BLOCK as u64 * 1_000_000_000 + / u64::from(PLAN_RATE), + frames: BLOCK, + output_latency_frames: 0, + stream_generation: 1, + clock_quality: ClockQuality::Exact, + }; + engine.render(context, &mut channels, &plan, &ring, &mixer, &clock); + for index in 0..BLOCK { + for sample in [left[index], right[index]] { + peak = peak.max(sample.abs()); + if sample.abs() >= 1.0 { + clipped += 1; + } + interleaved.push((sample.clamp(-1.0, 1.0) * 32767.0) as i16); + } + } + } + eprintln!("rig: peak {peak:.4} clipped samples {clipped}"); + write_wav(&output, &interleaved, PLAN_RATE); + eprintln!("rig: wrote {output}"); + } + + + /// DEBUG RIG (working tree only): drive the piano DIRECTLY from the MIDI + /// file's own note-ons and note-offs, dry, with no plan, no scheduler and + /// no articulation gate — the path the offline candidate renders used. + /// This is the reference sound; the difference from `rig_render` is + /// exactly what the application's playback path is doing to it. + /// + /// RIG_IN= RIG_OUT= RIG_SECS=44 [RIG_WET=0] \ + /// cargo test -p makepad-score-ui --release rig_direct -- --ignored --nocapture + #[test] + #[ignore] + fn rig_direct() { + let input = std::env::var("SCORE_RIG_IN").expect("SCORE_RIG_IN"); + let output = std::env::var("SCORE_RIG_OUT").expect("SCORE_RIG_OUT"); + let secs: f64 = std::env::var("SCORE_RIG_SECS") + .ok() + .and_then(|v| v.parse().ok()) + .unwrap_or(44.0); + let wet: f32 = std::env::var("RIG_WET") + .ok() + .and_then(|v| v.parse().ok()) + .unwrap_or(0.0); + let target_dbfs: f32 = std::env::var("RIG_DBFS") + .ok() + .and_then(|v| v.parse().ok()) + .unwrap_or(-18.0); + let bytes = std::fs::read(&input).expect("read midi"); + let file = makepad_midi_file::MidiFile::parse(&bytes).expect("parse midi"); + let sequences = file.paired_notes().expect("paired notes"); + let tempo = file.tempo_map().expect("tempo map"); + let rate = PLAN_RATE as f32; + + let mut piano = Piano::new_with_preset( + rate, + &makepad_piano_model::PIANO_PRESETS + [crate::sound::default_preset_index(ScoreEngine::Physical)], + ); + piano.set_reverb_mix(wet); + + // The FILE, played: its own seconds (every tempo change already + // applied), its own velocities, its own sustain pedal. No score model, + // no quantisation, no articulation gate. + let mut events: Vec<(usize, PianoEvent)> = Vec::new(); + let frame = |seconds: f64| -> usize { (seconds * f64::from(rate)).max(0.0) as usize }; + let mut notes = 0usize; + for sequence in &sequences { + for note in &sequence.notes { + notes += 1; + events.push(( + frame(note.time_on), + PianoEvent::NoteOn { key: note.key, velocity: note.velocity_on.max(1) }, + )); + events.push((frame(note.time_off), PianoEvent::NoteOff { key: note.key })); + } + } + let mut pedals = 0usize; + if std::env::var("RIG_NOPEDAL").is_err() { + for track in &file.tracks { + for event in &track.events { + if let makepad_midi_file::EventKind::Channel(channel) = &event.kind { + if let makepad_midi_file::ChannelMessage::ControlChange { + controller: 64, + value, + } = channel.message + { + pedals += 1; + events.push(( + frame(tempo.ticks_to_seconds(event.tick)), + PianoEvent::Sustain { value: f32::from(value) / 127.0 }, + )); + } + } + } + } + } + let velocities: std::collections::BTreeSet = sequences + .iter() + .flat_map(|s| s.notes.iter().map(|n| n.velocity_on)) + .collect(); + eprintln!( + "rig_direct: {notes} notes, {} distinct velocities, {pedals} pedal events, wet {wet}", + velocities.len() + ); + events.sort_by_key(|(frame, _)| *frame); + for (frame, event) in events.iter().take(12) { + eprintln!( + "rig_direct: {:8.3}s {:?}", + *frame as f64 / f64::from(rate), + event + ); + } + + const BLOCK: usize = 512; + let total = (secs * f64::from(PLAN_RATE)) as usize; + let mut left = vec![0.0_f32; BLOCK]; + let mut right = vec![0.0_f32; BLOCK]; + let mut all_l: Vec = Vec::with_capacity(total); + let mut all_r: Vec = Vec::with_capacity(total); + let mut cursor = 0usize; + let mut start = 0usize; + while start < total { + let end = (start + BLOCK).min(total); + let mut block_events: Vec = Vec::new(); + while cursor < events.len() && events[cursor].0 < end { + let frame = events[cursor].0.max(start); + block_events.push(PianoTimedEvent { + offset: (frame - start) as u32, + event: events[cursor].1, + }); + cursor += 1; + } + let count = end - start; + left[..count].fill(0.0); + right[..count].fill(0.0); + piano.process(&block_events, &mut left[..count], &mut right[..count]); + all_l.extend_from_slice(&left[..count]); + all_r.extend_from_slice(&right[..count]); + start = end; + } + + // The candidate renders were normalised; match that so a comparison is + // about tone and not about level. + let n = all_l.len().max(1) as f32; + let rms = (all_l.iter().chain(all_r.iter()).map(|s| s * s).sum::() + / (2.0 * n)) + .sqrt(); + let gain = if rms > 0.0 { + 10.0_f32.powf(target_dbfs / 20.0) / rms + } else { + 1.0 + }; + let mut peak = 0.0_f32; + let mut interleaved: Vec = Vec::with_capacity(all_l.len() * 2); + for (l, r) in all_l.iter().zip(all_r.iter()) { + for sample in [l * gain, r * gain] { + peak = peak.max(sample.abs()); + interleaved.push((sample.clamp(-1.0, 1.0) * 32767.0) as i16); + } + } + eprintln!("rig_direct: rms {rms:.4} gain {gain:.3} peak {peak:.3}"); + write_wav(&output, &interleaved, PLAN_RATE); + eprintln!("rig_direct: wrote {output}"); + } + + fn write_wav(path: &str, samples: &[i16], rate: u32) { + let data_len = (samples.len() * 2) as u32; + let mut out = Vec::with_capacity(44 + data_len as usize); + out.extend_from_slice(b"RIFF"); + out.extend_from_slice(&(36 + data_len).to_le_bytes()); + out.extend_from_slice(b"WAVEfmt "); + out.extend_from_slice(&16u32.to_le_bytes()); + out.extend_from_slice(&1u16.to_le_bytes()); + out.extend_from_slice(&2u16.to_le_bytes()); + out.extend_from_slice(&rate.to_le_bytes()); + out.extend_from_slice(&(rate * 4).to_le_bytes()); + out.extend_from_slice(&4u16.to_le_bytes()); + out.extend_from_slice(&16u16.to_le_bytes()); + out.extend_from_slice(b"data"); + out.extend_from_slice(&data_len.to_le_bytes()); + for sample in samples { + out.extend_from_slice(&sample.to_le_bytes()); + } + std::fs::write(path, out).expect("write wav"); + } + fn test_backend(sound: Arc) -> SamplerBackend { SamplerBackend::new( PLAN_RATE as f32, diff --git a/libs/score_ui/src/spacing.rs b/libs/score_ui/src/spacing.rs index 1718b3caf..2c4acc593 100644 --- a/libs/score_ui/src/spacing.rs +++ b/libs/score_ui/src/spacing.rs @@ -1,966 +1,3 @@ -//! Horizontal spacing and page planning. -//! -//! This is the seam between the semantic score and -//! [`makepad_score_layout`]'s constrained spring-and-rod solver. Nothing here -//! decides *how* to space music — the kernel does that — but everything here -//! decides *what the music actually is*, in numbers the kernel understands: -//! -//! * a **column** is one onset, a moment where something starts, merged -//! across every voice and both staves of the grand staff so the two hands -//! line up vertically; -//! * its **spring** (`natural`) is its duration run through the kernel's -//! duration curve, so a sixteenth asks for less room than a half note but -//! not sixteen times less; -//! * its **rod** (`minimum`) is measured ink: the real Bravura advance widths -//! of the noteheads at that onset, the second-interval head shift, the -//! augmentation dots, the accidentals hanging off the *next* column, and -//! the barline where the measure ends. -//! -//! The kernel then solves each system's chain to the system width and breaks -//! the measure list into systems and the systems into pages; this module -//! turns the solved widths back into page coordinates the engraver draws at. -//! -//! # Why these flexibilities -//! -//! A column's width under force `F` is `rod + I*q(d)*(1 + F)`: both the -//! stretch and the shrink flexibility are set to the column's *duration -//! space* `I*q(d)`, with `headroom` set to the rod. Three properties follow, -//! and they are exactly the classical engraving behaviour: -//! -//! 1. Ink never scales. Justifying a system moves whitespace around; it never -//! inflates or squeezes a notehead's own advance. -//! 2. Whitespace scales in proportion to duration space, so a system that has -//! to stretch keeps the *ratios* between a sixteenth's gap and a half -//! note's gap. That proportional invariance is what reads as "engraved". -//! 3. `F = -1` is exactly the point where all whitespace is gone and every -//! rod is touching. Since [`makepad_score_layout::BreakStyle::min_ratio`] -//! is `-1`, the line breaker's feasibility test and the spacing model's -//! collision limit become the same statement, with no fudge factor. +//! Compatibility re-exports for shared score spacing. -use crate::document::PAGE_WIDTH_SP; -use crate::engrave::{ - measure_staff_columns, staff_frames, Column, MARGIN_LEFT, MARGIN_RIGHT, STAFF_SPAN, -}; -use crate::font::{music_font, MusicFont}; -use makepad_score::model::{KeySignature, Measure, MeasureId, Meter, Rational, Score, ScoreTime}; -use makepad_score_layout::{ - break_pages, BreakRule, DistanceStyle, IncrementalLayout, LayoutStyle, LineWidths, - MeasureSource, PageSpec, RelayoutStats, Sp, SpacingColumn, SystemLayout, SystemVertical, - TurnRule, -}; -use std::{collections::BTreeMap, ops::Range}; - -/// Page y of the top of the first system's block (its ink, not its staff). -const PAGE_MUSIC_TOP: f64 = 28.0; -/// Page y below which nothing but the folio may be printed. -const PAGE_MUSIC_BOTTOM: f64 = 222.0; - -/// One placed onset column: where its noteheads' left edges go. -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct ColumnPlacement { - /// Absolute score time of the onset. - pub onset: ScoreTime, - /// Page x of the unshifted notehead's left edge. - pub x: f64, -} - -/// One placed measure. -#[derive(Clone, Debug)] -pub struct MeasurePlacement { - pub measure: MeasureId, - /// Index in score order. - pub index: usize, - /// Page x of the measure's left boundary (the opening barline). - pub left: f64, - /// Page x of the measure's closing barline. - pub right: f64, - /// Onset columns in time order. - pub columns: Vec, -} - -impl MeasurePlacement { - /// Page x for an onset, or the measure's left boundary when the onset is - /// not a column of this measure (which the engraver never asks for). - pub fn x_of(&self, onset: ScoreTime) -> f64 { - self.columns - .iter() - .find(|column| column.onset == onset) - .map(|column| column.x) - .unwrap_or(self.left) - } - - /// Page x for a point in time inside the measure, interpolated between - /// the columns that bracket it. Used by the playback cursor. - pub fn x_at(&self, whole: f64, measure_start: f64, measure_end: f64) -> f64 { - let time = whole.clamp(measure_start, measure_end); - let mut previous = (measure_start, self.left); - for column in &self.columns { - let at = rational_f64(column.onset.0); - if at > time + 1e-12 { - let span = (at - previous.0).max(1e-9); - let t = ((time - previous.0) / span).clamp(0.0, 1.0); - return previous.1 + (column.x - previous.1) * t; - } - previous = (at, column.x); - } - let span = (measure_end - previous.0).max(1e-9); - let t = ((time - previous.0) / span).clamp(0.0, 1.0); - previous.1 + (self.right - previous.1) * t - } -} - -/// One placed system. -#[derive(Clone, Debug)] -pub struct SystemPlacement { - /// Page y of the top staff line of the upper staff. - pub top: f64, - /// Page y of the bottom staff line of the lower staff. - pub bottom: f64, - /// Page x where this system's music starts. - pub music_left: f64, - /// Page x of the system's right edge. - pub right: f64, - /// True for the system carrying the score's first measure. - pub show_meter: bool, - pub measures: Vec, -} - -/// A moment in the score, resolved to the page. -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct CursorLocation { - pub page: usize, - pub x_sp: f64, - pub top_sp: f64, - pub bottom_sp: f64, -} - -/// How far above and below the staves the playback cursor reaches, so it -/// clears ledger lines and stems without touching the neighbouring system. -const CURSOR_SYSTEM_PAD: f64 = 3.0; - -/// One placed page. -#[derive(Clone, Debug, Default)] -pub struct PagePlacement { - pub systems: Vec, -} - -/// Which pages a relayout invalidated. -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum PagesDirty { - /// The break structure moved: everything must be repainted. - All, - /// Only these pages changed. - Only(Vec), -} - -/// Cached per-measure spacing input, kept beside the kernel's own cache so a -/// one-measure edit re-measures one measure's ink rather than the score's. -#[derive(Clone, Debug, Default)] -struct MeasureCache { - /// The onsets, in time order, matching `source.columns` one for one. - onsets: Vec, - /// Distance from this measure's closing barline back to the next - /// measure's first column. - lead_after: f64, - /// Ink reach above the upper staff's top line, in staff spaces. - above: f64, - /// Ink reach below the lower staff's bottom line. - below: f64, -} - -/// The document's horizontal spacing and page plan. -pub struct ScoreSpacing { - style: LayoutStyle, - incremental: IncrementalLayout, - sources: Vec, - cache: Vec, - measure_ids: Vec, - /// Page x where music starts on a system that shows no time signature. - music_left: f64, - /// Page x where music starts on the score's very first system. - music_left_first: f64, - widths: LineWidths, - systems: Vec, - pages: Vec, - /// Which systems each page carries, with its vertical adjustment ratio. - page_fills: Vec<(Range, f64)>, - /// Page index of every measure, by score order. - measure_page: Vec, - stats: RelayoutStats, -} - -impl Default for ScoreSpacing { - fn default() -> Self { - Self::new() - } -} - -impl ScoreSpacing { - pub fn new() -> Self { - Self { - style: LayoutStyle::default(), - incremental: IncrementalLayout::new(), - sources: Vec::new(), - cache: Vec::new(), - measure_ids: Vec::new(), - music_left: MARGIN_LEFT + 8.0, - music_left_first: MARGIN_LEFT + 8.0, - widths: LineWidths::uniform(Sp(1.0)), - systems: Vec::new(), - pages: Vec::new(), - page_fills: Vec::new(), - measure_page: Vec::new(), - stats: RelayoutStats::default(), - } - } - - pub fn style(&self) -> &LayoutStyle { - &self.style - } - - pub fn pages(&self) -> &[PagePlacement] { - &self.pages - } - - pub fn page_count(&self) -> usize { - self.pages.len() - } - - pub fn stats(&self) -> RelayoutStats { - self.stats - } - - pub fn page_of_measure(&self, index: usize) -> Option { - self.measure_page.get(index).copied() - } - - /// Where a moment in the score is on the page, for the playback cursor: - /// page index, page x, and the vertical extent of the system it lands in. - /// The system span is what keeps the cursor from ruling the whole sheet. - pub fn locate(&self, score: &Score, whole: f64) -> Option { - let index = self.measure_ids.iter().position(|id| { - score.measures.get(id).is_some_and(|measure| { - let start = rational_f64(measure.start.0); - let end = start + rational_f64(measure.extent.0); - whole >= start && whole < end - }) - })?; - let measure = score.measures.get(&self.measure_ids[index])?; - let start = rational_f64(measure.start.0); - let end = start + rational_f64(measure.extent.0); - let page = *self.measure_page.get(index)?; - let system = self - .pages - .get(page)? - .systems - .iter() - .find(|system| system.measures.iter().any(|placement| placement.index == index))?; - let placement = system - .measures - .iter() - .find(|placement| placement.index == index)?; - Some(CursorLocation { - page, - x_sp: placement.x_at(whole, start, end), - top_sp: system.top - CURSOR_SYSTEM_PAD, - bottom_sp: system.bottom + CURSOR_SYSTEM_PAD, - }) - } - - /// Re-measure every measure and lay the whole score out. Used on load and - /// after any edit that can move more than one measure (undo, redo). - pub fn rebuild(&mut self, score: &Score) { - let font = music_font(); - let measures = ordered_measures(score); - self.measure_ids = measures.iter().map(|measure| measure.id).collect(); - // Measure every bar's ink once; a bar's trailing rod needs the next - // bar's leading ink, which is the neighbour in this same list. - let inks: Vec = measures - .iter() - .map(|measure| measure_ink(score, font, measure, &self.style.distance)) - .collect(); - let previous: Vec = self.sources.iter().map(|source| source.revision).collect(); - self.sources.clear(); - self.cache.clear(); - for (index, measure) in measures.iter().enumerate() { - let revision = previous.get(index).copied().unwrap_or(0).wrapping_add(1); - let next_left = leading_ink(inks.get(index + 1)); - let (source, cache) = self.springs(measure, &inks[index], next_left, revision); - self.sources.push(source); - self.cache.push(cache); - } - self.plan_prefix(score, font); - self.relayout(); - self.repaginate(); - } - - /// One measure changed. Re-measures that measure (and its predecessor, - /// whose trailing rod reaches across the barline into it), then asks the - /// kernel for the cheapest relayout it can get away with. - pub fn touch_measure(&mut self, score: &Score, index: usize) -> PagesDirty { - if index >= self.sources.len() { - self.rebuild(score); - return PagesDirty::All; - } - let font = music_font(); - let measures = ordered_measures(score); - let mut touched = vec![index]; - if index > 0 { - touched.insert(0, index - 1); - } - for &at in &touched { - let revision = self.sources[at].revision.wrapping_add(1); - let Some(measure) = measures.get(at) else { continue }; - let ink = measure_ink(score, font, measure, &self.style.distance); - let next_left = leading_ink( - measures - .get(at + 1) - .map(|next| measure_ink(score, font, next, &self.style.distance)) - .as_ref(), - ); - let (source, cache) = self.springs(measure, &ink, next_left, revision); - // The predecessor is only really dirty when the edit changed the - // ink its trailing rod reaches into, so compare before bumping. - if at != index - && source.columns == self.sources[at].columns - && source.break_right == self.sources[at].break_right - { - continue; - } - self.sources[at] = source; - self.cache[at] = cache; - } - let before: Vec> = self.systems.iter().map(|s| s.measures.clone()).collect(); - self.relayout(); - let after: Vec> = self.systems.iter().map(|s| s.measures.clone()).collect(); - if before != after { - self.repaginate(); - return PagesDirty::All; - } - // Same breaks: only the pages carrying a re-solved system move. - let mut dirty: Vec = touched - .iter() - .filter_map(|&at| self.measure_page.get(at).copied()) - .collect(); - dirty.sort_unstable(); - dirty.dedup(); - for &page in &dirty { - self.place_page(page); - } - PagesDirty::Only(dirty) - } - - /// The kernel's incremental line layout over the cached measure sources. - fn relayout(&mut self) { - self.systems = self - .incremental - .layout(&self.sources, self.widths, &self.style) - .to_vec(); - self.stats = self.incremental.stats(); - } - - /// Where music starts, and therefore how wide a system is. - /// - /// The clef and key signature are drawn at every system start, so their - /// width comes off every system; the time signature is drawn once, so it - /// comes off the first system only. The key allowance is the *widest* - /// key the score uses, which keeps the music left edge aligned down the - /// page even across a key change. - fn plan_prefix(&mut self, score: &Score, font: &'static MusicFont) { - let mut fifths = 0_i8; - for measure in ordered_measures(score) { - if let Some(key) = score.maps.key_at(measure.start, None, None) { - if key.fifths.unsigned_abs() > fifths.unsigned_abs() { - fifths = key.fifths; - } - } - } - let meter = score - .maps - .meter_at(ScoreTime::ZERO, None, None) - .cloned() - .unwrap_or(Meter::Measured { - groups: vec![4], - unit: 4, - }); - let key = KeySignature { fifths, custom: Vec::new() }; - let lead = self.style.distance.barline_to_note.0; - self.music_left = - crate::engrave::prefix_width(font, &key, None, &self.style) + MARGIN_LEFT + lead; - self.music_left_first = - crate::engrave::prefix_width(font, &key, Some(&meter), &self.style) + MARGIN_LEFT + lead; - let right = PAGE_WIDTH_SP - MARGIN_RIGHT; - // The chain runs from the first column to one `barline_to_note` past - // the closing barline, so solving to this target lands that barline - // exactly on the right edge. - self.widths = LineWidths { - first: Sp(right - self.music_left_first + lead), - rest: Sp(right - self.music_left + lead), - }; - } - - /// Turn one measure's measured ink into springs and rods. - /// - /// `next_left` is the ink the *following* measure's first column hangs - /// left of its notehead — an accidental, say — which this measure's - /// trailing rod has to clear along with the barline. - fn springs( - &self, - measure: &Measure, - ink: &MeasureInk, - next_left: f64, - revision: u64, - ) -> (MeasureSource, MeasureCache) { - let extent = rational_f64(measure.extent.0).max(1e-9); - let start = rational_f64(measure.start.0); - let distance = &self.style.distance; - // The rod has to clear the barline the engraver actually draws, so - // take its thickness from the font's own engraving defaults. - let barline = music_font() - .engraving() - .thin_barline_thickness - .max(self.style.stroke.barline_thin.0); - let lead_after = if next_left > 0.0 { - (distance.barline_to_accidental.0 + next_left).max(distance.barline_to_note.0) - } else { - distance.barline_to_note.0 - }; - - let mut columns = Vec::with_capacity(ink.columns.len().max(1)); - for (at, column) in ink.columns.iter().enumerate() { - let onset = rational_f64(column.onset.0) - start; - let next = ink - .columns - .get(at + 1) - .map(|next| rational_f64(next.onset.0) - start) - .unwrap_or(extent); - // The spring's duration is the interval to the next onset: what - // this column has to *say*, as opposed to what it has to clear. - let duration = (next - onset).max(1.0 / 512.0); - let gap = if at + 1 < ink.columns.len() { - distance.note_to_note_min.0 + ink.columns[at + 1].left - } else { - distance.note_to_barline.0 + barline + lead_after - }; - columns.push(spring(column.right + gap, duration, &self.style)); - } - if columns.is_empty() { - // An empty measure still has to be wide enough to read as one. - columns.push(spring(distance.min_measure_width.0, extent, &self.style)); - } - let cache = MeasureCache { - onsets: ink.columns.iter().map(|column| column.onset).collect(), - lead_after, - above: ink.above, - below: ink.below, - }; - ( - MeasureSource { - revision, - columns, - break_right: BreakRule::Allowed, - spanner_penalty: 0.0, - }, - cache, - ) - } - - /// Stack the systems onto pages and place every column on every page. - fn repaginate(&mut self) { - let verticals: Vec = self - .systems - .iter() - .map(|system| { - let (above, below) = self.system_reach(&system.measures); - SystemVertical { - height: Sp(STAFF_SPAN + above + below), - gap_natural: self.style.vertical.system_distance_min, - gap_min: self.style.vertical.system_distance_min * 0.7, - gap_stretch: self.style.vertical.system_distance_max - - self.style.vertical.system_distance_min, - turn_after: TurnRule::Allowed, - } - }) - .collect(); - let plan = break_pages( - &verticals, - PageSpec { - usable_height: Sp(PAGE_MUSIC_BOTTOM - PAGE_MUSIC_TOP), - }, - &self.style.breaking, - ); - self.pages.clear(); - self.measure_page = vec![0; self.sources.len()]; - // A score with nothing on it still gets one page to put its title on. - let fills: Vec> = if plan.pages.is_empty() { - vec![0..self.systems.len()] - } else { - plan.pages.iter().map(|page| page.systems.clone()).collect() - }; - for (page_index, fill) in fills.iter().enumerate() { - self.pages.push(PagePlacement::default()); - for system in fill.clone() { - for measure in self.systems[system].measures.clone() { - if let Some(slot) = self.measure_page.get_mut(measure) { - *slot = page_index; - } - } - } - } - let adjustments: Vec<(Range, f64)> = fills - .iter() - .cloned() - .zip( - plan.pages - .iter() - .map(|page| if page.justified { page.adjustment } else { 0.0 }) - .chain(std::iter::repeat(0.0)), - ) - .collect(); - self.page_fills = adjustments; - for page in 0..self.pages.len() { - self.place_page(page); - } - } - - fn system_reach(&self, measures: &Range) -> (f64, f64) { - let mut above = 3.0_f64; - let mut below = 3.0_f64; - for index in measures.clone() { - if let Some(cache) = self.cache.get(index) { - above = above.max(cache.above); - below = below.max(cache.below); - } - } - (above.min(14.0), below.min(14.0)) - } - - /// Turn one page's solved column widths into page coordinates. - fn place_page(&mut self, page_index: usize) { - let Some((fill, adjustment)) = self.page_fills.get(page_index).cloned() else { - return; - }; - let mut placed = PagePlacement::default(); - let mut y = PAGE_MUSIC_TOP; - for system_index in fill.clone() { - let system = &self.systems[system_index]; - let (above, below) = self.system_reach(&system.measures); - if system_index != fill.start { - let gap = self.style.vertical.system_distance_min.0 - + adjustment - * (self.style.vertical.system_distance_max.0 - - self.style.vertical.system_distance_min.0); - y += gap; - } - let top = y + above; - y += STAFF_SPAN + above + below; - let show_meter = system.measures.start == 0; - let music_left = if show_meter { - self.music_left_first - } else { - self.music_left - }; - let mut x = music_left; - let mut widths = system.solution.widths.iter().map(|w| w.0); - let mut measures = Vec::with_capacity(system.measures.len()); - // Measure boundaries tile the system: each starts where the - // previous one's barline stands. - let mut left = music_left - self.style.distance.barline_to_note.0; - for index in system.measures.clone() { - let source = &self.sources[index]; - let cache = &self.cache[index]; - let mut columns = Vec::with_capacity(cache.onsets.len()); - for (at, _) in source.columns.iter().enumerate() { - if let Some(&onset) = cache.onsets.get(at) { - columns.push(ColumnPlacement { onset, x }); - } - x += widths.next().unwrap_or(0.0); - } - // The closing barline stands back from the next measure's - // first column by the same lead its trailing rod reserved; - // the system's last barline lands on the right edge. - let last = index + 1 == system.measures.end; - let lead = if last { - self.style.distance.barline_to_note.0 - } else { - cache.lead_after - }; - let right = x - lead; - measures.push(MeasurePlacement { - measure: self.measure_ids[index], - index, - left, - right, - columns, - }); - left = right; - } - placed.systems.push(SystemPlacement { - top, - bottom: top + STAFF_SPAN, - music_left, - right: PAGE_WIDTH_SP - MARGIN_RIGHT, - show_meter, - measures, - }); - } - if let Some(slot) = self.pages.get_mut(page_index) { - *slot = placed; - } - } -} - -/// Build one column's spring from its rod and its duration. -/// -/// `headroom` is the rod, so the regularizer's notion of "whitespace" -/// (`width - headroom`) is exactly the duration space, and both flexibilities -/// are that same duration space — see the module docs for why. -fn spring(rod: f64, duration: f64, style: &LayoutStyle) -> SpacingColumn { - let space = style.spacing.spacing_increment.0 - * makepad_score_layout::duration_quanta(duration, &style.spacing); - SpacingColumn { - natural: Sp(rod + space), - minimum: Sp(rod), - stretch_flex: space.max(style.spacing.min_stretch_flex), - shrink_flex: space.max(style.spacing.min_shrink_flex), - headroom: Sp(rod), - duration_class: Some((duration * 1024.0).round().clamp(0.0, 4096.0) as u32), - } -} - -/// One onset's measured ink, merged over every voice and both staves. -#[derive(Clone, Copy, Debug)] -pub(crate) struct ColumnInk { - pub onset: ScoreTime, - /// Ink reaching left of the notehead origin: accidentals, and the heads - /// a down-stem chord pushes to the far side of its stem. - pub left: f64, - /// Ink reaching right of it: the notehead advance, second-interval head - /// shifts, augmentation dots. - pub right: f64, -} - -/// A measure's merged onset columns plus its vertical reach. -pub(crate) struct MeasureInk { - pub columns: Vec, - pub above: f64, - pub below: f64, -} - -/// Measure one measure: what ink sits at each onset, and how far the ink -/// reaches above and below the grand staff. -pub(crate) fn measure_ink( - score: &Score, - font: &'static MusicFont, - measure: &Measure, - distance: &DistanceStyle, -) -> MeasureInk { - let key = score - .maps - .key_at(measure.start, None, None) - .cloned() - .unwrap_or(KeySignature::C_MAJOR); - let frames = staff_frames(0.0); - let staves = measure_staff_columns(font, score, measure, &key, &frames); - let mut merged: BTreeMap = BTreeMap::new(); - let mut top = 0.0_f64; - let mut bottom = STAFF_SPAN; - for voices in &staves { - for columns in voices { - for column in columns { - let (left, right) = column_extents(font, column, distance); - let entry = merged.entry(column.time).or_insert((0.0, 0.0)); - entry.0 = entry.0.max(left); - entry.1 = entry.1.max(right); - top = top.min(column.top_y()); - bottom = bottom.max(column.bottom_y()); - } - } - } - MeasureInk { - columns: merged - .into_iter() - .map(|(onset, (left, right))| ColumnInk { onset, left, right }) - .collect(), - // A notehead is one staff space tall; stems, beams and flags reach - // roughly a stem length past the outermost head. - above: (-top + 1.0 + 2.0).max(3.0), - below: (bottom - STAFF_SPAN + 1.0 + 2.0).max(3.0), - } -} - -/// How far one chord's ink reaches either side of its notehead origin. -fn column_extents(font: &'static MusicFont, column: &Column, distance: &DistanceStyle) -> (f64, f64) { - let head = column - .heads - .iter() - .map(|head| font.advance(&head.glyph).max(font.bbox(&head.glyph).width())) - .fold(0.0_f64, f64::max) - .max(0.6); - let shifted = column.heads.iter().any(|head| head.shifted); - // A second-interval head sits on the far side of the stem: to the right - // for an up stem, to the left for a down stem. - let (mut left, mut right) = match (shifted, column.stem_up) { - (false, _) => (0.0, head), - (true, true) => (0.0, head * 2.0), - (true, false) => (head, head), - }; - let accidental = column - .heads - .iter() - .filter_map(|head| head.accidental.as_deref()) - .map(|name| font.advance(name).max(font.bbox(name).width())) - .fold(0.0_f64, f64::max); - if accidental > 0.0 { - left += accidental + distance.accidental_to_note.0; - } - if column.value.dots > 0 { - let dot = font.advance("augmentationDot").max(0.3); - let dots = f64::from(column.value.dots); - right += distance.note_to_dot.0 + dots * dot + (dots - 1.0) * distance.dot_to_dot.0; - } - (left, right) -} - -/// How far the first column of a measure reaches left of its notehead. -fn leading_ink(ink: Option<&MeasureInk>) -> f64 { - ink.and_then(|ink| ink.columns.first()) - .map(|column| column.left) - .unwrap_or(0.0) -} - -pub(crate) fn ordered_measures(score: &Score) -> Vec<&Measure> { - let mut measures: Vec<&Measure> = score.measures.values().collect(); - measures.sort_by_key(|measure| (measure.ordinal, measure.start)); - measures -} - -pub(crate) fn rational_f64(value: Rational) -> f64 { - value.numerator() as f64 / value.denominator() as f64 -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::engrave::tests::{engrave, fixture, fixture_events, Placed}; - use makepad_score::model::Step; - use makepad_score_layout::duration_quanta; - - const SCALE: [Step; 7] = [ - Step::C, - Step::D, - Step::E, - Step::F, - Step::G, - Step::A, - Step::B, - ]; - - /// The x of every notehead on the page, left to right. - fn head_xs(score: &Score) -> Vec { - let mut xs: Vec = engrave(score) - .noteheads - .into_iter() - .map(|(x, _, _)| x) - .collect(); - xs.sort_by(f64::total_cmp); - xs - } - - fn run(count: usize, denominator: u64) -> Score { - let pitches: Vec<(Step, i8)> = (0..count).map(|i| (SCALE[i % 7], 4)).collect(); - fixture(&pitches, denominator) - } - - /// The headline defect this module exists to fix: a run of equal notes - /// must advance by one constant step, not bunch up at the barline. - #[test] - fn a_run_of_sixteenths_advances_in_equal_steps() { - let font = music_font(); - let style = LayoutStyle::default(); - let xs = head_xs(&run(16, 16)); - assert_eq!(xs.len(), 16); - let steps: Vec = xs.windows(2).map(|pair| pair[1] - pair[0]).collect(); - let first = steps[0]; - for step in &steps { - assert!( - (step - first).abs() < 1e-9, - "sixteenths are unevenly spaced: {steps:?}" - ); - } - // And every step clears the ink: notehead advance plus the house - // minimum whitespace between notes. - let rod = font.advance("noteheadBlack") + style.distance.note_to_note_min.0; - assert!(first > rod, "step {first} is tighter than the rod {rod}"); - } - - /// A single bar is not smeared across the page: below the style's - /// fill threshold the last system stays ragged at its natural width. - #[test] - fn a_one_bar_score_stays_ragged() { - let drawn = engrave(&run(16, 16)); - let margin = PAGE_WIDTH_SP - MARGIN_RIGHT; - assert!( - drawn.system_right < margin - 10.0, - "a one-bar score was stretched to {} of {margin}", - drawn.system_right - ); - // But it still starts where music starts, and the notes fill it. - let last = drawn.noteheads.iter().map(|(x, _, _)| *x).fold(0.0, f64::max); - assert!(last < drawn.system_right && last > drawn.system_right - 6.0); - } - - /// Space follows the duration curve, not the clock: a half note gets the - /// curve's ratio more whitespace than a quarter, never four times more. - #[test] - fn a_long_note_earns_curve_much_room_not_clock_much() { - let font = music_font(); - let style = LayoutStyle::default(); - let xs = head_xs(&fixture_events(&[ - Placed { onset: (0, 1), duration: (1, 2), step: Step::G, octave: 4 }, - Placed { onset: (1, 2), duration: (1, 4), step: Step::A, octave: 4 }, - Placed { onset: (3, 4), duration: (1, 4), step: Step::B, octave: 4 }, - ])); - assert_eq!(xs.len(), 3); - let gap = style.distance.note_to_note_min.0; - let white_half = (xs[1] - xs[0]) - (font.advance("noteheadHalf") + gap); - let white_quarter = (xs[2] - xs[1]) - (font.advance("noteheadBlack") + gap); - let want = duration_quanta(0.5, &style.spacing) / duration_quanta(0.25, &style.spacing); - let got = white_half / white_quarter; - assert!( - (got - want).abs() < 1e-6, - "whitespace ratio {got} should follow the duration curve {want}" - ); - // Sanity: the clock ratio would have been 2.0. - assert!(got < 1.5); - } - - /// The rods are measured ink, not a guess: for a plain run they are the - /// font's own notehead advance plus the house note-to-note minimum, and - /// the last one also has to clear the barline. - #[test] - fn rods_are_measured_from_the_font() { - let font = music_font(); - let style = LayoutStyle::default(); - let score = run(8, 8); - let measures = ordered_measures(&score); - let ink = measure_ink(&score, font, measures[0], &style.distance); - assert_eq!(ink.columns.len(), 8); - for column in &ink.columns { - assert_eq!(column.left, 0.0); - assert!((column.right - font.advance("noteheadBlack")).abs() < 1e-9); - } - let mut spacing = ScoreSpacing::new(); - spacing.rebuild(&score); - let rods: Vec = spacing.sources[0] - .columns - .iter() - .map(|column| column.minimum.0) - .collect(); - let inner = font.advance("noteheadBlack") + style.distance.note_to_note_min.0; - for rod in &rods[..7] { - assert!((rod - inner).abs() < 1e-9, "inner rod {rod} != {inner}"); - } - // The trailing rod carries the note-to-barline space, the barline - // itself and the lead into the next measure. - assert!(rods[7] > inner + style.distance.note_to_barline.0); - } - - /// Every column of a system is a spring whose whitespace is its duration - /// space scaled by one shared force. That is the invariant the engraved - /// picture rests on, so pin it directly on the solved widths. - #[test] - fn one_force_scales_every_column_s_duration_space() { - let score = run(12, 16); - let mut spacing = ScoreSpacing::new(); - spacing.rebuild(&score); - let system = &spacing.systems[0]; - let force = system.solution.force; - for (column, width) in spacing.sources[0] - .columns - .iter() - .zip(&system.solution.widths) - { - let want = column.minimum.0 + (column.natural.0 - column.minimum.0) * (1.0 + force); - assert!( - (width.0 - want).abs() < 1e-9, - "column width {} is not rod + duration space * (1 + F)", - width.0 - ); - assert!(width.0 >= column.minimum.0 - 1e-12, "a rod was violated"); - } - } - - /// Systems no longer hold a constant four measures: the breaker decides, - /// and a bar of sixteenths costs more room than a bar of quarters. - #[test] - fn measures_per_system_follows_the_music() { - let dense = { - let mut score = run(16, 16); - grow(&mut score, 8); - score - }; - let sparse = { - let mut score = run(4, 4); - grow(&mut score, 8); - score - }; - let mut a = ScoreSpacing::new(); - a.rebuild(&dense); - let mut b = ScoreSpacing::new(); - b.rebuild(&sparse); - let per = |s: &ScoreSpacing| s.systems[0].measures.len(); - assert!( - per(&a) < per(&b), - "sixteenths {} should not fit as densely as quarters {}", - per(&a), - per(&b) - ); - } - - /// Repeat a one-measure fixture `count` times, so a score has something - /// for the line breaker to break. - fn grow(score: &mut Score, count: u32) { - let first = ordered_measures(score)[0].id; - let template = score.measures[&first].clone(); - let events: Vec<_> = score - .voices - .values() - .map(|voice| (voice.id, voice.events.clone())) - .collect(); - let mut ids = makepad_score::model::IdGenerator::new(0x7e58); - for ordinal in 1..count { - let start = ScoreTime::new(i64::from(ordinal), 1).unwrap(); - let id = ids.next::().unwrap(); - score.measures.insert( - id, - Measure { - id, - ordinal, - label: (ordinal + 1).to_string(), - start, - extent: template.extent, - }, - ); - score.flow.nodes.push(makepad_score::model::FlowNode { - measure: id, - ordinal, - }); - for (voice, source) in &events { - let mut copies = Vec::with_capacity(source.len()); - for event in source { - let mut event = event.clone(); - event.id = ids.next::().unwrap(); - event.onset = event.onset.checked_add_time(start).unwrap(); - if let makepad_score::model::EventKind::Chord(notes) = &mut event.kind { - for note in notes { - note.id = ids.next::().unwrap(); - } - } - copies.push(event); - } - score.voices.get_mut(voice).unwrap().events.extend(copies); - } - } - } -} +pub use makepad_score_view::spacing::*; diff --git a/libs/score_ui/src/state.rs b/libs/score_ui/src/state.rs index cab5eab93..19ce7a9a1 100644 --- a/libs/score_ui/src/state.rs +++ b/libs/score_ui/src/state.rs @@ -884,7 +884,7 @@ fn pitch_name(diatonic: i32, alter: i32) -> String { /// The score's own opening tempo, when it carries one. An imported performance /// knows its tempo; playing it at the app default is simply wrong music. -fn score_opening_tempo(score: &makepad_score::model::Score) -> Option { +pub(crate) fn score_opening_tempo(score: &makepad_score::model::Score) -> Option { score.maps.tempo.iter().find_map(|change| match change.value { makepad_score::model::Tempo::Instant { quarters_per_minute } => { let bpm = rational_f64(quarters_per_minute); diff --git a/libs/score_view/Cargo.toml b/libs/score_view/Cargo.toml new file mode 100644 index 000000000..7de43f0c9 --- /dev/null +++ b/libs/score_view/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "makepad-score-view" +version = "0.1.0" +edition = "2021" +description = "Playback-free score engraving and Makepad score widget" +license = "MIT OR Apache-2.0" + +[lib] +name = "makepad_score_view" + +[features] +default = ["embed-bravura"] +embed-bravura = [] + +[dependencies] +makepad-widgets = { path = "../../widgets", version = "2.0.0" } +makepad-score = { path = "../score", version = "1.0.0" } +makepad-score-layout = { path = "../score_layout", version = "0.1.0" } +makepad-score-render = { path = "../score_render", version = "0.1.0" } +ttf-parser = { path = "../ttf-parser" } + +[dev-dependencies] +makepad-test = { path = "../makepad_test", version = "0.1.0" } +makepad-zune-png = { path = "../zune/zune-png", version = "0.5.2" } diff --git a/apps/score/resources/fonts/OFL.txt b/libs/score_view/resources/fonts/OFL.txt similarity index 100% rename from apps/score/resources/fonts/OFL.txt rename to libs/score_view/resources/fonts/OFL.txt diff --git a/apps/score/resources/fonts/bravura.otf b/libs/score_view/resources/fonts/bravura.otf similarity index 100% rename from apps/score/resources/fonts/bravura.otf rename to libs/score_view/resources/fonts/bravura.otf diff --git a/apps/score/resources/fonts/bravura_metadata.json b/libs/score_view/resources/fonts/bravura_metadata.json similarity index 100% rename from apps/score/resources/fonts/bravura_metadata.json rename to libs/score_view/resources/fonts/bravura_metadata.json diff --git a/apps/score/resources/fonts/glyphnames.json b/libs/score_view/resources/fonts/glyphnames.json similarity index 100% rename from apps/score/resources/fonts/glyphnames.json rename to libs/score_view/resources/fonts/glyphnames.json diff --git a/libs/score_view/src/build.rs b/libs/score_view/src/build.rs new file mode 100644 index 000000000..b4ea070d5 --- /dev/null +++ b/libs/score_view/src/build.rs @@ -0,0 +1,932 @@ +//! Programmatic builders for short percussion, pitched, and bass-tab scores. + +use crate::document::pitch_from_midi; +use makepad_score::{ + model::*, + symbol::Clef, +}; +use std::collections::BTreeMap; + +const BUILDER_ACTOR: u64 = 0x6275_696c_6465_7273; + +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum DrumVoice { + Kick, + Snare, + SideStick, + HiHatClosed, + HiHatOpen, + HiHatPedal, + TomHigh, + TomMid, + TomLow, + TomFloor, + Ride, + RideBell, + Crash, +} + +impl DrumVoice { + pub const ALL: [Self; 13] = [ + Self::Kick, + Self::Snare, + Self::SideStick, + Self::HiHatClosed, + Self::HiHatOpen, + Self::HiHatPedal, + Self::TomHigh, + Self::TomMid, + Self::TomLow, + Self::TomFloor, + Self::Ride, + Self::RideBell, + Self::Crash, + ]; + + pub const fn gm_note(self) -> u8 { + match self { + Self::Kick => 36, + Self::Snare => 38, + Self::SideStick => 37, + Self::HiHatClosed => 42, + Self::HiHatOpen => 46, + Self::HiHatPedal => 44, + Self::TomHigh => 50, + Self::TomMid => 48, + Self::TomLow => 45, + Self::TomFloor => 41, + Self::Ride => 51, + Self::RideBell => 53, + Self::Crash => 49, + } + } + + pub fn short_label(self) -> &'static str { + match self { + Self::Kick => "Kick", + Self::Snare | Self::SideStick => "Snare", + Self::HiHatClosed => "HH", + Self::HiHatOpen => "HH open", + Self::HiHatPedal => "Pedal", + Self::TomHigh => "Tom hi", + Self::TomMid => "Tom mid", + Self::TomLow => "Tom lo", + Self::TomFloor => "Floor", + Self::Ride => "Ride", + Self::RideBell => "Bell", + Self::Crash => "Crash", + } + } + + pub fn display(self) -> (Pitch, Notehead) { + let (step, octave, notehead) = match self { + Self::Kick => (Step::F, 4, Notehead::Normal), + Self::Snare => (Step::C, 5, Notehead::Normal), + Self::SideStick => (Step::C, 5, Notehead::X), + Self::HiHatClosed | Self::HiHatOpen => (Step::G, 5, Notehead::X), + Self::HiHatPedal => (Step::D, 4, Notehead::X), + Self::TomHigh => (Step::E, 5, Notehead::Normal), + Self::TomMid => (Step::D, 5, Notehead::Normal), + Self::TomLow => (Step::A, 4, Notehead::Normal), + Self::TomFloor => (Step::F, 4, Notehead::Normal), + Self::Ride => (Step::F, 5, Notehead::X), + Self::RideBell => (Step::F, 5, Notehead::Diamond), + Self::Crash => (Step::A, 5, Notehead::X), + }; + (Pitch::new(step, Alter::NATURAL, octave), notehead) + } + + fn name(self) -> &'static str { + match self { + Self::Kick => "Kick drum", + Self::Snare => "Snare drum", + Self::SideStick => "Side stick", + Self::HiHatClosed => "Closed hi-hat", + Self::HiHatOpen => "Open hi-hat", + Self::HiHatPedal => "Pedal hi-hat", + Self::TomHigh => "High tom", + Self::TomMid => "Mid tom", + Self::TomLow => "Low tom", + Self::TomFloor => "Floor tom", + Self::Ride => "Ride cymbal", + Self::RideBell => "Ride bell", + Self::Crash => "Crash cymbal", + } + } +} + +#[derive(Clone, Copy, Debug)] +pub struct DrumHit { + pub time_beats: f64, + pub voice: DrumVoice, + pub velocity: f32, +} + +#[derive(Clone, Copy, Debug)] +pub struct PitchedNote { + pub onset_beats: f64, + pub duration_beats: f64, + pub midi: u8, + pub velocity: f32, +} + +#[derive(Clone, Debug, PartialEq)] +pub struct LyricWord { + pub onset_beats: f64, + pub end_beats: f64, + pub text: String, +} + +#[derive(Clone, Debug)] +pub struct BuildOptions { + pub bars: u32, + pub beats_per_bar: u32, + pub grid: Duration, + pub bpm: Option, + pub title: Option, +} + +impl Default for BuildOptions { + fn default() -> Self { + Self { + bars: 1, + beats_per_bar: 4, + grid: Duration::new(1, 16).expect("1/16 is a duration"), + bpm: None, + title: None, + } + } +} + +pub fn build_drum_score(hits: &[DrumHit], opts: &BuildOptions) -> Score { + let mut skeleton = Skeleton::new( + opts, + "Percussion", + StaffKind::Percussion(PercussionMap { + entries: DrumVoice::ALL + .into_iter() + .map(|voice| { + let (display, _) = voice.display(); + ( + u16::from(voice.gm_note()), + PercussionSound { + name: voice.name().into(), + midi_note: voice.gm_note(), + display, + }, + ) + }) + .collect(), + }), + Clef::Percussion, + 3, + *b"DRUMSCOREBUILD01", + ); + let total = skeleton.grid.total_ticks; + let mut at: BTreeMap> = BTreeMap::new(); + for hit in hits { + let tick = skeleton.grid.quantize_onset(hit.time_beats); + if tick < total { + at.entry(tick).or_default().push(hit); + } + } + let mut rhythmic = Vec::new(); + for (tick, hits) in at { + let notes = hits + .into_iter() + .map(|hit| { + let (pitch, notehead) = hit.voice.display(); + Note { + id: skeleton.next::(), + performance: performance(hit.velocity), + written_pitch: Some(pitch), + unpitched_sound: Some(u16::from(hit.voice.gm_note())), + display_staff: skeleton.staff, + tie_from: None, + tie_to: None, + tab: None, + notehead, + } + }) + .collect(); + rhythmic.push(Rhythmic { + start: tick, + ticks: 1, + kind: EventKind::Chord(notes), + }); + } + let rhythmic = fill_rests(rhythmic, &skeleton.grid); + skeleton.finish(rhythmic) +} + +pub fn build_pitched_score(notes: &[PitchedNote], opts: &BuildOptions) -> Score { + let median = median_midi(notes); + let (clef, line) = if median >= 60 { (Clef::G, 2) } else { (Clef::F, 4) }; + let mut skeleton = Skeleton::new( + opts, + "Notes", + StaffKind::Standard, + clef, + line, + *b"PITCHSCOREBUILD1", + ); + let groups = quantized_groups(notes, &skeleton.grid); + let rhythmic = pitched_events(groups, &mut skeleton, None); + let rhythmic = fill_rests(rhythmic, &skeleton.grid); + skeleton.finish(rhythmic) +} + +pub fn build_pitched_score_with_lyrics( + notes: &[PitchedNote], + lyrics: &[LyricWord], + opts: &BuildOptions, +) -> Score { + let mut score = build_pitched_score(notes, opts); + attach_lyrics(&mut score, lyrics, opts); + score +} + +fn attach_lyrics(score: &mut Score, words: &[LyricWord], opts: &BuildOptions) { + #[derive(Clone, Copy)] + struct LyricNote { + onset_beats: f64, + note: NoteId, + } + + let mut notes = score + .voices + .values() + .flat_map(|voice| &voice.events) + .filter_map(|event| { + let note = event + .chord_notes() + .iter() + .find(|note| note.tie_from.is_none())?; + Some(LyricNote { + onset_beats: event.onset.0.numerator() as f64 + / event.onset.0.denominator() as f64 + * 4.0, + note: note.id, + }) + }) + .collect::>(); + notes.sort_by(|left, right| left.onset_beats.total_cmp(&right.onset_beats)); + if notes.is_empty() { + return; + } + + let total_beats = f64::from(opts.bars.max(1)) * f64::from(opts.beats_per_bar.max(1)); + let mut assigned: Vec> = vec![Vec::new(); notes.len()]; + for word in words { + if word.text.trim().is_empty() + || !word.onset_beats.is_finite() + || word.onset_beats < 0.0 + || word.onset_beats >= total_beats + { + continue; + } + let length = if word.end_beats.is_finite() { + (word.end_beats - word.onset_beats).max(0.0) + } else { + 0.0 + }; + let tolerance = 0.25_f64.max(length * 0.15); + let Some((index, distance)) = notes + .iter() + .enumerate() + .map(|(index, note)| (index, (note.onset_beats - word.onset_beats).abs())) + .min_by(|left, right| { + left.1 + .total_cmp(&right.1) + .then_with(|| left.0.cmp(&right.0)) + }) + else { + continue; + }; + if distance <= tolerance { + assigned[index].push(word); + } + } + + for words in &mut assigned { + words.sort_by(|left, right| left.onset_beats.total_cmp(&right.onset_beats)); + } + for index in 0..notes.len() { + if assigned[index].is_empty() { + continue; + } + let text = assigned[index] + .iter() + .map(|word| word.text.trim()) + .collect::>() + .join(" "); + let word_end = assigned[index] + .iter() + .filter_map(|word| word.end_beats.is_finite().then_some(word.end_beats)) + .max_by(f64::total_cmp) + .unwrap_or(notes[index].onset_beats); + let next_word_note = assigned[index + 1..] + .iter() + .position(|words| !words.is_empty()) + .map(|offset| index + 1 + offset) + .unwrap_or(notes.len()); + let melisma_to = notes[index + 1..next_word_note] + .iter() + .take_while(|note| note.onset_beats <= word_end) + .last() + .map(|note| note.note); + score.lyrics.push(LyricSyllable { + note: notes[index].note, + verse: 1, + text, + role: SyllabicRole::Single, + elision: None, + melisma_to, + }); + } +} + +pub fn build_bass_tab_score(notes: &[PitchedNote], tuning: &[u8], opts: &BuildOptions) -> Score { + let tuning = if tuning.is_empty() { &[28, 33, 38, 43][..] } else { tuning }; + let pitches = tuning.iter().copied().map(pitch_from_midi).collect(); + let mut skeleton = Skeleton::new( + opts, + "Bass tablature", + StaffKind::Tablature(Tuning { strings_low_to_high: pitches }), + if tuning.len() <= 4 { Clef::Tab4String } else { Clef::Tab6String }, + 3, + *b"BASSTABSCORE0001", + ); + let groups = quantized_groups(notes, &skeleton.grid); + let rhythmic = pitched_events(groups, &mut skeleton, Some(tuning)); + let rhythmic = fill_rests(rhythmic, &skeleton.grid); + skeleton.finish(rhythmic) +} + +struct Grid { + duration: Duration, + ticks_per_beat: i64, + total_ticks: i64, +} + +impl Grid { + fn new(opts: &BuildOptions) -> Self { + let beats = i64::from(opts.beats_per_bar.max(1)); + let bars = i64::from(opts.bars.max(1)); + let numerator = opts.grid.0.numerator().max(1); + let denominator = opts.grid.0.denominator() as i64; + let ticks_per_beat = div_round(denominator, 4 * numerator).max(1); + Self { + duration: opts.grid, + ticks_per_beat, + total_ticks: ticks_per_beat * beats * bars, + } + } + + fn quantize_onset(&self, beats: f64) -> i64 { + if !beats.is_finite() { + return 0; + } + (beats.max(0.0) * self.ticks_per_beat as f64).round() as i64 + } + + fn quantize_duration(&self, beats: f64) -> i64 { + if !beats.is_finite() { + return 1; + } + (beats.max(0.0) * self.ticks_per_beat as f64).round().max(1.0) as i64 + } + + fn time(&self, tick: i64) -> ScoreTime { + ScoreTime(self.rational(tick)) + } + + fn duration(&self, ticks: i64) -> Duration { + Duration::from_rational(self.rational(ticks.max(1))).expect("positive grid duration") + } + + fn rational(&self, ticks: i64) -> Rational { + Rational::new( + self.duration.0.numerator().saturating_mul(ticks), + self.duration.0.denominator(), + ) + .expect("grid tick is representable") + } +} + +fn div_round(numerator: i64, denominator: i64) -> i64 { + (numerator + denominator / 2) / denominator +} + +struct Skeleton { + score: Score, + ids: IdGenerator, + staff: StaffId, + voice: VoiceId, + grid: Grid, +} + +impl Skeleton { + fn new( + opts: &BuildOptions, + part_name: &str, + kind: StaffKind, + clef: Clef, + clef_line: u8, + score_id: [u8; 16], + ) -> Self { + let grid = Grid::new(opts); + let mut ids = IdGenerator::new(BUILDER_ACTOR); + let part = ids.next::().expect("builder id space"); + let staff = ids.next::().expect("builder id space"); + let voice = ids.next::().expect("builder id space"); + let mut score = Score::new(score_id); + score.title = opts.title.clone().unwrap_or_default(); + score.parts.insert(part, Part { + id: part, + name: part_name.into(), + staves: vec![staff], + transposition: Transposition::NONE, + }); + score.staves.insert(staff, Staff { + id: staff, + part, + parent: None, + kind, + voices: vec![voice], + }); + let beats = opts.beats_per_bar.max(1); + let bars = opts.bars.max(1); + let extent = Duration::new(i64::from(beats), 4).expect("bar duration"); + for bar in 0..bars { + let id = ids.next::().expect("builder id space"); + let start = ScoreTime::new(i64::from(bar) * i64::from(beats), 4) + .expect("measure start"); + score.measures.insert(id, Measure { + id, + ordinal: bar, + label: (bar + 1).to_string(), + start, + extent, + }); + score.flow.nodes.push(FlowNode { measure: id, ordinal: bar }); + } + score.maps.time_signature.push(Change { + at: ScoreTime::ZERO, + scope: MapScope::Global, + value: Meter::Measured { groups: vec![beats as u16], unit: 4 }, + }); + if let Some(bpm) = opts.bpm.filter(|bpm| bpm.is_finite() && *bpm > 0.0) { + score.maps.tempo.push(Change { + at: ScoreTime::ZERO, + scope: MapScope::Global, + value: Tempo::Instant { + quarters_per_minute: Rational::new((bpm * 1000.0).round() as i64, 1000) + .expect("positive tempo"), + }, + }); + } + let mut events = vec![plain_event( + ids.next::().expect("builder id space"), + ScoreTime::ZERO, + EventKind::Clef(ClefChange { clef, line: clef_line }), + )]; + if let Some(bpm) = opts.bpm.filter(|bpm| bpm.is_finite() && *bpm > 0.0) { + events.push(plain_event( + ids.next::().expect("builder id space"), + ScoreTime::ZERO, + EventKind::Direction(DirectionEvent { + kind: DirectionKind::TempoText(format!("{} bpm", bpm.round() as u32)), + placement: None, + original_text: None, + }), + )); + } + score.voices.insert(voice, Voice { id: voice, staff, number: 1, events }); + Self { score, ids, staff, voice, grid } + } + + fn next(&mut self) -> Id { + self.ids.next::().expect("builder id space") + } + + fn finish(mut self, rhythmic: Vec) -> Score { + let mut timed = rhythmic + .into_iter() + .map(|event| TimedEvent { + id: self.next::(), + onset: self.grid.time(event.start), + duration: Some(self.grid.duration(event.ticks)), + grace: None, + kind: event.kind, + beams: Vec::new(), + tuplets: Vec::new(), + articulations: Vec::new(), + ornaments: Vec::new(), + }) + .collect::>(); + let voice = self.score.voices.get_mut(&self.voice).expect("builder voice"); + voice.events.append(&mut timed); + voice.events.sort_by_key(|event| (event.onset, event.id)); + self.score.maps.sort(); + self.score + } +} + +fn plain_event(id: EventId, onset: ScoreTime, kind: EventKind) -> TimedEvent { + TimedEvent { + id, + onset, + duration: None, + grace: None, + kind, + beams: Vec::new(), + tuplets: Vec::new(), + articulations: Vec::new(), + ornaments: Vec::new(), + } +} + +struct Rhythmic { + start: i64, + ticks: i64, + kind: EventKind, +} + +fn fill_rests(mut events: Vec, grid: &Grid) -> Vec { + events.sort_by_key(|event| event.start); + let mut output = Vec::new(); + let mut cursor = 0; + for event in events { + if event.start > cursor { + push_rests(&mut output, cursor, event.start, grid); + } + if event.start >= cursor { + cursor = event.start + event.ticks; + output.push(event); + } + } + if cursor < grid.total_ticks { + push_rests(&mut output, cursor, grid.total_ticks, grid); + } + output +} + +fn push_rests(output: &mut Vec, mut start: i64, end: i64, grid: &Grid) { + while start < end { + let in_beat = start.rem_euclid(grid.ticks_per_beat); + let beat_room = grid.ticks_per_beat - in_beat; + let room = (end - start).min(beat_room); + let mut ticks = largest_power_of_two_at_most(room); + while grid.ticks_per_beat % ticks != 0 && ticks > 1 { + ticks /= 2; + } + output.push(Rhythmic { start, ticks, kind: EventKind::Rest }); + start += ticks; + } +} + +fn largest_power_of_two_at_most(value: i64) -> i64 { + let mut result = 1; + while result <= value / 2 { + result *= 2; + } + result +} + +#[derive(Clone)] +struct NoteGroup { + start: i64, + ticks: i64, + notes: Vec<(u8, f32)>, +} + +fn quantized_groups(notes: &[PitchedNote], grid: &Grid) -> Vec { + let mut grouped: BTreeMap> = BTreeMap::new(); + for note in notes { + let start = grid.quantize_onset(note.onset_beats); + if start < grid.total_ticks { + grouped.entry(start).or_default().push(note); + } + } + let starts = grouped.keys().copied().collect::>(); + starts + .iter() + .enumerate() + .filter_map(|(index, start)| { + let source = &grouped[start]; + let wanted = source + .iter() + .map(|note| grid.quantize_duration(note.duration_beats)) + .max() + .unwrap_or(1); + let next = starts.get(index + 1).copied().unwrap_or(grid.total_ticks); + let end = (*start + wanted).min(next).min(grid.total_ticks); + (end > *start).then(|| { + let mut pitches = BTreeMap::new(); + for note in source { + pitches.insert(note.midi, note.velocity); + } + NoteGroup { + start: *start, + ticks: end - *start, + notes: pitches.into_iter().collect(), + } + }) + }) + .collect() +} + +fn pitched_events( + groups: Vec, + skeleton: &mut Skeleton, + tuning: Option<&[u8]>, +) -> Vec { + let mut output = Vec::new(); + for group in groups { + let mut pieces = Vec::new(); + let mut cursor = group.start; + let end = group.start + group.ticks; + while cursor < end { + let beat_end = ((cursor / skeleton.grid.ticks_per_beat) + 1) + * skeleton.grid.ticks_per_beat; + let piece_end = end.min(beat_end); + pieces.push((cursor, piece_end - cursor)); + cursor = piece_end; + } + let ids = (0..pieces.len()) + .map(|_| { + group + .notes + .iter() + .map(|_| skeleton.next::()) + .collect::>() + }) + .collect::>(); + for (piece_index, (start, ticks)) in pieces.into_iter().enumerate() { + let notes = group + .notes + .iter() + .enumerate() + .map(|(note_index, &(midi, velocity))| Note { + id: ids[piece_index][note_index], + performance: performance(velocity), + written_pitch: Some(pitch_from_midi(midi)), + unpitched_sound: None, + display_staff: skeleton.staff, + tie_from: piece_index + .checked_sub(1) + .map(|previous| ids[previous][note_index]), + tie_to: ids.get(piece_index + 1).map(|next| next[note_index]), + tab: tuning.and_then(|tuning| tab_position(midi, tuning)), + notehead: Notehead::Normal, + }) + .collect(); + output.push(Rhythmic { start, ticks, kind: EventKind::Chord(notes) }); + } + } + output +} + +fn performance(velocity: f32) -> Option { + if !velocity.is_finite() { + return None; + } + Some(NotePerformance { + velocity: (velocity.clamp(0.0, 1.0) * 127.0).round().clamp(1.0, 127.0) as u8, + }) +} + +fn median_midi(notes: &[PitchedNote]) -> u8 { + let mut values = notes.iter().map(|note| note.midi).collect::>(); + values.sort_unstable(); + values.get(values.len() / 2).copied().unwrap_or(60) +} + +fn tab_position(midi: u8, tuning: &[u8]) -> Option { + tuning + .iter() + .copied() + .enumerate() + .filter(|(_, open)| midi >= *open) + .map(|(index, open)| { + let string = tuning.len() - index; + (u16::from(midi - open), string as u16) + }) + .min() + .map(|(fret, string)| TabPosition { string, fret, bend: Alter::NATURAL }) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::ScoreDocument; + + fn rhythmic(score: &Score) -> Vec<&TimedEvent> { + score + .voices + .values() + .flat_map(|voice| voice.events.iter()) + .filter(|event| event.duration.is_some()) + .collect() + } + + fn assert_bar_exact(score: &Score) { + assert!(score.validate().is_empty(), "{:#?}", score.validate()); + for measure in score.measures.values() { + let end = measure.start.checked_add(measure.extent).unwrap(); + let events = rhythmic(score) + .into_iter() + .filter(|event| event.onset >= measure.start && event.onset < end) + .collect::>(); + assert_eq!(events.first().unwrap().onset, measure.start); + let mut cursor = measure.start; + for event in events { + assert_eq!(event.onset, cursor); + cursor = event.end().unwrap(); + } + assert_eq!(cursor, end); + } + } + + #[test] + fn gm_numbers_match_the_drum_map() { + let got = DrumVoice::ALL.map(DrumVoice::gm_note); + assert_eq!(got, [36, 38, 37, 42, 46, 44, 50, 48, 45, 41, 51, 53, 49]); + } + + #[test] + fn drum_hits_quantize_chord_and_fill_rests() { + let opts = BuildOptions::default(); + let score = build_drum_score(&[ + DrumHit { time_beats: 0.02, voice: DrumVoice::Kick, velocity: 1.0 }, + DrumHit { time_beats: 0.03, voice: DrumVoice::HiHatClosed, velocity: 0.7 }, + DrumHit { time_beats: 0.20, voice: DrumVoice::Ride, velocity: 0.6 }, + DrumHit { time_beats: 2.0, voice: DrumVoice::Snare, velocity: 0.8 }, + ], &opts); + assert_bar_exact(&score); + let events = rhythmic(&score); + assert!(matches!(&events[0].kind, EventKind::Chord(notes) if notes.len() == 2)); + assert!(events.iter().any(|event| matches!(event.kind, EventKind::Rest))); + assert_eq!(events[0].onset, ScoreTime::ZERO); + assert!(events + .iter() + .any(|event| event.onset == ScoreTime::new(1, 16).unwrap())); + } + + #[test] + fn pitched_notes_split_and_tie_at_beats_and_bars() { + let opts = BuildOptions { bars: 2, ..BuildOptions::default() }; + let score = build_pitched_score(&[ + PitchedNote { onset_beats: 3.5, duration_beats: 1.5, midi: 64, velocity: 0.8 }, + ], &opts); + assert_bar_exact(&score); + let chain = rhythmic(&score) + .into_iter() + .filter_map(|event| match &event.kind { EventKind::Chord(notes) => Some(¬es[0]), _ => None }) + .collect::>(); + assert!(chain.len() >= 2); + assert_eq!(chain[0].tie_to, Some(chain[1].id)); + assert_eq!(chain[1].tie_from, Some(chain[0].id)); + } + + #[test] + fn later_pitched_onset_wins_an_overlap() { + let score = build_pitched_score(&[ + PitchedNote { onset_beats: 0.0, duration_beats: 3.0, midi: 60, velocity: 0.5 }, + PitchedNote { onset_beats: 1.0, duration_beats: 1.0, midi: 62, velocity: 0.5 }, + ], &BuildOptions::default()); + assert_bar_exact(&score); + let at_one = rhythmic(&score).into_iter().find(|event| event.onset == ScoreTime::new(1, 4).unwrap()).unwrap(); + assert!(matches!(&at_one.kind, EventKind::Chord(notes) if notes[0].written_pitch == Some(pitch_from_midi(62)))); + } + + fn lyric_note_onset(score: &Score, lyric: &LyricSyllable) -> f64 { + score + .voices + .values() + .flat_map(|voice| &voice.events) + .find(|event| event.chord_notes().iter().any(|note| note.id == lyric.note)) + .map(|event| { + event.onset.0.numerator() as f64 / event.onset.0.denominator() as f64 * 4.0 + }) + .expect("lyric note belongs to an event") + } + + fn lyric_notes() -> [PitchedNote; 3] { + [ + PitchedNote { onset_beats: 0.0, duration_beats: 0.5, midi: 60, velocity: 0.8 }, + PitchedNote { onset_beats: 1.0, duration_beats: 0.5, midi: 62, velocity: 0.8 }, + PitchedNote { onset_beats: 2.0, duration_beats: 0.5, midi: 64, velocity: 0.8 }, + ] + } + + #[test] + fn lyrics_match_exact_note_onsets() { + let score = build_pitched_score_with_lyrics( + &lyric_notes(), + &[ + LyricWord { onset_beats: 0.0, end_beats: 0.5, text: "sing".into() }, + LyricWord { onset_beats: 2.0, end_beats: 2.5, text: "now".into() }, + ], + &BuildOptions::default(), + ); + assert_eq!(score.lyrics.len(), 2); + assert_eq!(score.lyrics[0].text, "sing"); + assert_eq!(lyric_note_onset(&score, &score.lyrics[0]), 0.0); + assert_eq!(score.lyrics[1].text, "now"); + assert_eq!(lyric_note_onset(&score, &score.lyrics[1]), 2.0); + } + + #[test] + fn lyrics_choose_the_nearest_note_within_tolerance() { + let score = build_pitched_score_with_lyrics( + &lyric_notes(), + &[LyricWord { onset_beats: 0.8, end_beats: 1.2, text: "near".into() }], + &BuildOptions::default(), + ); + assert_eq!(score.lyrics.len(), 1); + assert_eq!(lyric_note_onset(&score, &score.lyrics[0]), 1.0); + } + + #[test] + fn words_on_one_note_are_joined() { + let score = build_pitched_score_with_lyrics( + &lyric_notes(), + &[ + LyricWord { onset_beats: 0.0, end_beats: 0.1, text: "come".into() }, + LyricWord { onset_beats: 0.1, end_beats: 0.2, text: "on".into() }, + ], + &BuildOptions::default(), + ); + assert_eq!(score.lyrics.len(), 1); + assert_eq!(score.lyrics[0].text, "come on"); + } + + #[test] + fn a_word_held_over_later_notes_gets_a_melisma() { + let score = build_pitched_score_with_lyrics( + &lyric_notes(), + &[LyricWord { onset_beats: 0.0, end_beats: 1.2, text: "sing".into() }], + &BuildOptions::default(), + ); + assert_eq!(score.lyrics.len(), 1); + let second = score + .voices + .values() + .flat_map(|voice| &voice.events) + .find(|event| event.onset == ScoreTime::new(1, 4).unwrap()) + .and_then(|event| event.chord_notes().first()) + .expect("second note"); + assert_eq!(score.lyrics[0].melisma_to, Some(second.id)); + } + + #[test] + fn no_words_make_no_lyrics() { + let score = build_pitched_score_with_lyrics( + &lyric_notes(), + &[], + &BuildOptions::default(), + ); + assert!(score.lyrics.is_empty()); + } + + #[test] + fn words_outside_the_loop_are_ignored() { + let score = build_pitched_score_with_lyrics( + &lyric_notes(), + &[ + LyricWord { onset_beats: -0.1, end_beats: 0.1, text: "before".into() }, + LyricWord { onset_beats: 4.0, end_beats: 4.2, text: "after".into() }, + ], + &BuildOptions::default(), + ); + assert!(score.lyrics.is_empty()); + } + + #[test] + fn bass_tab_chooses_the_lowest_fret() { + let score = build_bass_tab_score(&[ + PitchedNote { onset_beats: 0.0, duration_beats: 1.0, midi: 43, velocity: 0.8 }, + ], &[28, 33, 38, 43], &BuildOptions::default()); + assert_bar_exact(&score); + let tab = rhythmic(&score).into_iter().find_map(|event| event.chord_notes().first()?.tab).unwrap(); + assert_eq!((tab.string, tab.fret), (1, 0)); + } + + #[test] + fn every_builder_engraves_headlessly_with_fallback_outlines() { + let opts = BuildOptions::default(); + let pitched = [PitchedNote { onset_beats: 0.0, duration_beats: 1.0, midi: 60, velocity: 0.8 }]; + let scores = [ + build_drum_score(&[DrumHit { time_beats: 0.0, voice: DrumVoice::Kick, velocity: 1.0 }], &opts), + build_pitched_score(&pitched, &opts), + build_bass_tab_score(&pitched, &[28, 33, 38, 43], &opts), + ]; + for score in scores { + let document = ScoreDocument::new(score).unwrap(); + assert!(!document.pages().is_empty()); + assert!(!document.pages()[0].items().is_empty()); + } + } +} diff --git a/libs/score_view/src/document.rs b/libs/score_view/src/document.rs new file mode 100644 index 000000000..1551a823e --- /dev/null +++ b/libs/score_view/src/document.rs @@ -0,0 +1,565 @@ +//! Playback-free score document and retained engraving pages. + +use crate::spacing::ScoreSpacing; +use makepad_score::model::*; +use makepad_score_render::{PageCache, PaintList, Point, Rect, SemanticId}; +use std::{collections::BTreeMap, sync::Arc}; + +pub const PAGE_WIDTH_SP: f64 = 168.0; +pub const PAGE_HEIGHT_SP: f64 = 238.0; + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct DocumentOptions { + pub hide_labels: bool, + pub drum_key: bool, + pub page_size: Point, +} + +impl Default for DocumentOptions { + fn default() -> Self { + Self { + hide_labels: false, + drum_key: false, + page_size: Point::new(PAGE_WIDTH_SP, PAGE_HEIGHT_SP), + } + } +} + +impl DocumentOptions { + pub fn content(score: &Score, hide_labels: bool) -> Self { + let measure_ratio = score.measures.len() as f64 / 8.0; + Self { + hide_labels, + drum_key: true, + page_size: Point::new( + PAGE_WIDTH_SP * measure_ratio.clamp(0.5, 1.0), + PAGE_HEIGHT_SP, + ), + } + } +} + +const ACTOR: u64 = 0x5c0e; +const NOTE_SEMANTIC_TAG: u64 = 0x1000_0000_0000_0000; +const MEASURE_SEMANTIC_TAG: u64 = 0x2000_0000_0000_0000; +pub(crate) const DECORATION_TAG: u64 = 0x8000_0000_0000_0000; + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum SemanticKind { + Note, + Measure, +} + +#[derive(Clone, Debug)] +pub struct SemanticElement { + pub semantic: SemanticId, + pub kind: SemanticKind, + pub note: Option, + pub event: Option, + pub measure: MeasureId, + pub staff: StaffId, + pub voice: VoiceId, + pub page: usize, + pub bounds: Rect, + pub midi: Option, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum DocumentError { + Native(String), +} + +impl std::fmt::Display for DocumentError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Native(message) => f.write_str(message), + } + } +} + +impl std::error::Error for DocumentError {} + +/// A score plus its retained, playback-free engraving pages. +pub struct ScoreDocument { + score: Score, + options: DocumentOptions, + pages: Vec>, + cache: PageCache, + elements: BTreeMap, + spacing: ScoreSpacing, + frame: u64, +} + +impl Default for ScoreDocument { + fn default() -> Self { + Self { + score: Score::new([0; 16]), + options: DocumentOptions::default(), + pages: Vec::new(), + cache: PageCache::new(32 * 1024 * 1024), + elements: BTreeMap::new(), + spacing: ScoreSpacing::new(), + frame: 1, + } + } +} + +impl ScoreDocument { + pub fn demo() -> Result { + Self::new(demo_score(8)?) + } + + pub fn new(score: Score) -> Result { + Self::with_options(score, DocumentOptions::default()) + } + + pub fn with_options( + score: Score, + options: DocumentOptions, + ) -> Result { + let mut document = Self::default(); + document.set_score_with_options(score, options)?; + Ok(document) + } + + pub fn set_score(&mut self, score: Score) -> Result<(), DocumentError> { + self.set_score_with_options(score, self.options) + } + + pub fn set_score_with_options( + &mut self, + score: Score, + options: DocumentOptions, + ) -> Result<(), DocumentError> { + self.score = score; + self.options = options; + self.rebuild() + } + + pub fn set_options(&mut self, options: DocumentOptions) -> Result<(), DocumentError> { + if self.options == options { + return Ok(()); + } + self.options = options; + self.rebuild() + } + + pub fn clear(&mut self) { + self.score = Score::new([0; 16]); + self.pages.clear(); + self.cache = PageCache::new(32 * 1024 * 1024); + self.elements.clear(); + self.spacing = ScoreSpacing::new(); + self.spacing.set_page_width(self.options.page_size.x); + } + + pub fn score(&self) -> &Score { + &self.score + } + + pub fn pages(&self) -> &[Arc] { + &self.pages + } + + pub fn options(&self) -> DocumentOptions { + self.options + } + + pub fn content_bounds(&self, page: usize) -> Option { + let bounds = self.pages.get(page)?.items().iter().fold(Rect::EMPTY, |bounds, item| { + bounds.union(item.bounds) + }); + (!bounds.is_empty()).then_some(bounds) + } + + pub fn first_system_bounds(&self, page: usize) -> Option { + let placement = self.spacing.pages().get(page)?; + let system = placement.systems.first()?; + let min_y = system.top - 14.0; + let max_y = placement + .systems + .get(1) + .map_or(system.bottom + 14.0, |next| (system.bottom + next.top) * 0.5); + let bounds = self.pages.get(page)?.items().iter().fold(Rect::EMPTY, |bounds, item| { + if item.bounds.max.y >= min_y && item.bounds.min.y <= max_y { + bounds.union(item.bounds) + } else { + bounds + } + }); + (!bounds.is_empty()).then_some(bounds) + } + + pub fn page_count(&self) -> usize { + self.pages.len() + } + + pub fn system_count(&self, page: usize) -> usize { + self.spacing.pages().get(page).map_or(0, |page| page.systems.len()) + } + + pub fn spacing(&self) -> &ScoreSpacing { + &self.spacing + } + + pub fn element(&self, semantic: SemanticId) -> Option<&SemanticElement> { + self.elements.get(&semantic) + } + + pub fn rebuild(&mut self) -> Result<(), DocumentError> { + self.spacing.set_page_width(self.options.page_size.x); + self.spacing.set_drum_key(self.options.drum_key); + self.spacing.rebuild(&self.score); + self.pages.clear(); + self.elements.clear(); + for page_index in 0..self.spacing.page_count() { + let placement = &self.spacing.pages()[page_index]; + let (list, elements) = crate::engrave::make_page_with_options( + &self.score, + placement, + page_index, + self.frame, + self.options, + )?; + let list = Arc::new(list); + self.cache.insert(list.clone(), self.frame); + self.pages.push(list); + self.elements + .extend(elements.into_iter().map(|element| (element.semantic, element))); + self.frame = self.frame.saturating_add(1); + } + Ok(()) + } +} + +pub fn semantic_for_note(id: NoteId) -> SemanticId { + let (actor, counter) = id.raw(); + SemanticId(NOTE_SEMANTIC_TAG | actor.rotate_left(17) ^ counter) +} + +pub fn semantic_for_measure(id: MeasureId) -> SemanticId { + let (actor, counter) = id.raw(); + SemanticId(MEASURE_SEMANTIC_TAG | actor.rotate_left(11) ^ counter) +} + +pub fn pitch_to_midi(pitch: Pitch) -> u8 { + let natural = match pitch.step { + Step::C => 0, + Step::D => 2, + Step::E => 4, + Step::F => 5, + Step::G => 7, + Step::A => 9, + Step::B => 11, + }; + let alter = pitch.alter.0.numerator() as f64 / pitch.alter.0.denominator() as f64; + ((i16::from(pitch.octave) + 1) * 12 + natural + alter.round() as i16).clamp(0, 127) as u8 +} + +pub fn pitch_from_midi(midi: u8) -> Pitch { + let octave = (midi / 12) as i8 - 1; + let (step, alter) = match midi % 12 { + 0 => (Step::C, 0), + 1 => (Step::C, 1), + 2 => (Step::D, 0), + 3 => (Step::D, 1), + 4 => (Step::E, 0), + 5 => (Step::F, 0), + 6 => (Step::F, 1), + 7 => (Step::G, 0), + 8 => (Step::G, 1), + 9 => (Step::A, 0), + 10 => (Step::A, 1), + _ => (Step::B, 0), + }; + Pitch::new(step, Alter::new(alter, 1).unwrap_or(Alter::NATURAL), octave) +} + +/// Build the small two-staff fixture used by examples and tests. +pub fn demo_score(measure_count: usize) -> Result { + let mut ids = IdGenerator::new(ACTOR); + let part = ids.next::().map_err(id_error)?; + let upper = ids.next::().map_err(id_error)?; + let lower = ids.next::().map_err(id_error)?; + let upper_voice = ids.next::().map_err(id_error)?; + let lower_voice = ids.next::().map_err(id_error)?; + let mut score = Score::new(*b"SCOREVIEWDEMO000"); + score.title = "Demo score".into(); + score.parts.insert(part, Part { + id: part, + name: "Keyboard".into(), + staves: vec![upper, lower], + transposition: Transposition::NONE, + }); + score.staves.insert(upper, Staff { + id: upper, part, parent: None, kind: StaffKind::Standard, voices: vec![upper_voice], + }); + score.staves.insert(lower, Staff { + id: lower, part, parent: Some(upper), kind: StaffKind::Standard, voices: vec![lower_voice], + }); + let mut upper_events = Vec::new(); + let mut lower_events = Vec::new(); + for bar in 0..measure_count.max(1) { + let measure = ids.next::().map_err(id_error)?; + let start = ScoreTime::new(bar as i64, 1).map_err(native_error)?; + let extent = Duration::new(1, 1).map_err(native_error)?; + score.measures.insert(measure, Measure { + id: measure, ordinal: bar as u32, label: (bar + 1).to_string(), start, extent, + }); + score.flow.nodes.push(FlowNode { measure, ordinal: bar as u32 }); + for beat in 0..4 { + let onset = start + .checked_add_time(ScoreTime::new(beat, 4).map_err(native_error)?) + .map_err(native_error)?; + upper_events.push(note_event( + ids.next::().map_err(id_error)?, + ids.next::().map_err(id_error)?, + upper, + onset, + Duration::new(1, 4).map_err(native_error)?, + pitch_from_midi(60 + ((bar * 4 + beat as usize) % 8) as u8), + )); + } + lower_events.push(note_event( + ids.next::().map_err(id_error)?, + ids.next::().map_err(id_error)?, + lower, + start, + extent, + pitch_from_midi(40 + (bar % 5) as u8), + )); + } + score.voices.insert(upper_voice, Voice { id: upper_voice, staff: upper, number: 1, events: upper_events }); + score.voices.insert(lower_voice, Voice { id: lower_voice, staff: lower, number: 1, events: lower_events }); + score.maps.time_signature.push(Change { + at: ScoreTime::ZERO, + scope: MapScope::Global, + value: Meter::Measured { groups: vec![4], unit: 4 }, + }); + Ok(score) +} + +fn id_error(_: IdError) -> DocumentError { + DocumentError::Native("score id space exhausted".into()) +} + +fn native_error(error: impl std::fmt::Display) -> DocumentError { + DocumentError::Native(error.to_string()) +} + +pub fn note_event( + event: EventId, + note: NoteId, + staff: StaffId, + onset: ScoreTime, + duration: Duration, + pitch: Pitch, +) -> TimedEvent { + TimedEvent { + id: event, + onset, + duration: Some(duration), + grace: None, + kind: EventKind::Chord(vec![Note { + id: note, + performance: None, + written_pitch: Some(pitch), + unpitched_sound: None, + display_staff: staff, + tie_from: None, + tie_to: None, + tab: None, + notehead: Notehead::Normal, + }]), + beams: Vec::new(), + tuplets: Vec::new(), + articulations: Vec::new(), + ornaments: Vec::new(), + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + build_drum_score, build_pitched_score, BuildOptions, DrumHit, DrumVoice, PitchedNote, + }; + use makepad_score_render::{PaintKind, Primitive, RuleKind}; + + fn drum_document(hide_labels: bool) -> ScoreDocument { + crate::font::ensure_default_font(); + let hits = [ + DrumHit { time_beats: 0.0, voice: DrumVoice::HiHatClosed, velocity: 1.0 }, + DrumHit { time_beats: 1.0, voice: DrumVoice::HiHatClosed, velocity: 1.0 }, + DrumHit { time_beats: 2.0, voice: DrumVoice::HiHatClosed, velocity: 1.0 }, + DrumHit { time_beats: 3.0, voice: DrumVoice::HiHatClosed, velocity: 1.0 }, + ]; + let score = build_drum_score(&hits, &BuildOptions::default()); + let options = DocumentOptions::content(&score, hide_labels); + ScoreDocument::with_options(score, options).expect("the drum fixture engraves") + } + + fn text_items(document: &ScoreDocument) -> Vec<&makepad_score_render::PaintItem> { + document.pages()[0] + .items() + .iter() + .filter(|item| matches!(item.kind, PaintKind::Text(_))) + .collect() + } + + #[test] + fn compact_drum_content_is_smaller_than_its_page() { + let document = drum_document(true); + let page = &document.pages()[0]; + let bounds = document.content_bounds(0).expect("engraved content has bounds"); + assert!(bounds.width() > 0.0 && bounds.height() > 0.0); + assert!(bounds.width() < page.page_size().x); + assert!(bounds.height() < page.page_size().y); + assert_eq!(page.page_size().x, PAGE_WIDTH_SP * 0.5); + } + + #[test] + fn hide_labels_does_not_remove_the_drum_key() { + let visible = drum_document(false); + assert!(text_items(&visible).len() > 1); + + let hidden = drum_document(true); + let texts: Vec<&str> = text_items(&hidden) + .into_iter() + .filter_map(|item| match &item.kind { + PaintKind::Text(run) => Some(run.text.as_ref()), + _ => None, + }) + .collect(); + assert_eq!(texts, vec!["HH"]); + } + + #[test] + fn adjacent_drum_voices_share_one_key_line() { + crate::font::ensure_default_font(); + let score = build_drum_score( + &[ + DrumHit { time_beats: 0.0, voice: DrumVoice::HiHatClosed, velocity: 1.0 }, + DrumHit { time_beats: 1.0, voice: DrumVoice::Crash, velocity: 1.0 }, + ], + &BuildOptions::default(), + ); + let options = DocumentOptions::content(&score, true); + let document = ScoreDocument::with_options(score, options).expect("drum fixture engraves"); + let texts: Vec<&str> = text_items(&document) + .into_iter() + .filter_map(|item| match &item.kind { + PaintKind::Text(run) => Some(run.text.as_ref()), + _ => None, + }) + .collect(); + assert_eq!(texts, vec!["Crash / HH"]); + } + + #[test] + fn content_drum_key_contains_only_used_voices_at_their_display_pitches() { + crate::font::ensure_default_font(); + let score = build_drum_score( + &[ + DrumHit { time_beats: 0.0, voice: DrumVoice::Kick, velocity: 1.0 }, + DrumHit { time_beats: 1.0, voice: DrumVoice::Snare, velocity: 1.0 }, + DrumHit { time_beats: 2.0, voice: DrumVoice::HiHatClosed, velocity: 1.0 }, + ], + &BuildOptions::default(), + ); + let options = DocumentOptions::content(&score, true); + let without_key = ScoreDocument::with_options( + score.clone(), + DocumentOptions { drum_key: false, ..options }, + ) + .expect("the unlabelled drum fixture engraves"); + let document = ScoreDocument::with_options(score, options) + .expect("the labelled drum fixture engraves"); + let reserved = document.spacing().pages()[0].systems[0].music_left + - without_key.spacing().pages()[0].systems[0].music_left; + assert!((reserved - crate::engrave::drum_key_width(document.score())).abs() < 1e-9); + let system_top = document.spacing().pages()[0].systems[0].top; + let staff = crate::engrave::score_staff_frames(document.score(), system_top)[0]; + let mut labels: Vec<(&str, f64, f64)> = text_items(&document) + .into_iter() + .filter_map(|item| match &item.kind { + PaintKind::Text(run) => Some((run.text.as_ref(), item.bounds.center().y, item.bounds.max.x)), + _ => None, + }) + .collect(); + labels.sort_by_key(|(label, _, _)| *label); + assert_eq!(labels.iter().map(|(label, _, _)| *label).collect::>(), vec!["HH", "Kick", "Snare"]); + + let clef_x = document.pages()[0] + .items() + .iter() + .find_map(|item| match &item.kind { + PaintKind::Glyph(glyph) if glyph.glyph.0.as_ref() == "unpitchedPercussionClef1" => { + Some(glyph.origin.x) + } + _ => None, + }) + .expect("percussion clef"); + for (label, center_y, right) in labels { + let voice = match label { + "Kick" => DrumVoice::Kick, + "Snare" => DrumVoice::Snare, + "HH" => DrumVoice::HiHatClosed, + _ => unreachable!(), + }; + let (display, _) = voice.display(); + let diatonic = i32::from(display.octave) * 7 + i32::from(display.step.index()); + assert!((center_y - staff.y_of(diatonic)).abs() < 1e-9); + assert!(right < clef_x, "{label} must sit left of the clef"); + } + } + + #[test] + fn pitched_content_score_has_no_drum_key() { + crate::font::ensure_default_font(); + let score = build_pitched_score( + &[PitchedNote { + onset_beats: 0.0, + duration_beats: 1.0, + midi: 60, + velocity: 1.0, + }], + &BuildOptions::default(), + ); + let options = DocumentOptions::content(&score, true); + let document = ScoreDocument::with_options(score, options).expect("pitched fixture engraves"); + assert!(text_items(&document).is_empty()); + } + + #[test] + fn drum_page_retains_percussion_clef_staff_and_x_heads() { + let document = drum_document(true); + let items = document.pages()[0].items(); + let glyphs: Vec<&str> = items + .iter() + .filter_map(|item| match &item.kind { + PaintKind::Glyph(glyph) => Some(glyph.glyph.0.as_ref()), + _ => None, + }) + .collect(); + assert!(glyphs.contains(&"unpitchedPercussionClef1")); + assert!( + glyphs.iter().filter(|name| **name == "noteheadXBlack").count() >= 4, + "expected the four hi-hat X noteheads, got {glyphs:?}" + ); + let staff_lines = items + .iter() + .filter(|item| { + matches!( + item.kind, + PaintKind::Primitive(Primitive::Rule { + kind: RuleKind::Staff, + staff_group: Some(_), + .. + }) + ) + }) + .count(); + assert_eq!(staff_lines, 5); + } +} diff --git a/libs/score_view/src/engrave.rs b/libs/score_view/src/engrave.rs new file mode 100644 index 000000000..2dd89db94 --- /dev/null +++ b/libs/score_view/src/engrave.rs @@ -0,0 +1,2170 @@ +//! Page engraving: turns the semantic score into one retained paint page. +//! +//! Everything here is in staff spaces, page-local, y down. The vertical +//! placement of a note is diatonic — a staff step is half a staff space — and +//! all glyph metrics (notehead width, stem attachment, ledger extension, beam +//! thickness) come from the loaded SMuFL font rather than from constants. + +use crate::document::{ + pitch_to_midi, semantic_for_measure, semantic_for_note, DocumentError, DocumentOptions, + SemanticElement, SemanticKind, DECORATION_TAG, +}; +use crate::font::{music_font, Engraving, MusicFont}; +use crate::spacing::{MeasurePlacement, PagePlacement, SystemPlacement}; +use makepad_score::{ + model::{ + EventKind, KeySignature, Measure, Meter, Notehead, Pitch, Rational, Score, + ScoreTime, StaffId, StaffKind, SyllabicRole, TimedEvent, VoiceId, + }, + symbol::{ + Accidental, Clef, Direction, FlagDuration, NoteheadDuration, NoteheadShape, + Placement, Symbol, + }, +}; +use makepad_score_layout::LayoutStyle; +use makepad_score_render::{ + Beam, GlyphItem, Ink, InkRole, LineKind, LinearRgba, MusicFontRef, PageId, PaintItem, + PaintKind, PaintList, Point, Primitive, Rect, RuleKind, SemanticId, SmuflGlyph, + TextDirection, TextFontRef, TextRun, +}; +use std::{collections::BTreeSet, sync::Arc}; + +/// One em is four staff spaces in every SMuFL font. +const EM_SIZE: f64 = 4.0; +/// Distance from the top staff line of the upper staff to that of the lower. +const STAFF_GAP: f64 = 14.0; +/// Top staff line of the upper staff to bottom staff line of the lower. +pub(crate) const STAFF_SPAN: f64 = STAFF_GAP + 4.0; +pub const MARGIN_LEFT: f64 = 17.0; +pub const MARGIN_RIGHT: f64 = 14.0; +/// Shortest stem, in staff spaces, measured from the notehead centre. +const STEM_LENGTH: f64 = 3.5; +const BEAM_MIN_STEM: f64 = 3.0; +const DRUM_KEY_TEXT_SIZE: f64 = 1.4; +const DRUM_KEY_COLUMN_PAD: f64 = 1.5; +const DRUM_KEY_LEADER: f64 = 0.6; +const DRUM_KEY_COLLISION: f64 = 1.2; + +/// A five-line staff placed on the page, with its clef. +#[derive(Clone, Copy, Debug)] +pub(crate) struct StaffFrame { + /// Page y of the top staff line. + pub(crate) top: f64, + clef: &'static str, + /// Page y of the line the clef's origin sits on. + clef_line: f64, + /// Diatonic index (octave * 7 + step) of the pitch on the middle line. + pub(crate) middle_diatonic: i32, + /// Staff steps to shift a key signature by, relative to a treble staff. + key_shift: i8, +} + +/// The grand staff of one system, given the page y of its top staff line. +pub(crate) fn staff_frames(top: f64) -> [StaffFrame; 2] { + [StaffFrame::treble(top), StaffFrame::bass(top + STAFF_GAP)] +} + +pub(crate) fn score_staff_frames(score: &Score, top: f64) -> Vec { + let Some(part) = score.parts.values().next() else { + return staff_frames(top).into(); + }; + if part.staves.is_empty() { + return staff_frames(top).into(); + } + part.staves + .iter() + .enumerate() + .map(|(index, staff_id)| { + let fallback = if index == 0 { (Clef::G, 2) } else { (Clef::F, 4) }; + let (clef, line) = score + .voices + .values() + .filter(|voice| voice.staff == *staff_id) + .flat_map(|voice| &voice.events) + .find_map(|event| match event.kind { + EventKind::Clef(change) => Some((change.clef, change.line)), + _ => None, + }) + .unwrap_or(fallback); + StaffFrame::for_clef(top + index as f64 * STAFF_GAP, clef, line) + }) + .collect() +} + +pub(crate) fn score_staff_span(score: &Score) -> f64 { + let frames = score_staff_frames(score, 0.0); + frames.last().map_or(STAFF_SPAN, |staff| staff.bottom()) +} + +impl StaffFrame { + fn treble(top: f64) -> Self { + Self { + top, + clef: "gClef", + clef_line: top + 3.0, + // B4 sits on the middle line of a treble staff. + middle_diatonic: 4 * 7 + 6, + key_shift: 0, + } + } + + fn bass(top: f64) -> Self { + Self { + top, + clef: "fClef", + clef_line: top + 1.0, + // D3 sits on the middle line of a bass staff. + middle_diatonic: 3 * 7 + 1, + key_shift: -2, + } + } + + fn for_clef(top: f64, clef: Clef, line: u8) -> Self { + let (middle_diatonic, key_shift) = match clef { + Clef::F | Clef::F8va | Clef::F8vb | Clef::F15ma | Clef::F15mb => { + (3 * 7 + 1, -2) + } + _ => (4 * 7 + 6, 0), + }; + Self { + top, + clef: clef_name(clef), + clef_line: top + f64::from(5_u8.saturating_sub(line.clamp(1, 5))), + middle_diatonic, + key_shift, + } + } + + fn middle(self) -> f64 { + self.top + 2.0 + } + + pub(crate) fn bottom(self) -> f64 { + self.top + 4.0 + } + + /// Page y of a diatonic pitch position on this staff. + pub(crate) fn y_of(self, diatonic: i32) -> f64 { + self.middle() - f64::from(diatonic - self.middle_diatonic) * 0.5 + } +} + +#[derive(Clone, Debug)] +struct DrumKeyRow { + label: String, + diatonic: f64, +} + +pub(crate) fn drum_key_width(score: &Score) -> f64 { + drum_key_rows_width(&drum_key_rows(score)) +} + +fn drum_key_rows_width(rows: &[DrumKeyRow]) -> f64 { + rows + .iter() + .map(|row| crate::title::text_width_sp(&row.label, DRUM_KEY_TEXT_SIZE)) + .reduce(f64::max) + .map_or(0.0, |width| width + DRUM_KEY_COLUMN_PAD) +} + +fn drum_key_rows(score: &Score) -> Vec { + let Some(staff_id) = score.parts.values().next().and_then(|part| part.staves.first()) else { + return Vec::new(); + }; + let Some(staff) = score.staves.get(staff_id) else { + return Vec::new(); + }; + let StaffKind::Percussion(map) = &staff.kind else { + return Vec::new(); + }; + let used: BTreeSet = score + .voices + .values() + .filter(|voice| voice.staff == *staff_id) + .flat_map(|voice| &voice.events) + .flat_map(|event| match &event.kind { + EventKind::Chord(notes) => notes.as_slice(), + _ => &[], + }) + .filter_map(|note| note.unpitched_sound) + .collect(); + + let mut sounds: Vec<(String, i32)> = map + .entries + .iter() + .filter(|(sound_id, _)| used.contains(sound_id)) + .map(|(_, sound)| { + let label = crate::build::DrumVoice::ALL + .into_iter() + .find(|voice| voice.gm_note() == sound.midi_note) + .map(|voice| voice.short_label().to_string()) + .unwrap_or_else(|| sound.name.trim().chars().take(8).collect()); + (label, diatonic_index(sound.display)) + }) + .collect(); + sounds.sort_by(|left, right| right.1.cmp(&left.1).then_with(|| left.0.cmp(&right.0))); + + struct Group { + labels: Vec, + top_diatonic: i32, + diatonic_sum: i32, + } + let mut groups: Vec = Vec::new(); + for (label, diatonic) in sounds { + if let Some(group) = groups.last_mut() { + let separation = f64::from(group.top_diatonic - diatonic) * 0.5; + if separation < DRUM_KEY_COLLISION { + group.labels.push(label); + group.diatonic_sum += diatonic; + continue; + } + } + groups.push(Group { + labels: vec![label], + top_diatonic: diatonic, + diatonic_sum: diatonic, + }); + } + groups + .into_iter() + .map(|group| DrumKeyRow { + diatonic: f64::from(group.diatonic_sum) / group.labels.len() as f64, + label: group.labels.join(" / "), + }) + .collect() +} + +fn clef_name(clef: Clef) -> &'static str { + match clef { + Clef::G => "gClef", + Clef::G8va => "gClef8va", + Clef::G8vb => "gClef8vb", + Clef::G15ma => "gClef15ma", + Clef::G15mb => "gClef15mb", + Clef::F => "fClef", + Clef::F8va => "fClef8va", + Clef::F8vb => "fClef8vb", + Clef::F15ma => "fClef15ma", + Clef::F15mb => "fClef15mb", + Clef::C => "cClef", + Clef::Percussion => "unpitchedPercussionClef1", + Clef::PercussionAlternate => "unpitchedPercussionClef2", + Clef::Tab4String => "4stringTabClef", + Clef::Tab6String => "6stringTabClef", + } +} + +/// The written form of one duration. +#[derive(Clone, Copy, Debug, PartialEq)] +pub(crate) struct NoteValue { + /// 0 = whole, 1 = half, 2 = quarter, 3 = eighth, ... + power: u8, + pub(crate) dots: u8, +} + +impl NoteValue { + fn flags(self) -> u8 { + self.power.saturating_sub(2) + } + + fn notehead(self, notehead: &Notehead) -> Symbol { + let duration = match self.power { + 0 => NoteheadDuration::Whole, + 1 => NoteheadDuration::Half, + _ => NoteheadDuration::Black, + }; + let shape = match notehead { + Notehead::X => NoteheadShape::X, + Notehead::Diamond => NoteheadShape::Diamond, + Notehead::Triangle => NoteheadShape::TriangleUp, + Notehead::Slash => NoteheadShape::Slash, + _ => NoteheadShape::Normal, + }; + Symbol::Notehead { duration, shape } + } + + fn has_stem(self) -> bool { + self.power >= 1 + } +} + +/// One notehead inside a chord column. +#[derive(Clone, Debug)] +pub(crate) struct HeadLayout { + pub(crate) note: makepad_score::model::NoteId, + midi: u8, + diatonic: i32, + y: f64, + pub(crate) glyph: String, + pub(crate) accidental: Option, + /// Seconds are offset to the far side of the stem. + pub(crate) shifted: bool, +} + +/// One rhythmic column: a chord (or single note) of one voice. +#[derive(Clone, Debug)] +pub(crate) struct Column { + event: makepad_score::model::EventId, + measure: makepad_score::model::MeasureId, + voice: VoiceId, + staff: StaffId, + /// Onset in whole notes from the start of the score. + onset: f64, + /// The same onset, exactly: the key columns are merged on. + pub(crate) time: ScoreTime, + /// Page x of the unshifted notehead's left edge, filled in from the + /// spacing plan once the system's springs are solved. + x: f64, + pub(crate) heads: Vec, + pub(crate) value: NoteValue, + pub(crate) stem_up: bool, + articulations: Vec, +} + +impl Column { + pub(crate) fn top_y(&self) -> f64 { + self.heads + .iter() + .map(|head| head.y) + .fold(f64::INFINITY, f64::min) + } + + pub(crate) fn bottom_y(&self) -> f64 { + self.heads + .iter() + .map(|head| head.y) + .fold(f64::NEG_INFINITY, f64::max) + } + + /// The notehead the stem starts from. + fn stem_origin_y(&self) -> f64 { + if self.stem_up { + self.bottom_y() + } else { + self.top_y() + } + } + + /// The notehead the stem has to clear. + fn stem_far_y(&self) -> f64 { + if self.stem_up { + self.top_y() + } else { + self.bottom_y() + } + } +} + +/// Accumulates paint items and hands out decoration IDs. +struct PageBuilder<'a> { + font: &'static MusicFont, + engraving: Engraving, + items: Vec, + elements: Vec, + decoration: u64, + page_index: usize, + score: &'a Score, + hide_labels: bool, +} + +impl PageBuilder<'_> { + fn next_decor(&mut self) -> SemanticId { + self.decoration = self.decoration.saturating_add(1); + SemanticId(self.decoration) + } + + fn glyph(&mut self, id: SemanticId, name: &str, origin: Point, ink: Ink, z: i16) -> bool { + if !self.font.has(name) { + return false; + } + let bbox = self.font.bbox(name); + // The font box is y-up around the origin; the page is y-down. + let bounds = Rect::new( + Point::new(origin.x + bbox.min_x, origin.y - bbox.max_y), + Point::new(origin.x + bbox.max_x, origin.y - bbox.min_y), + ); + self.items.push(PaintItem { + id, + bounds, + z, + ink, + kind: PaintKind::Glyph(GlyphItem { + font: MusicFontRef(0), + glyph: SmuflGlyph::new(name.to_string()), + origin, + em_size: EM_SIZE, + }), + }); + true + } + + fn decor_glyph(&mut self, name: &str, origin: Point) { + let id = self.next_decor(); + self.glyph(id, name, origin, Ink::role(InkRole::Primary), 2); + } + + fn rule(&mut self, rect: Rect, kind: RuleKind, ink: Ink, z: i16) { + let id = self.next_decor(); + self.items + .push(PaintItem::primitive(id, z, ink, Primitive::Rule { + rect, + kind, + staff_group: None, + })); + } + + fn beam(&mut self, start: Point, end: Point, thickness: f64) { + let id = self.next_decor(); + self.items.push(PaintItem::primitive( + id, + 2, + Ink::role(InkRole::Primary), + Primitive::Beam(Beam { + start, + end, + thickness, + }), + )); + } + + /// One centred run. The width is *measured*, not estimated: it decides + /// both the item's bounds and where the run starts, so a guess is a run + /// drawn off centre — and, for the title, off the page. + fn text(&mut self, text: impl Into>, origin: Point, size: f64, z: i16) { + if self.hide_labels { + return; + } + self.push_text(text, origin, size, z); + } + + /// Lyrics are score content, not furniture, so compact views which hide + /// titles and measure labels must continue to show them. + fn lyric_text(&mut self, text: impl Into>, origin: Point, size: f64, z: i16) { + self.push_text(text, origin, size, z); + } + + /// Drum-key labels are score content too. Their anchor is the right edge + /// and their y is the notehead centre, not the top of the text line box. + fn drum_key_text( + &mut self, + text: impl Into>, + right: f64, + center_y: f64, + size: f64, + z: i16, + ) { + let text = text.into(); + let width = crate::title::text_width_sp(&text, size).max(size * 0.5); + let top = center_y - crate::title::line_box_sp(size) * 0.5; + self.push_text_left(text, Point::new(right - width, top), width, size, z); + } + + fn push_text(&mut self, text: impl Into>, origin: Point, size: f64, z: i16) { + let text = text.into(); + let width = crate::title::text_width_sp(&text, size).max(size * 0.5); + self.push_text_left( + text, + Point::new(origin.x - width * 0.5, origin.y), + width, + size, + z, + ); + } + + fn push_text_left( + &mut self, + text: Arc, + origin: Point, + width: f64, + size: f64, + z: i16, + ) { + let id = self.next_decor(); + self.items.push(PaintItem { + id, + bounds: Rect::from_xywh( + origin.x, + origin.y, + width, + crate::title::line_box_sp(size), + ), + z, + ink: Ink::role(InkRole::Secondary), + kind: PaintKind::Text(TextRun { + font: TextFontRef(0), + text, + origin, + size, + letter_spacing: 0.0, + direction: TextDirection::Auto, + language: None, + }), + }); + } +} + +/// Engraves one page of the score from its solved placement. +/// +/// Every x here comes from the spacing plan: the page tells this function +/// where each system, measure and onset column landed once the spring-and-rod +/// chain was solved to the system width. Nothing is divided up locally. +pub fn make_page( + score: &Score, + page: &PagePlacement, + page_index: usize, + revision: u64, +) -> Result<(PaintList, Vec), DocumentError> { + make_page_with_options( + score, + page, + page_index, + revision, + DocumentOptions::default(), + ) +} + +pub fn make_page_with_options( + score: &Score, + page: &PagePlacement, + page_index: usize, + revision: u64, + options: DocumentOptions, +) -> Result<(PaintList, Vec), DocumentError> { + let font = music_font(); + let style = LayoutStyle::default(); + let mut builder = PageBuilder { + font, + engraving: font.engraving(), + items: Vec::new(), + elements: Vec::new(), + decoration: DECORATION_TAG | ((page_index as u64 + 1) << 40), + page_index, + score, + hide_labels: options.hide_labels, + }; + + if page_index == 0 { + // The instrumentation is the score's own part list, not a guess. + let parts: Vec<&str> = score + .parts + .values() + .map(|part| part.name.as_str()) + .filter(|name| !name.trim().is_empty()) + .collect(); + let subtitle = if parts.is_empty() { + String::new() + } else { + format!("for {}", parts.join(", ")) + }; + // Fitted, not fixed: a long title shrinks and then wraps rather than + // running off both edges of the page. + let block = crate::title::title_block(&score.title, &subtitle); + for line in block.lines() { + builder.text( + line.text.clone(), + Point::new(options.page_size.x * 0.5, line.top), + line.size, + 1, + ); + } + } + + let measures = crate::spacing::ordered_measures(score); + let drum_key_rows = if page_index == 0 && options.drum_key { + drum_key_rows(score) + } else { + Vec::new() + }; + let drum_key_width = drum_key_rows_width(&drum_key_rows); + for (index, system) in page.systems.iter().enumerate() { + let Some(first) = system.measures.first() else { + continue; + }; + let Some(&measure) = measures.get(first.index) else { + continue; + }; + let staves = score_staff_frames(score, system.top); + let right = system + .measures + .last() + .map(|last| last.right) + .unwrap_or(system.right); + let first_system = page_index == 0 && index == 0; + let left = MARGIN_LEFT + if first_system { drum_key_width } else { 0.0 }; + draw_system_frame(&mut builder, &staves, index, left, right); + if first_system { + if let Some(staff) = staves.first().copied() { + draw_drum_key(&mut builder, staff, left, &drum_key_rows); + } + } + + let key = score + .maps + .key_at(measure.start, None, None) + .cloned() + .unwrap_or(KeySignature::C_MAJOR); + let meter = score.maps.meter_at(measure.start, None, None).cloned(); + draw_system_prefix( + &mut builder, + &staves, + &key, + meter.as_ref().filter(|_| system.show_meter), + &style, + left, + ); + + for placement in &system.measures { + let Some(&measure) = measures.get(placement.index) else { + continue; + }; + draw_measure( + &mut builder, + &staves, + measure, + &key, + placement, + placement.index == first.index, + placement.index + 1 == measures.len(), + ); + } + draw_system_lyrics(&mut builder, &staves, system, &measures); + } + + builder.text( + (page_index + 1).to_string(), + Point::new(options.page_size.x * 0.5, options.page_size.y - 7.0), + 1.8, + 1, + ); + + let list = PaintList::new( + PageId(page_index as u32), + revision, + options.page_size, + builder.items, + ) + .map_err(|error| DocumentError::Native(error.to_string()))?; + Ok((list, builder.elements)) +} + +fn draw_system_frame( + builder: &mut PageBuilder<'_>, + staves: &[StaffFrame], + system: usize, + left: f64, + right: f64, +) { + let Some(first) = staves.first() else { return }; + let last = staves.last().unwrap_or(first); + let staff_ink = Ink::role(InkRole::Staff); + let thickness = builder.engraving.staff_line_thickness; + for (index, staff) in staves.iter().enumerate() { + let group = system as u32 * 2 + index as u32 + 1; + for line in 0..5 { + let rect = Rect::from_xywh(left, staff.top + line as f64, right - left, thickness); + let id = builder.next_decor(); + builder.items.push(PaintItem::primitive( + id, + 0, + staff_ink, + Primitive::Rule { + rect, + kind: RuleKind::Staff, + staff_group: Some(group), + }, + )); + } + } + // Multi-staff parts get a brace-substitute bracket; a drum part stays a + // single, conventional five-line staff. + if staves.len() > 1 { + let id = builder.next_decor(); + builder.items.push(PaintItem::primitive( + id, + 1, + Ink::role(InkRole::Primary), + Primitive::Bracket { + x: left - 1.3, + top: first.top, + bottom: last.bottom(), + thickness: builder.engraving.bracket_thickness * 0.5, + hook: 1.0, + }, + )); + } + let thin = builder.engraving.thin_barline_thickness; + builder.rule( + Rect::from_xywh(left, first.top, thin, last.bottom() - first.top), + RuleKind::BarlineThin, + Ink::role(InkRole::Primary), + 1, + ); +} + +fn draw_drum_key( + builder: &mut PageBuilder<'_>, + staff: StaffFrame, + staff_left: f64, + rows: &[DrumKeyRow], +) { + let text_right = staff_left - DRUM_KEY_LEADER; + let thickness = builder.engraving.staff_line_thickness; + for row in rows { + let y = staff.middle() + - (row.diatonic - f64::from(staff.middle_diatonic)) * 0.5; + builder.drum_key_text(row.label.as_str(), text_right, y, DRUM_KEY_TEXT_SIZE, 2); + builder.rule( + Rect::from_xywh(text_right, y - thickness * 0.5, DRUM_KEY_LEADER, thickness), + RuleKind::Ledger, + Ink::role(InkRole::Secondary), + 1, + ); + } +} + +/// The geometry of a system prefix: clef, key signature and — on the score's +/// first system only — the time signature. +/// +/// The planner and the engraver share this so that "where music starts" is +/// one number computed once. All distances are style constants, not +/// hand-tuned literals. +struct Prefix { + clef_x: f64, + accidental: Option, + accidental_x: Vec, + meter: Option, + /// Distance from the left margin to the end of the prefix. + width: f64, +} + +struct MeterPrefix { + numerator: Vec, + denominator: Vec, + x: f64, + span: f64, +} + +fn prefix_layout( + font: &MusicFont, + key: &KeySignature, + meter: Option<&Meter>, + style: &LayoutStyle, +) -> Prefix { + let distance = &style.distance; + let mut cursor = distance.clef_left_margin.0; + let clef_x = cursor; + let clef = font.advance("gClef").max(font.advance("fClef")); + cursor += clef + distance.clef_to_key.0; + + let steps = key_signature_steps(key.fifths); + let mut accidental = None; + let mut accidental_x = Vec::new(); + if !steps.is_empty() { + let glyph = if key.fifths > 0 { + Symbol::Accidental(Accidental::Sharp) + } else { + Symbol::Accidental(Accidental::Flat) + } + .canonical_name() + .to_string(); + let advance = font.advance(&glyph).max(0.7) + distance.accidental_column.0; + for index in 0..steps.len() { + accidental_x.push(cursor + index as f64 * advance); + } + cursor += advance * steps.len() as f64; + accidental = Some(glyph); + } + + let meter = match meter { + Some(Meter::Measured { groups, unit }) => { + cursor += distance.key_to_time.0; + let beats: u32 = groups.iter().map(|group| u32::from(*group)).sum(); + let numerator: Vec = digits_of(beats) + .iter() + .map(|digit| digit.canonical_name().to_string()) + .collect(); + let denominator: Vec = digits_of(u32::from(*unit)) + .iter() + .map(|digit| digit.canonical_name().to_string()) + .collect(); + let run = |names: &[String]| -> f64 { names.iter().map(|name| font.advance(name)).sum() }; + let span = run(&numerator).max(run(&denominator)); + let at = cursor; + cursor += span; + Some(MeterPrefix { + numerator, + denominator, + x: at, + span, + }) + } + _ => None, + }; + + Prefix { + clef_x, + accidental, + accidental_x, + meter, + width: cursor, + } +} + +/// Distance from the left margin to where a system's music may start. +pub(crate) fn prefix_width( + font: &MusicFont, + key: &KeySignature, + meter: Option<&Meter>, + style: &LayoutStyle, +) -> f64 { + prefix_layout(font, key, meter, style).width +} + +/// Clef, key signature and (only where it belongs) time signature. +fn draw_system_prefix( + builder: &mut PageBuilder<'_>, + staves: &[StaffFrame], + key: &KeySignature, + meter: Option<&Meter>, + style: &LayoutStyle, + left: f64, +) { + let prefix = prefix_layout(builder.font, key, meter, style); + let steps = key_signature_steps(key.fifths); + for staff in staves { + builder.decor_glyph(staff.clef, Point::new(left + prefix.clef_x, staff.clef_line)); + if let Some(glyph) = &prefix.accidental { + let glyph = glyph.clone(); + for (step, x) in steps.iter().zip(&prefix.accidental_x) { + let y = staff.middle() - f64::from(*step + staff.key_shift) * 0.5; + builder.decor_glyph(&glyph, Point::new(left + x, y)); + } + } + if let Some(meter) = &prefix.meter { + for (digits, line) in [(&meter.numerator, 1.0), (&meter.denominator, 3.0)] { + let run: f64 = digits.iter().map(|name| builder.font.advance(name)).sum(); + let mut x = left + meter.x + (meter.span - run) * 0.5; + for name in digits { + let name = name.clone(); + builder.decor_glyph(&name, Point::new(x, staff.top + line)); + x += builder.font.advance(&name); + } + } + } + } +} + +fn digits_of(value: u32) -> Vec { + use makepad_score::symbol::Digit; + let digit = |value: u32| match value { + 0 => Digit::Zero, + 1 => Digit::One, + 2 => Digit::Two, + 3 => Digit::Three, + 4 => Digit::Four, + 5 => Digit::Five, + 6 => Digit::Six, + 7 => Digit::Seven, + 8 => Digit::Eight, + _ => Digit::Nine, + }; + value + .to_string() + .chars() + .filter_map(|character| character.to_digit(10)) + .map(|value| Symbol::TimeSignatureDigit(digit(value))) + .collect() +} + +/// Diatonic offsets from the middle line, in staff steps, for the accidentals +/// of a key signature on a treble staff. A bass staff is two steps lower. +fn key_signature_steps(fifths: i8) -> Vec { + const SHARPS: [i8; 7] = [4, 1, 5, 2, -1, 3, 0]; + const FLATS: [i8; 7] = [0, 3, -1, 2, -2, 1, -3]; + let count = fifths.unsigned_abs().min(7) as usize; + if fifths > 0 { + SHARPS[..count].to_vec() + } else { + FLATS[..count].to_vec() + } +} + +fn draw_measure( + builder: &mut PageBuilder<'_>, + staves: &[StaffFrame], + measure: &Measure, + key: &KeySignature, + placement: &MeasurePlacement, + first_in_system: bool, + last_of_score: bool, +) { + let Some(first_staff) = staves.first() else { return }; + let last_staff = staves.last().unwrap_or(first_staff); + let (x0, x1) = (placement.left, placement.right); + let measure_semantic = semantic_for_measure(measure.id); + let bounds = Rect::from_xywh( + x0, + first_staff.top - 3.0, + x1 - x0, + last_staff.bottom() - first_staff.top + 6.0, + ); + builder.items.push(PaintItem::primitive( + measure_semantic, + -2, + Ink::color(InkRole::Selection, LinearRgba::new(0.0, 0.0, 0.0, 0.0)), + Primitive::Rule { + rect: bounds, + kind: RuleKind::Staff, + staff_group: None, + }, + )); + let score = builder.score; + if let (Some(voice), Some(staff)) = ( + score.voices.values().next().map(|voice| voice.id), + score.staves.values().next().map(|staff| staff.id), + ) { + builder.elements.push(SemanticElement { + semantic: measure_semantic, + kind: SemanticKind::Measure, + note: None, + event: None, + measure: measure.id, + staff, + voice, + page: builder.page_index, + bounds, + midi: None, + }); + } + if first_in_system { + builder.text( + measure.label.clone(), + Point::new(x0 + 0.9, first_staff.top - 1.4), + 1.5, + 1, + ); + } + + // One barline through the whole grand staff reads as one system. + let thin = builder.engraving.thin_barline_thickness; + let height = last_staff.bottom() - first_staff.top; + if last_of_score { + let thick = builder.engraving.thick_barline_thickness; + let separation = 0.4; + builder.rule( + Rect::from_xywh(x1 - thick - separation - thin, first_staff.top, thin, height), + RuleKind::BarlineThin, + Ink::role(InkRole::Primary), + 1, + ); + builder.rule( + Rect::from_xywh(x1 - thick, first_staff.top, thick, height), + RuleKind::BarlineThick, + Ink::role(InkRole::Primary), + 1, + ); + } else { + builder.rule( + Rect::from_xywh(x1 - thin, first_staff.top, thin, height), + RuleKind::BarlineThin, + Ink::role(InkRole::Primary), + 1, + ); + } + + let staves_columns = measure_staff_columns(builder.font, builder.score, measure, key, staves); + for (staff_frame, voices) in staves.iter().zip(&staves_columns) { + if voices.is_empty() { + draw_measure_rest(builder, *staff_frame, (x0 + x1) * 0.5); + continue; + } + for columns in voices { + // Every column takes its x from the solved system chain; nothing + // is spread out locally. + let mut columns = columns.clone(); + for column in &mut columns { + column.x = placement.x_of(column.time); + } + draw_columns(builder, *staff_frame, measure, &columns); + } + } +} + +#[derive(Clone, Copy)] +struct LyricAnchor { + x: f64, + staff_bottom: f64, +} + +/// Lyrics are laid out after the system's note columns so every syllable, +/// hyphen, and melisma uses the same solved x coordinate as its notehead. +fn draw_system_lyrics( + builder: &mut PageBuilder<'_>, + staves: &[StaffFrame], + system: &SystemPlacement, + measures: &[&Measure], +) { + if builder.score.lyrics.is_empty() { + return; + } + let head_width = builder.font.bbox("noteheadBlack").width(); + let mut anchors = Vec::new(); + for placement in &system.measures { + let Some(&measure) = measures.get(placement.index) else { continue }; + let key = builder + .score + .maps + .key_at(measure.start, None, None) + .cloned() + .unwrap_or(KeySignature::C_MAJOR); + let staff_columns = + measure_staff_columns(builder.font, builder.score, measure, &key, staves); + for (staff, voices) in staves.iter().zip(&staff_columns) { + for columns in voices { + for column in columns { + let x = placement.x_of(column.time); + for head in &column.heads { + let shift = if head.shifted { + if column.stem_up { head_width } else { -head_width } + } else { + 0.0 + }; + let width = builder.font.bbox(&head.glyph).width().max(0.1); + anchors.push(( + head.note, + LyricAnchor { + x: x + shift + width * 0.5, + staff_bottom: staff.bottom(), + }, + )); + } + } + } + } + } + + let mut visible = builder + .score + .lyrics + .iter() + .filter_map(|lyric| { + anchors + .iter() + .find(|(note, _)| *note == lyric.note) + .map(|(_, anchor)| (lyric.clone(), *anchor)) + }) + .collect::>(); + visible.sort_by(|(left, left_anchor), (right, right_anchor)| { + left_anchor + .staff_bottom + .total_cmp(&right_anchor.staff_bottom) + .then_with(|| left.verse.cmp(&right.verse)) + .then_with(|| left_anchor.x.total_cmp(&right_anchor.x)) + }); + + const SIZE: f64 = 1.5; + const BELOW_STAFF: f64 = 2.5; + const VERSE_GAP: f64 = 1.8; + for (index, (lyric, anchor)) in visible.iter().enumerate() { + let y = anchor.staff_bottom + + BELOW_STAFF + + f64::from(lyric.verse.saturating_sub(1)) * VERSE_GAP; + let label = match &lyric.elision { + Some(elision) => format!("{}{}", lyric.text, elision), + None => lyric.text.clone(), + }; + let width = crate::title::text_width_sp(&label, SIZE).max(SIZE * 0.5); + builder.lyric_text(label, Point::new(anchor.x, y), SIZE, 2); + + if matches!(lyric.role, SyllabicRole::Begin | SyllabicRole::Middle) { + if let Some((next, next_anchor)) = visible.get(index + 1) { + if next.verse == lyric.verse + && (next_anchor.staff_bottom - anchor.staff_bottom).abs() < 0.01 + && matches!(next.role, SyllabicRole::Middle | SyllabicRole::End) + { + builder.lyric_text( + "-", + Point::new((anchor.x + next_anchor.x) * 0.5, y), + SIZE, + 2, + ); + } + } + } + + let Some(end_note) = lyric.melisma_to else { continue }; + let Some((_, end_anchor)) = anchors.iter().find(|(note, _)| *note == end_note) else { + continue; + }; + let start_x = anchor.x + width * 0.5 + 0.25; + let end_x = end_anchor.x - 0.2; + if end_x > start_x { + let line_y = y + crate::title::line_box_sp(SIZE) * 0.75; + let id = builder.next_decor(); + builder.items.push(PaintItem::primitive( + id, + 1, + Ink::role(InkRole::Secondary), + Primitive::Line { + start: Point::new(start_x, line_y), + end: Point::new(end_x, line_y), + thickness: 0.08, + dash: None, + kind: LineKind::LyricExtender, + }, + )); + } + } +} + +/// One measure's columns, per staff and then per active +/// voice. An empty voice list means that staff rests for the whole measure. +/// +/// Both the spacing pass (which measures the ink) and the engraving pass +/// (which draws it) go through here, so the rods the solver sees describe the +/// glyphs that actually get drawn. +pub(crate) fn measure_staff_columns( + font: &'static MusicFont, + score: &Score, + measure: &Measure, + key: &KeySignature, + staves: &[StaffFrame], +) -> Vec>> { + let Some(part) = score.parts.values().next() else { + return Vec::new(); + }; + let mut out = vec![Vec::new(); staves.len()]; + let measure_end = measure + .start + .checked_add(measure.extent) + .unwrap_or(measure.start); + for (slot, staff_frame) in staves.iter().copied().enumerate() { + let Some(staff_id) = part.staves.get(slot).copied() else { continue }; + let active: Vec<&makepad_score::model::Voice> = score + .voices + .values() + .filter(|voice| voice.staff == staff_id) + .filter(|voice| { + voice + .events + .iter() + .any(|event| in_measure(event, measure.start, measure_end)) + }) + .collect(); + let multi_voice = active.len() > 1; + for (voice_index, voice) in active.iter().enumerate() { + out[slot].push(build_columns( + font, + staff_frame, + voice, + measure, + measure_end, + key, + if multi_voice { + Some(voice_index == 0) + } else { + None + }, + )); + } + } + out +} + +fn in_measure(event: &TimedEvent, start: ScoreTime, end: ScoreTime) -> bool { + matches!(event.kind, EventKind::Chord(_)) + && !event.chord_notes().is_empty() + && event.onset >= start + && event.onset < end +} + +fn draw_measure_rest(builder: &mut PageBuilder<'_>, staff: StaffFrame, center_x: f64) { + let name = Symbol::Rest(makepad_score::symbol::RestDuration::Whole) + .canonical_name() + .to_string(); + let width = builder.font.bbox(&name).width(); + // A whole-measure rest hangs from the second line from the top. + builder.decor_glyph(&name, Point::new(center_x - width * 0.5, staff.top + 1.0)); +} + +/// One voice's columns for one measure, everything but their x: pitches, +/// written note values, stem directions, accidentals and second-interval +/// head shifts. The x arrives later, from the solved spacing chain. +fn build_columns( + font: &'static MusicFont, + staff: StaffFrame, + voice: &makepad_score::model::Voice, + measure: &Measure, + measure_end: ScoreTime, + key: &KeySignature, + forced_stem_up: Option, +) -> Vec { + let mut state = KeyState::new(key); + let mut columns = Vec::new(); + + let events: Vec<&TimedEvent> = voice + .events + .iter() + .filter(|event| in_measure(event, measure.start, measure_end)) + .collect(); + for (index, event) in events.iter().enumerate() { + // A performance import carries sounding lengths, not written ones: a + // staccato sixteenth is stored as a thirty-second. Writing each note up + // to the next onset recovers the notated rhythm, and cannot overstate a + // note, because this engraver has no rests to put in the gap. + let remaining = measure_end + .checked_sub(event.onset) + .map(|time| rational_f64(time.0)) + .unwrap_or(0.0); + let sounding = event + .duration + .map(|duration| rational_f64(duration.0)) + .unwrap_or(0.0); + let written = match events.get(index + 1) { + Some(next) => next + .onset + .checked_sub(event.onset) + .map(|time| rational_f64(time.0)) + .unwrap_or(sounding), + // The last note of the measure keeps its own length: there is no + // following onset to measure against. + None => sounding.min(remaining), + }; + let value = note_value_of(if written > 0.0 { written } else { sounding }); + let mut heads: Vec = Vec::new(); + for note in event.chord_notes() { + let Some(pitch) = note.written_pitch else { + continue; + }; + let diatonic = diatonic_index(pitch); + let accidental = state.accidental_for(pitch, diatonic); + heads.push(HeadLayout { + note: note.id, + midi: pitch_to_midi(pitch), + diatonic, + y: staff.y_of(diatonic), + glyph: value.notehead(¬e.notehead).canonical_name().to_string(), + accidental, + shifted: false, + }); + } + if heads.is_empty() { + continue; + } + heads.sort_by(|a, b| a.diatonic.cmp(&b.diatonic)); + heads.dedup_by(|a, b| a.diatonic == b.diatonic); + + let average = heads.iter().map(|head| head.diatonic).sum::() as f64 + / heads.len() as f64; + let stem_up = forced_stem_up + .unwrap_or_else(|| average < f64::from(staff.middle_diatonic) + 0.01); + // Seconds cannot share a side of the stem. + let mut previous: Option = None; + let mut previous_shifted = false; + let order: Vec = if stem_up { + (0..heads.len()).collect() + } else { + (0..heads.len()).rev().collect() + }; + for index in order { + let diatonic = heads[index].diatonic; + let shifted = previous + .map(|previous_diatonic| (diatonic - previous_diatonic).abs() == 1) + .unwrap_or(false) + && !previous_shifted; + heads[index].shifted = shifted; + previous = Some(diatonic); + previous_shifted = shifted; + } + + let articulations = event + .articulations + .iter() + .filter_map(|placed| { + let placement = if stem_up { + Placement::Below + } else { + Placement::Above + }; + let symbol = Symbol::Articulation { + articulation: placed.kind, + placement, + }; + let name = symbol.canonical_name().to_string(); + font.has(&name).then_some(name) + }) + .collect(); + + columns.push(Column { + event: event.id, + measure: measure.id, + voice: voice.id, + onset: rational_f64(event.onset.0), + time: event.onset, + staff: voice.staff, + x: 0.0, + heads, + value, + stem_up, + articulations, + }); + } + columns.sort_by(|a, b| a.onset.total_cmp(&b.onset)); + columns +} + +/// Tracks which accidentals are already sounding in the current measure. +struct KeyState { + signature: [i32; 7], + current: std::collections::BTreeMap, +} + +impl KeyState { + fn new(key: &KeySignature) -> Self { + let mut signature = [0_i32; 7]; + let sharp_order = [3_usize, 0, 4, 1, 5, 2, 6]; + let flat_order = [6_usize, 2, 5, 1, 4, 0, 3]; + let count = key.fifths.unsigned_abs().min(7) as usize; + if key.fifths > 0 { + for step in &sharp_order[..count] { + signature[*step] = 1; + } + } else { + for step in &flat_order[..count] { + signature[*step] = -1; + } + } + Self { + signature, + current: std::collections::BTreeMap::new(), + } + } + + fn accidental_for(&mut self, pitch: Pitch, diatonic: i32) -> Option { + let alter = (rational_f64(pitch.alter.0)).round() as i32; + let step = diatonic.rem_euclid(7) as usize; + let sounding = self + .current + .get(&diatonic) + .copied() + .unwrap_or(self.signature[step]); + if alter == sounding { + return None; + } + self.current.insert(diatonic, alter); + let accidental = match alter { + -3 => Accidental::TripleFlat, + -2 => Accidental::DoubleFlat, + -1 => Accidental::Flat, + 0 => Accidental::Natural, + 1 => Accidental::Sharp, + 2 => Accidental::DoubleSharp, + _ => Accidental::TripleSharp, + }; + Some(Symbol::Accidental(accidental).canonical_name().to_string()) + } +} + +fn draw_columns( + builder: &mut PageBuilder<'_>, + staff: StaffFrame, + measure: &Measure, + columns: &[Column], +) { + let groups = beam_groups(builder.score, measure, columns); + let mut beamed = vec![false; columns.len()]; + for group in &groups { + for index in group { + beamed[*index] = true; + } + } + for (index, column) in columns.iter().enumerate() { + draw_column_heads(builder, staff, column); + if !column.value.has_stem() { + continue; + } + if beamed[index] { + continue; + } + let tip = unbeamed_stem_tip(staff, column); + draw_stem(builder, column, tip); + let flags = column.value.flags(); + if flags > 0 { + draw_flag(builder, column, tip, flags); + } + } + for group in &groups { + draw_beam_group(builder, staff, columns, group); + } +} + +fn draw_column_heads(builder: &mut PageBuilder<'_>, staff: StaffFrame, column: &Column) { + let head_width = builder.font.bbox("noteheadBlack").width(); + let extension = builder.engraving.leger_line_extension; + let ledger_thickness = builder.engraving.leger_line_thickness; + let mut ledgers: Vec<(f64, f64, f64)> = Vec::new(); + + for head in &column.heads { + let width = builder.font.bbox(&head.glyph).width().max(0.1); + let shift = if head.shifted { + if column.stem_up { + head_width + } else { + -head_width + } + } else { + 0.0 + }; + let x = column.x + shift; + let semantic = semantic_for_note(head.note); + let bounds = Rect::new( + Point::new(x, head.y - 0.5), + Point::new(x + width, head.y + 0.5), + ); + let drawn = builder.glyph( + semantic, + &head.glyph, + Point::new(x, head.y), + Ink::role(InkRole::Primary), + 2, + ); + if drawn { + builder.elements.push(SemanticElement { + semantic, + kind: SemanticKind::Note, + note: Some(head.note), + event: Some(column.event), + measure: column.measure, + staff: column.staff, + voice: column.voice, + page: builder.page_index, + bounds, + midi: Some(head.midi), + }); + } + if let Some(accidental) = &head.accidental { + let accidental_width = builder.font.advance(accidental).max(0.6); + builder.decor_glyph( + accidental, + Point::new(x - accidental_width - 0.22, head.y), + ); + } + // Ledger lines: one for every staff position outside the five lines. + let mut line = staff.top - 1.0; + while line >= head.y - 0.01 { + ledgers.push((line, x, width)); + line -= 1.0; + } + let mut line = staff.bottom() + 1.0; + while line <= head.y + 0.01 { + ledgers.push((line, x, width)); + line += 1.0; + } + if column.value.dots > 0 { + let mut dot_y = head.y; + if (head.y - staff.top).rem_euclid(1.0).abs() < 0.01 { + dot_y -= 0.5; + } + let dot_width = builder.font.advance("augmentationDot").max(0.3); + for dot in 0..column.value.dots { + builder.decor_glyph( + "augmentationDot", + Point::new( + x + width + 0.32 + f64::from(dot) * dot_width * 1.1, + dot_y, + ), + ); + } + } + } + + ledgers.sort_by(|a, b| a.0.total_cmp(&b.0).then(a.1.total_cmp(&b.1))); + ledgers.dedup_by(|a, b| (a.0 - b.0).abs() < 0.01 && (a.1 - b.1).abs() < 0.01); + for (y, x, width) in ledgers { + builder.rule( + Rect::from_xywh( + x - extension, + y - ledger_thickness * 0.5, + width + extension * 2.0, + ledger_thickness, + ), + RuleKind::Ledger, + Ink::role(InkRole::Primary), + 1, + ); + } + + for (index, articulation) in column.articulations.iter().enumerate() { + let bbox = builder.font.bbox(articulation); + let width = bbox.width().max(0.2); + let x = column.x + head_width * 0.5 - width * 0.5; + let y = if column.stem_up { + column.bottom_y() + 0.9 + index as f64 * 0.6 + } else { + column.top_y() - 0.9 - index as f64 * 0.6 + }; + builder.decor_glyph(articulation, Point::new(x, y)); + } +} + +fn unbeamed_stem_tip(staff: StaffFrame, column: &Column) -> f64 { + let extra = f64::from(column.value.flags().saturating_sub(1)) * 0.5; + if column.stem_up { + (column.stem_far_y() - STEM_LENGTH - extra).min(staff.middle()) + } else { + (column.stem_far_y() + STEM_LENGTH + extra).max(staff.middle()) + } +} + +/// Page x of the centre of a column's stem, from the font's own anchor. +fn stem_x(builder: &PageBuilder<'_>, column: &Column) -> f64 { + let thickness = builder.engraving.stem_thickness; + let glyph = column + .heads + .first() + .map(|head| head.glyph.clone()) + .unwrap_or_else(|| "noteheadBlack".to_string()); + if column.stem_up { + column.x + builder.font.stem_up_se(&glyph).0 - thickness * 0.5 + } else { + column.x + builder.font.stem_down_nw(&glyph).0 + thickness * 0.5 + } +} + +fn draw_stem(builder: &mut PageBuilder<'_>, column: &Column, tip: f64) { + let thickness = builder.engraving.stem_thickness; + let glyph = column + .heads + .first() + .map(|head| head.glyph.clone()) + .unwrap_or_else(|| "noteheadBlack".to_string()); + let center = stem_x(builder, column); + let attach = if column.stem_up { + column.stem_origin_y() - builder.font.stem_up_se(&glyph).1 + } else { + column.stem_origin_y() - builder.font.stem_down_nw(&glyph).1 + }; + let (top, bottom) = if tip < attach { (tip, attach) } else { (attach, tip) }; + builder.rule( + Rect::from_xywh(center - thickness * 0.5, top, thickness, bottom - top), + RuleKind::Stem, + Ink::role(InkRole::Primary), + 2, + ); +} + +fn draw_flag(builder: &mut PageBuilder<'_>, column: &Column, tip: f64, flags: u8) { + let duration = match flags { + 1 => FlagDuration::Eighth, + 2 => FlagDuration::Sixteenth, + 3 => FlagDuration::ThirtySecond, + 4 => FlagDuration::SixtyFourth, + _ => FlagDuration::OneTwentyEighth, + }; + let direction = if column.stem_up { + Direction::Up + } else { + Direction::Down + }; + let name = Symbol::Flag { + duration, + direction, + } + .canonical_name() + .to_string(); + let thickness = builder.engraving.stem_thickness; + let x = stem_x(builder, column) + + if column.stem_up { + -thickness * 0.5 + } else { + -thickness * 0.5 + }; + builder.decor_glyph(&name, Point::new(x, tip)); +} + +/// Splits a measure's columns into beam groups: runs of two or more flagged +/// notes inside one metrical beat. +fn beam_groups(score: &Score, measure: &Measure, columns: &[Column]) -> Vec> { + let beat = beat_length(score, measure); + let measure_start = rational_f64(measure.start.0); + let mut groups: Vec> = Vec::new(); + let mut current: Vec = Vec::new(); + let mut current_beat: Option = None; + for (index, column) in columns.iter().enumerate() { + let beat_index = (((column.onset - measure_start) / beat) + 1e-6).floor() as i64; + let beamable = column.value.flags() > 0; + // Note: a played rest inside a beat does not break the group, because + // this engraver does not yet write rests between notes; grouping on the + // beat alone is what a performance import can honestly support. + if !beamable || current_beat != Some(beat_index) { + if current.len() > 1 { + groups.push(std::mem::take(&mut current)); + } else { + current.clear(); + } + } + if beamable { + current_beat = Some(beat_index); + current.push(index); + } else { + current_beat = None; + } + } + if current.len() > 1 { + groups.push(current); + } + groups +} + +/// The beaming unit: a beat, or a dotted beat in a compound meter. +fn beat_length(score: &Score, measure: &Measure) -> f64 { + let meter = score.maps.meter_at(measure.start, None, None); + match meter { + Some(Meter::Measured { groups, unit }) if *unit > 0 => { + let beats: u32 = groups.iter().map(|group| u32::from(*group)).sum(); + let unit_length = 1.0 / f64::from(*unit); + if *unit >= 8 && beats % 3 == 0 && beats > 3 { + unit_length * 3.0 + } else { + unit_length + } + } + _ => 0.25, + } +} + +fn draw_beam_group( + builder: &mut PageBuilder<'_>, + staff: StaffFrame, + columns: &[Column], + group: &[usize], +) { + if group.len() < 2 { + return; + } + // One direction for the whole group. Where a voice has already been given + // a direction (two voices sharing a staff), the beam must not fight it. + let forced = columns[group[0]].stem_up; + let agreed = group + .iter() + .all(|index| columns[*index].stem_up == forced); + let average = group + .iter() + .flat_map(|index| columns[*index].heads.iter().map(|head| head.diatonic)) + .sum::() as f64 + / group + .iter() + .map(|index| columns[*index].heads.len()) + .sum::() + .max(1) as f64; + let stem_up = if agreed { + forced + } else { + average < f64::from(staff.middle_diatonic) + 0.01 + }; + + let members: Vec = group + .iter() + .map(|index| Column { + stem_up, + ..columns[*index].clone() + }) + .collect(); + let xs: Vec = members + .iter() + .map(|column| stem_x(builder, column)) + .collect(); + let first_x = xs[0]; + let last_x = *xs.last().unwrap(); + let run = (last_x - first_x).max(0.001); + + let ideal = |column: &Column| -> f64 { + if stem_up { + column.stem_far_y() - STEM_LENGTH + } else { + column.stem_far_y() + STEM_LENGTH + } + }; + let first_ideal = ideal(&members[0]); + let last_ideal = ideal(members.last().unwrap()); + // A gentle, capped slope reads better than following the outer notes. + let slope = ((last_ideal - first_ideal) / run).clamp(-0.25, 0.25); + let cap = 1.5 / run; + let slope = slope.clamp(-cap, cap); + + let mut offset = if stem_up { f64::INFINITY } else { f64::NEG_INFINITY }; + for (column, x) in members.iter().zip(&xs) { + let limit = if stem_up { + column.stem_far_y() - BEAM_MIN_STEM - slope * (x - first_x) + } else { + column.stem_far_y() + BEAM_MIN_STEM - slope * (x - first_x) + }; + offset = if stem_up { + offset.min(limit) + } else { + offset.max(limit) + }; + } + // Keep the beam from crowding the staff on the far side. + let line_y = |x: f64| offset + slope * (x - first_x); + + let thickness = builder.engraving.beam_thickness; + let spacing = builder.engraving.beam_spacing; + let stem_thickness = builder.engraving.stem_thickness; + let inward = if stem_up { 1.0 } else { -1.0 }; + + for (column, x) in members.iter().zip(&xs) { + draw_stem(builder, column, line_y(*x)); + } + + let max_level = members + .iter() + .map(|column| column.value.flags()) + .max() + .unwrap_or(1) + .max(1); + for level in 0..max_level { + let dy = inward * (f64::from(level) * (thickness + spacing) + thickness * 0.5); + let mut index = 0; + while index < members.len() { + if members[index].value.flags() <= level { + index += 1; + continue; + } + let start = index; + while index < members.len() && members[index].value.flags() > level { + index += 1; + } + let end = index - 1; + if start == end { + if level == 0 { + continue; + } + // A lone short note inside the group takes a hook. + let x = xs[start]; + let hook = 1.0; + let toward_previous = start > 0; + let (from, to) = if toward_previous { + (x - hook, x + stem_thickness * 0.5) + } else { + (x - stem_thickness * 0.5, x + hook) + }; + builder.beam( + Point::new(from, line_y(from) + dy), + Point::new(to, line_y(to) + dy), + thickness, + ); + continue; + } + let from = xs[start] - stem_thickness * 0.5; + let to = xs[end] + stem_thickness * 0.5; + builder.beam( + Point::new(from, line_y(from) + dy), + Point::new(to, line_y(to) + dy), + thickness, + ); + } + } +} + +/// Reads a length in whole notes as a written note value: a power of two plus +/// augmentation dots. +fn note_value_of(value: f64) -> NoteValue { + if !(value > 0.0) { + return NoteValue { power: 2, dots: 0 }; + } + for power in 0..=7_u8 { + let base = 0.5_f64.powi(i32::from(power)); + for dots in 0..=2_u8 { + let scale = 2.0 - 0.5_f64.powi(i32::from(dots)); + if (value - base * scale).abs() < 1e-6 { + return NoteValue { power, dots }; + } + } + } + // Not a written value (a quantized import can produce these): take the + // largest note that fits, so the notehead and beaming stay sane. + let mut power = 0_u8; + while power < 7 && 0.5_f64.powi(i32::from(power)) > value + 1e-9 { + power += 1; + } + NoteValue { power, dots: 0 } +} + +fn diatonic_index(pitch: Pitch) -> i32 { + i32::from(pitch.octave) * 7 + i32::from(pitch.step.index()) +} + +fn rational_f64(value: Rational) -> f64 { + value.numerator() as f64 / value.denominator() as f64 +} + +#[doc(hidden)] +pub mod tests { + use super::*; + use makepad_score::model::{ + Alter, Change, Duration, EventTag, FlowNode, IdGenerator, LayerTag, MapScope, MeasureTag, Note, + NoteTag, Part, PartTag, Staff, StaffKind, StaffTag, Step, Transposition, VoiceTag, + }; + use makepad_score_render::PaintKind; + + #[allow(dead_code)] + fn duration(numerator: i64, denominator: u64) -> f64 { + numerator as f64 / denominator as f64 + } + + /// A one-measure grand-staff score whose upper voice is `pitches`, each of + /// `note_denominator` length, starting on the downbeat. + pub fn fixture(pitches: &[(Step, i8)], note_denominator: u64) -> Score { + let events: Vec = pitches + .iter() + .enumerate() + .map(|(index, &(step, octave))| Placed { + onset: (index as i64, note_denominator), + duration: (1, note_denominator), + step, + octave, + }) + .collect(); + fixture_events(&events) + } + + /// One note of a test fixture: where it starts, how long it lasts, what + /// pitch it is. + #[derive(Clone, Copy, Debug)] + pub struct Placed { + pub onset: (i64, u64), + pub duration: (i64, u64), + pub step: Step, + pub octave: i8, + } + + /// A one-measure, one-voice grand-staff score holding exactly `events`. + pub fn fixture_events(events: &[Placed]) -> Score { + let mut ids = IdGenerator::new(0x7e57); + let piano = ids.next::().unwrap(); + let treble = ids.next::().unwrap(); + let bass = ids.next::().unwrap(); + let right = ids.next::().unwrap(); + let left = ids.next::().unwrap(); + let _ = ids.next::().unwrap(); + let mut score = Score::new(*b"MAKEPADSCORETEST"); + score.title = "Fixture".into(); + score.parts.insert( + piano, + Part { + id: piano, + name: "Piano".into(), + staves: vec![treble, bass], + transposition: Transposition::NONE, + }, + ); + for (id, parent) in [(treble, None), (bass, Some(treble))] { + score.staves.insert( + id, + Staff { + id, + part: piano, + parent, + kind: StaffKind::Standard, + voices: vec![if id == treble { right } else { left }], + }, + ); + } + let measure = ids.next::().unwrap(); + score.measures.insert( + measure, + Measure { + id: measure, + ordinal: 0, + label: "1".into(), + start: ScoreTime::ZERO, + extent: Duration::new(1, 1).unwrap(), + }, + ); + score.flow.nodes.push(FlowNode { + measure, + ordinal: 0, + }); + let mut placed = Vec::new(); + for note in events { + let event = ids.next::().unwrap(); + let id = ids.next::().unwrap(); + placed.push(TimedEvent { + id: event, + onset: ScoreTime::new(note.onset.0, note.onset.1).unwrap(), + duration: Some(Duration::new(note.duration.0, note.duration.1).unwrap()), + grace: None, + kind: EventKind::Chord(vec![Note { + performance: None, + id, + written_pitch: Some(Pitch::new(note.step, Alter::NATURAL, note.octave)), + unpitched_sound: None, + display_staff: treble, + tie_from: None, + tie_to: None, + tab: None, + notehead: Notehead::Normal, + }]), + beams: Vec::new(), + tuplets: Vec::new(), + articulations: Vec::new(), + ornaments: Vec::new(), + }); + } + score.voices.insert( + right, + makepad_score::model::Voice { + id: right, + staff: treble, + number: 1, + events: placed, + }, + ); + score.voices.insert( + left, + makepad_score::model::Voice { + id: left, + staff: bass, + number: 2, + events: Vec::new(), + }, + ); + score.maps.time_signature.push(Change { + at: ScoreTime::ZERO, + scope: MapScope::Global, + value: Meter::Measured { + groups: vec![4], + unit: 4, + }, + }); + score + } + + pub struct Drawn { + pub noteheads: Vec<(f64, f64, f64)>, + pub beams: Vec, + pub stems: Vec, + pub ledgers: Vec, + pub glyphs: Vec, + /// Page y of the upper staff's top line on the first system. + pub staff_top: f64, + /// Page x of the first system's closing barline. + pub system_right: f64, + } + + pub fn engrave(score: &Score) -> Drawn { + let mut spacing = crate::spacing::ScoreSpacing::new(); + spacing.rebuild(score); + let placement = spacing.pages()[0].clone(); + let system = &placement.systems[0]; + let (page, _elements) = make_page(score, &placement, 0, 1).unwrap(); + let mut drawn = Drawn { + noteheads: Vec::new(), + beams: Vec::new(), + stems: Vec::new(), + ledgers: Vec::new(), + glyphs: Vec::new(), + staff_top: system.top, + system_right: system.measures.last().map(|m| m.right).unwrap_or(system.right), + }; + for item in page.items() { + match &item.kind { + PaintKind::Glyph(glyph) => { + drawn.glyphs.push(glyph.glyph.0.to_string()); + if glyph.glyph.0.starts_with("notehead") { + drawn.noteheads.push(( + glyph.origin.x, + glyph.origin.y, + item.bounds.width(), + )); + } + } + PaintKind::Primitive(Primitive::Beam(beam)) => drawn.beams.push(*beam), + PaintKind::Primitive(Primitive::Rule { + rect, + kind: RuleKind::Stem, + .. + }) => drawn.stems.push(*rect), + PaintKind::Primitive(Primitive::Rule { + rect, + kind: RuleKind::Ledger, + .. + }) => drawn.ledgers.push(*rect), + _ => {} + } + } + drawn + } + + #[test] + fn eighth_notes_are_beamed_by_the_beat_and_the_beam_clears_every_head() { + let pitches: Vec<(Step, i8)> = [ + (Step::C, 4), + (Step::D, 4), + (Step::E, 4), + (Step::F, 4), + (Step::G, 4), + (Step::A, 4), + (Step::B, 4), + (Step::C, 5), + ] + .into(); + let drawn = engrave(&fixture(&pitches, 8)); + assert_eq!(drawn.noteheads.len(), 8); + // Four beats of two eighths each. + assert_eq!(drawn.beams.len(), 4); + assert_eq!(drawn.stems.len(), 8); + for beam in &drawn.beams { + let heads: Vec<_> = drawn + .noteheads + .iter() + .filter(|(x, _, width)| { + *x + *width >= beam.start.x - 0.3 && *x <= beam.end.x + 0.3 + }) + .collect(); + assert_eq!(heads.len(), 2, "each beam spans exactly its two heads"); + // A beam sits wholly above its heads (stems up) or wholly below. + let above = beam.start.y < heads[0].1; + for (x, y, width) in heads { + // The beam is slanted: measure it directly over the notehead. + let t = ((x + width * 0.5 - beam.start.x) / (beam.end.x - beam.start.x)) + .clamp(0.0, 1.0); + let center = beam.start.y + (beam.end.y - beam.start.y) * t; + let near_edge = center + beam.thickness * 0.5 * if above { 1.0 } else { -1.0 }; + let clearance = if above { y - near_edge } else { near_edge - y }; + assert!( + clearance >= 2.0, + "beam edge {near_edge} crowds a notehead centred on {y}" + ); + } + } + // Every stem ends exactly on the outer edge of its beam. + for stem in &drawn.stems { + let x = stem.center().x; + assert!( + drawn + .beams + .iter() + .filter(|beam| x >= beam.start.x - 0.2 && x <= beam.end.x + 0.2) + .any(|beam| { + let t = ((x - beam.start.x) / (beam.end.x - beam.start.x)).clamp(0.0, 1.0); + let center = beam.start.y + (beam.end.y - beam.start.y) * t; + (center - beam.thickness * 0.5 - stem.min.y).abs() < 0.02 + || (center + beam.thickness * 0.5 - stem.max.y).abs() < 0.02 + }), + "a stem at {stem:?} does not meet a beam" + ); + } + } + + #[test] + fn high_notes_take_ledger_lines_at_whole_staff_positions() { + // A5 and C6 are the first two ledger positions above a treble staff. + let drawn = engrave(&fixture(&[(Step::C, 6)], 4)); + assert_eq!(drawn.noteheads.len(), 1); + let mut lines: Vec = drawn + .ledgers + .iter() + .map(|rect| rect.center().y - drawn.staff_top) + .collect(); + lines.sort_by(f64::total_cmp); + assert_eq!(lines, vec![-2.0, -1.0]); + let head_width = drawn.noteheads[0].2; + for ledger in &drawn.ledgers { + assert!( + ledger.width() > head_width, + "a ledger line must extend past the notehead" + ); + } + } + + #[test] + fn notes_inside_the_staff_take_no_ledger_lines() { + let drawn = engrave(&fixture(&[(Step::B, 4), (Step::E, 4), (Step::F, 5)], 4)); + assert!(drawn.ledgers.is_empty(), "{:?}", drawn.ledgers); + } + + #[test] + fn an_empty_staff_gets_a_measure_rest_and_the_page_gets_its_furniture() { + let drawn = engrave(&fixture(&[(Step::G, 4)], 4)); + assert!(drawn.glyphs.iter().any(|name| name == "restWhole")); + assert!(drawn.glyphs.iter().any(|name| name == "gClef")); + assert!(drawn.glyphs.iter().any(|name| name == "fClef")); + assert!(drawn.glyphs.iter().any(|name| name == "timeSig4")); + } + + #[test] + fn a_lyric_is_text_below_the_staff_even_when_labels_are_hidden() { + let note = crate::build::PitchedNote { + onset_beats: 0.0, + duration_beats: 1.0, + midi: 60, + velocity: 0.8, + }; + let word = crate::build::LyricWord { + onset_beats: 0.0, + end_beats: 1.0, + text: "sing".into(), + }; + let score = crate::build::build_pitched_score_with_lyrics( + &[note], + &[word], + &crate::build::BuildOptions::default(), + ); + let mut spacing = crate::spacing::ScoreSpacing::new(); + spacing.rebuild(&score); + let placement = spacing.pages()[0].clone(); + let staff_bottom = placement.systems[0].top + 4.0; + let options = DocumentOptions::content(&score, true); + let (page, _) = make_page_with_options(&score, &placement, 0, 1, options).unwrap(); + let lyric = page + .items() + .iter() + .find(|item| { + matches!(&item.kind, PaintKind::Text(run) if run.text.as_ref() == "sing") + }) + .expect("lyric text is engraved"); + assert!(lyric.bounds.min.y >= staff_bottom + 2.0, "{:?}", lyric.bounds); + } + + #[test] + fn durations_read_as_written_values() { + assert_eq!(note_value_of(duration(1, 1)), NoteValue { power: 0, dots: 0 }); + assert_eq!(note_value_of(duration(1, 2)), NoteValue { power: 1, dots: 0 }); + assert_eq!(note_value_of(duration(1, 4)), NoteValue { power: 2, dots: 0 }); + assert_eq!(note_value_of(duration(3, 8)), NoteValue { power: 2, dots: 1 }); + assert_eq!(note_value_of(duration(1, 8)), NoteValue { power: 3, dots: 0 }); + assert_eq!(note_value_of(duration(1, 16)).flags(), 2); + // 5/16 is not a written value; it degrades to the largest that fits. + assert_eq!(note_value_of(duration(5, 16)), NoteValue { power: 2, dots: 0 }); + } + + #[test] + fn diatonic_positions_follow_the_clef() { + let treble = StaffFrame::treble(10.0); + // B4 is the middle line; C4 is one ledger line below the staff. + let b4 = diatonic_index(Pitch::new(Step::B, Alter::NATURAL, 4)); + let c4 = diatonic_index(Pitch::new(Step::C, Alter::NATURAL, 4)); + let f5 = diatonic_index(Pitch::new(Step::F, Alter::NATURAL, 5)); + assert_eq!(treble.y_of(b4), 12.0); + assert_eq!(treble.y_of(c4), 15.0); + assert_eq!(treble.y_of(f5), 10.0); + + let bass = StaffFrame::bass(30.0); + let d3 = diatonic_index(Pitch::new(Step::D, Alter::NATURAL, 3)); + let c4 = diatonic_index(Pitch::new(Step::C, Alter::NATURAL, 4)); + assert_eq!(bass.y_of(d3), 32.0); + // Middle C is one ledger line above a bass staff. + assert_eq!(bass.y_of(c4), 29.0); + } + + #[test] + fn key_signature_accidentals_land_on_the_right_lines() { + assert_eq!(key_signature_steps(0), Vec::::new()); + // F sharp sits on the top line of a treble staff. + assert_eq!(key_signature_steps(1), vec![4]); + assert_eq!(key_signature_steps(-1), vec![0]); + assert_eq!(key_signature_steps(5).len(), 5); + } +} diff --git a/libs/score_view/src/font.rs b/libs/score_view/src/font.rs new file mode 100644 index 000000000..86984c619 --- /dev/null +++ b/libs/score_view/src/font.rs @@ -0,0 +1,1018 @@ +//! Music-font loading. +//! +//! The engraver needs real SMuFL outlines, not stand-ins. This module resolves +//! one OpenType music font plus its SMuFL metadata, pulls glyph outlines out of +//! the font by canonical name, and exposes the metric surface the engraver +//! needs: glyph bounding boxes, advance widths, stem anchors, and the font's +//! `engravingDefaults`. +//! +//! # Coordinates +//! +//! Outlines stay in the font's own design units (y-up), exactly as +//! [`makepad_score_render::GlyphOutline`] expects; the renderer normalizes them +//! by `units_per_em` and multiplies by a paint item's `em_size`. Everything +//! else here is in staff spaces, y-up, relative to the glyph origin, following +//! SMuFL's rule that one em is four staff spaces. +//! +//! # Availability +//! +//! The font is looked up at runtime (see [`search_paths`]); a checkout without +//! one still starts, falling back to a small set of hand-drawn outlines fitted +//! to Bravura's own bounding boxes. + +use makepad_score::{ + smufl::{FontMetadata, GlyphRegistry}, + symbol::{ + Accidental, Articulation, Clef, Digit, Direction, DynamicMark, FermataShape, FlagDuration, + NoteheadDuration, NoteheadShape, Ornament, Placement, RestDuration, Symbol, TremoloStrokes, + }, +}; +use makepad_score_render::{GlyphOutline, GlyphOutlineCommand}; +use std::{ + collections::BTreeMap, + path::{Path, PathBuf}, + sync::{Arc, OnceLock}, +}; + +/// A glyph's ink box in staff spaces, y-up, relative to the glyph origin. +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct GlyphBox { + pub min_x: f64, + pub min_y: f64, + pub max_x: f64, + pub max_y: f64, +} + +impl GlyphBox { + pub fn width(self) -> f64 { + self.max_x - self.min_x + } + + pub fn height(self) -> f64 { + self.max_y - self.min_y + } +} + +/// The font-independent engraving measurements this app consumes, in staff +/// spaces. Values are Bravura's until a font's `engravingDefaults` replaces +/// them. +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct Engraving { + pub staff_line_thickness: f64, + pub stem_thickness: f64, + pub beam_thickness: f64, + pub beam_spacing: f64, + pub leger_line_thickness: f64, + pub leger_line_extension: f64, + pub thin_barline_thickness: f64, + pub thick_barline_thickness: f64, + pub bracket_thickness: f64, +} + +impl Default for Engraving { + fn default() -> Self { + Self { + staff_line_thickness: 0.13, + stem_thickness: 0.12, + beam_thickness: 0.5, + beam_spacing: 0.25, + leger_line_thickness: 0.16, + leger_line_extension: 0.4, + thin_barline_thickness: 0.16, + thick_barline_thickness: 0.5, + bracket_thickness: 0.5, + } + } +} + +#[derive(Clone, Copy, Debug, Default)] +struct GlyphMetrics { + bbox: Option, + advance: Option, + stem_up_se: Option<(f64, f64)>, + stem_down_nw: Option<(f64, f64)>, +} + +/// One resolved music font: outlines by canonical SMuFL name plus metrics. +pub struct MusicFont { + source: String, + real: bool, + units_per_em: u16, + engraving: Engraving, + outlines: BTreeMap, + metrics: BTreeMap, +} + +impl MusicFont { + /// A one-line description of where the outlines came from. + pub fn source(&self) -> &str { + &self.source + } + + /// False when the hand-drawn fallback is in use. + pub fn is_real(&self) -> bool { + self.real + } + + pub fn units_per_em(&self) -> u16 { + self.units_per_em + } + + pub fn engraving(&self) -> Engraving { + self.engraving + } + + pub fn outlines(&self) -> impl Iterator { + self.outlines.iter().map(|(name, outline)| (name.as_str(), outline)) + } + + pub fn has(&self, name: &str) -> bool { + self.outlines.contains_key(name) + } + + /// Ink box in staff spaces, y-up. Missing glyphs report an empty box at the + /// origin so callers never have to special-case a font gap. + pub fn bbox(&self, name: &str) -> GlyphBox { + self.metrics + .get(name) + .and_then(|metrics| metrics.bbox) + .unwrap_or(GlyphBox { + min_x: 0.0, + min_y: 0.0, + max_x: 0.0, + max_y: 0.0, + }) + } + + /// Advance width in staff spaces, falling back to the ink width. + pub fn advance(&self, name: &str) -> f64 { + let metrics = self.metrics.get(name); + metrics + .and_then(|metrics| metrics.advance) + .or_else(|| metrics.and_then(|metrics| metrics.bbox).map(GlyphBox::width)) + .unwrap_or(0.0) + } + + /// Where an up-stem meets this notehead, in staff spaces from the origin. + pub fn stem_up_se(&self, name: &str) -> (f64, f64) { + self.metrics + .get(name) + .and_then(|metrics| metrics.stem_up_se) + .unwrap_or_else(|| (self.bbox(name).max_x, 0.168)) + } + + /// Where a down-stem meets this notehead, in staff spaces from the origin. + pub fn stem_down_nw(&self, name: &str) -> (f64, f64) { + self.metrics + .get(name) + .and_then(|metrics| metrics.stem_down_nw) + .unwrap_or_else(|| (self.bbox(name).min_x, -0.168)) + } +} + +/// The process-wide music font, loaded once on first use. +/// The font's identity without the absolute path — a dialog line, not a log. +pub fn music_font_summary() -> String { + let source = music_font().source(); + match source.split_once(" from ") { + Some((name, _path)) => name.to_string(), + None => source.to_string(), + } +} + +/// A music font compiled into the application, used when no file is found. +/// +/// The search paths come first, so a reader who wants a different SMuFL font +/// still gets one by pointing `MAKEPAD_SCORE_MUSIC_FONT` at it. This is the +/// floor: an application that ships its notation font renders notation +/// wherever it is run from, rather than only inside a checkout that happens to +/// have the font lying beside it. +static EMBEDDED: OnceLock = OnceLock::new(); +static MUSIC_FONT: OnceLock = OnceLock::new(); + +#[derive(Clone, Copy)] +pub struct EmbeddedFont { + pub name: &'static str, + pub otf: &'static [u8], + pub metadata: Option<&'static [u8]>, + pub glyphnames: Option<&'static [u8]>, +} + +/// Register the font the binary carries. Call before the first draw; later +/// calls are ignored, because the font is resolved once. +pub fn set_embedded_music_font(font: EmbeddedFont) { + let _ = EMBEDDED.set(font); +} + +/// The bundled SMuFL face and its metadata. +#[cfg(feature = "embed-bravura")] +pub fn bravura() -> EmbeddedFont { + EmbeddedFont { + name: "Bravura", + otf: include_bytes!("../resources/fonts/bravura.otf"), + metadata: Some(include_bytes!("../resources/fonts/bravura_metadata.json")), + glyphnames: Some(include_bytes!("../resources/fonts/glyphnames.json")), + } +} + +/// Install the bundled face as the fallback before the font is first resolved. +#[cfg(feature = "embed-bravura")] +pub fn ensure_default_font() { + if MUSIC_FONT.get().is_none() && EMBEDDED.get().is_none() { + set_embedded_music_font(bravura()); + } +} + +/// Without the embedding feature, callers still have a portable no-op hook. +#[cfg(not(feature = "embed-bravura"))] +pub fn ensure_default_font() {} + +pub fn music_font() -> &'static MusicFont { + MUSIC_FONT.get_or_init(|| { + let font = load_music_font(); + // One line, whichever way it went: a missing font is a degraded look, + // never a failed start. + println!("[score] music font: {}", font.source); + font + }) +} + +/// Where a music font is looked for, in order: +/// +/// 1. `$MAKEPAD_SCORE_MUSIC_FONT` — a full path to an `.otf`/`.ttf`. +/// 2. `$MAKEPAD_SCORE_FONT_DIR`, then a `resources/fonts` directory beside the +/// executable (including the macOS `../Resources/fonts` bundle location). +/// 3. `local/score-corpus/fonts` in the development checkout, found by walking +/// up from both the working directory and the executable. +fn search_paths() -> Vec { + let mut paths = Vec::new(); + if let Some(path) = std::env::var_os("MAKEPAD_SCORE_MUSIC_FONT") { + paths.push(PathBuf::from(path)); + } + let mut directories: Vec = Vec::new(); + if let Some(directory) = std::env::var_os("MAKEPAD_SCORE_FONT_DIR") { + directories.push(PathBuf::from(directory)); + } + let exe = std::env::current_exe().ok(); + if let Some(beside) = exe.as_ref().and_then(|exe| exe.parent()) { + directories.push(beside.join("resources/fonts")); + directories.push(beside.join("../Resources/fonts")); + } + let mut roots: Vec = Vec::new(); + if let Ok(current) = std::env::current_dir() { + roots.extend(current.ancestors().take(6).map(Path::to_path_buf)); + } + if let Some(beside) = exe.as_ref().and_then(|exe| exe.parent()) { + roots.extend(beside.ancestors().take(6).map(Path::to_path_buf)); + } + for root in roots { + directories.push(root.join("resources/fonts")); + directories.push(root.join("local/score-corpus/fonts")); + } + for directory in directories { + for name in ["bravura.otf", "Bravura.otf", "bravura.ttf", "Bravura.ttf"] { + paths.push(directory.join(name)); + } + } + paths +} + +fn load_music_font() -> MusicFont { + for path in search_paths() { + if !path.is_file() { + continue; + } + match load_from_file(&path) { + Ok(font) => return font, + Err(reason) => { + println!("[score] music font at {} unusable: {reason}", path.display()); + } + } + } + if let Some(embedded) = EMBEDDED.get() { + match load_from_bytes( + embedded.otf, + embedded.metadata, + embedded.glyphnames, + &format!("{} (built in)", embedded.name), + ) { + Ok(font) => return font, + Err(reason) => println!("[score] built-in music font unusable: {reason}"), + } + } + fallback_font() +} + +fn load_from_file(path: &Path) -> Result { + let bytes = std::fs::read(path).map_err(|error| error.to_string())?; + let registry = read_json(&metadata_candidates(path, "glyphnames.json")); + let metadata = read_json(&metadata_candidates(path, "metadata.json")); + load_font( + &bytes, + metadata.as_deref(), + registry.as_deref(), + path.parent().unwrap_or_else(|| Path::new(".")), + &path.display().to_string(), + ) +} + +/// The same load, from bytes the binary carries rather than a file. +fn load_from_bytes( + otf: &[u8], + metadata: Option<&[u8]>, + glyphnames: Option<&[u8]>, + source: &str, +) -> Result { + load_font(otf, metadata, glyphnames, Path::new("."), source) +} + +fn load_font( + bytes: &[u8], + metadata_json: Option<&[u8]>, + glyphnames_json: Option<&[u8]>, + directory: &Path, + source: &str, +) -> Result { + let face = ttf_parser::Face::parse(bytes, 0).map_err(|error| error.to_string())?; + let units_per_em = face.units_per_em(); + if units_per_em == 0 { + return Err("font has a zero-sized em square".into()); + } + + let registry = glyphnames_json.and_then(|bytes| GlyphRegistry::from_bytes(bytes).ok()); + let metadata = metadata_json.and_then(|bytes| FontMetadata::from_bytes(bytes).ok()); + + let mut outlines = BTreeMap::new(); + let mut metrics: BTreeMap = BTreeMap::new(); + for name in repertoire() { + let codepoint = registry + .as_ref() + .and_then(|registry| registry.codepoint_for_name(&name)); + let glyph = codepoint + .and_then(|codepoint| face.glyph_index(codepoint)) + .or_else(|| face.glyph_index_by_name(&name)); + let Some(glyph) = glyph else { continue }; + let mut builder = OutlineCollector::default(); + if face.outline_glyph(glyph, &mut builder).is_none() || builder.commands.is_empty() { + continue; + } + let entry = metrics.entry(name.clone()).or_default(); + // Prefer the font metadata's published box; otherwise measure the ink. + entry.bbox = Some(builder.bounds(units_per_em)); + entry.advance = face + .glyph_hor_advance(glyph) + .map(|advance| f64::from(advance) * 4.0 / f64::from(units_per_em)); + outlines.insert( + name, + GlyphOutline { + units_per_em, + commands: Arc::from(builder.commands), + }, + ); + } + if outlines.is_empty() { + return Err("no SMuFL glyphs found in the font".into()); + } + + let mut engraving = Engraving::default(); + if let Some(metadata) = &metadata { + let defaults = &metadata.engraving_defaults; + engraving = Engraving { + staff_line_thickness: defaults.staff_line_thickness.get(), + stem_thickness: defaults.stem_thickness.get(), + beam_thickness: defaults.beam_thickness.get(), + beam_spacing: defaults.beam_spacing.get(), + leger_line_thickness: defaults.leger_line_thickness.get(), + leger_line_extension: defaults.leger_line_extension.get(), + thin_barline_thickness: defaults.thin_barline_thickness.get(), + thick_barline_thickness: defaults.thick_barline_thickness.get(), + bracket_thickness: defaults.bracket_thickness.get(), + }; + for (name, entry) in metrics.iter_mut() { + if let Some(bbox) = metadata.glyph_bboxes.get(name) { + entry.bbox = Some(GlyphBox { + min_x: bbox.south_west.x.get(), + min_y: bbox.south_west.y.get(), + max_x: bbox.north_east.x.get(), + max_y: bbox.north_east.y.get(), + }); + } + if let Some(advance) = metadata.glyph_advance_widths.get(name) { + entry.advance = Some(advance.get()); + } + if let Some(anchors) = metadata.glyphs_with_anchors.get(name) { + entry.stem_up_se = anchors + .stem_up_se + .map(|point| (point.x.get(), point.y.get())); + entry.stem_down_nw = anchors + .stem_down_nw + .map(|point| (point.x.get(), point.y.get())); + } + } + } + + let font_name = metadata + .as_ref() + .and_then(|metadata| metadata.font_name.clone()) + .unwrap_or_else(|| "music font".to_string()); + let _ = directory; + Ok(MusicFont { + source: format!( + "{font_name} ({} glyphs, upem {units_per_em}) from {source}{}", + outlines.len(), + if metadata.is_some() { + "" + } else { + " [no metadata json; using built-in engraving defaults]" + } + ), + real: true, + units_per_em, + engraving, + outlines, + metrics, + }) +} + +/// Metadata lives beside the font: `bravura.otf` -> `bravura_metadata.json`. +fn metadata_candidates(font: &Path, suffix: &str) -> Vec { + let directory = font.parent().unwrap_or_else(|| Path::new(".")).to_path_buf(); + let stem = font + .file_stem() + .and_then(|stem| stem.to_str()) + .unwrap_or_default() + .to_ascii_lowercase(); + let mut candidates = Vec::new(); + if suffix == "metadata.json" { + candidates.push(directory.join(format!("{stem}_metadata.json"))); + candidates.push(directory.join("metadata.json")); + } else { + candidates.push(directory.join(suffix)); + } + candidates +} + +fn read_json(candidates: &[PathBuf]) -> Option> { + candidates + .iter() + .find_map(|path| std::fs::read(path).ok()) +} + +#[derive(Default)] +struct OutlineCollector { + commands: Vec, + min_x: f32, + min_y: f32, + max_x: f32, + max_y: f32, + started: bool, +} + +impl OutlineCollector { + fn include(&mut self, x: f32, y: f32) { + if !self.started { + self.min_x = x; + self.min_y = y; + self.max_x = x; + self.max_y = y; + self.started = true; + return; + } + self.min_x = self.min_x.min(x); + self.min_y = self.min_y.min(y); + self.max_x = self.max_x.max(x); + self.max_y = self.max_y.max(y); + } + + fn bounds(&self, units_per_em: u16) -> GlyphBox { + let scale = 4.0 / f64::from(units_per_em); + GlyphBox { + min_x: f64::from(self.min_x) * scale, + min_y: f64::from(self.min_y) * scale, + max_x: f64::from(self.max_x) * scale, + max_y: f64::from(self.max_y) * scale, + } + } +} + +impl ttf_parser::OutlineBuilder for OutlineCollector { + fn move_to(&mut self, x: f32, y: f32) { + self.include(x, y); + self.commands.push(GlyphOutlineCommand::MoveTo(x, y)); + } + + fn line_to(&mut self, x: f32, y: f32) { + self.include(x, y); + self.commands.push(GlyphOutlineCommand::LineTo(x, y)); + } + + fn quad_to(&mut self, cx: f32, cy: f32, x: f32, y: f32) { + self.include(x, y); + self.commands.push(GlyphOutlineCommand::QuadTo(cx, cy, x, y)); + } + + fn curve_to(&mut self, c1x: f32, c1y: f32, c2x: f32, c2y: f32, x: f32, y: f32) { + self.include(x, y); + self.commands + .push(GlyphOutlineCommand::CubicTo(c1x, c1y, c2x, c2y, x, y)); + } + + fn close(&mut self) { + self.commands.push(GlyphOutlineCommand::Close); + } +} + +/// The working repertoire, as canonical SMuFL names derived from [`Symbol`]. +fn repertoire() -> Vec { + let mut names: Vec = Vec::new(); + let mut push = |symbol: Symbol| names.push(symbol.canonical_name().to_string()); + + const NOTEHEAD_DURATIONS: [NoteheadDuration; 4] = [ + NoteheadDuration::DoubleWhole, + NoteheadDuration::Whole, + NoteheadDuration::Half, + NoteheadDuration::Black, + ]; + const NOTEHEAD_SHAPES: [NoteheadShape; 4] = [ + NoteheadShape::Normal, + NoteheadShape::X, + NoteheadShape::Diamond, + NoteheadShape::Slash, + ]; + for shape in NOTEHEAD_SHAPES { + for duration in NOTEHEAD_DURATIONS { + push(Symbol::Notehead { duration, shape }); + } + } + for duration in [ + RestDuration::Maxima, + RestDuration::Longa, + RestDuration::DoubleWhole, + RestDuration::Whole, + RestDuration::Half, + RestDuration::Quarter, + RestDuration::Eighth, + RestDuration::Sixteenth, + RestDuration::ThirtySecond, + RestDuration::SixtyFourth, + RestDuration::OneTwentyEighth, + ] { + push(Symbol::Rest(duration)); + } + for accidental in [ + Accidental::TripleFlat, + Accidental::DoubleFlat, + Accidental::Flat, + Accidental::Natural, + Accidental::Sharp, + Accidental::DoubleSharp, + Accidental::TripleSharp, + Accidental::NaturalFlat, + Accidental::NaturalSharp, + Accidental::QuarterToneFlat, + Accidental::ThreeQuarterTonesFlat, + Accidental::QuarterToneSharp, + Accidental::ThreeQuarterTonesSharp, + ] { + push(Symbol::Accidental(accidental)); + } + for clef in [ + Clef::G, + Clef::G8va, + Clef::G8vb, + Clef::G15ma, + Clef::G15mb, + Clef::F, + Clef::F8va, + Clef::F8vb, + Clef::F15ma, + Clef::F15mb, + Clef::C, + Clef::Percussion, + Clef::PercussionAlternate, + Clef::Tab4String, + Clef::Tab6String, + ] { + push(Symbol::Clef(clef)); + } + for duration in [ + FlagDuration::Eighth, + FlagDuration::Sixteenth, + FlagDuration::ThirtySecond, + FlagDuration::SixtyFourth, + FlagDuration::OneTwentyEighth, + ] { + for direction in [Direction::Up, Direction::Down] { + push(Symbol::Flag { + duration, + direction, + }); + } + } + for articulation in [ + Articulation::Accent, + Articulation::Staccato, + Articulation::Tenuto, + Articulation::Staccatissimo, + Articulation::Marcato, + Articulation::LaissezVibrer, + Articulation::Stress, + Articulation::SoftAccent, + Articulation::AccentStaccato, + Articulation::TenutoStaccato, + Articulation::MarcatoStaccato, + Articulation::MarcatoTenuto, + ] { + for placement in [Placement::Above, Placement::Below] { + push(Symbol::Articulation { + articulation, + placement, + }); + } + } + for dynamic in [ + DynamicMark::Piano, + DynamicMark::Pianissimo, + DynamicMark::Pianississimo, + DynamicMark::Pianissississimo, + DynamicMark::MezzoPiano, + DynamicMark::MezzoForte, + DynamicMark::Forte, + DynamicMark::Fortissimo, + DynamicMark::Fortississimo, + DynamicMark::Fortissississimo, + DynamicMark::FortePiano, + DynamicMark::Sforzando, + DynamicMark::SforzandoPiano, + DynamicMark::Sforzato, + DynamicMark::Rinforzando, + DynamicMark::Niente, + DynamicMark::Mezzo, + DynamicMark::Z, + ] { + push(Symbol::Dynamic(dynamic)); + } + const DIGITS: [Digit; 10] = [ + Digit::Zero, + Digit::One, + Digit::Two, + Digit::Three, + Digit::Four, + Digit::Five, + Digit::Six, + Digit::Seven, + Digit::Eight, + Digit::Nine, + ]; + for digit in DIGITS { + push(Symbol::TimeSignatureDigit(digit)); + push(Symbol::TupletDigit(digit)); + } + push(Symbol::TimeSignatureCommon); + push(Symbol::TimeSignatureCutCommon); + for ornament in [ + Ornament::Trill, + Ornament::Turn, + Ornament::InvertedTurn, + Ornament::TurnWithSlash, + Ornament::Mordent, + Ornament::ShortTrill, + Ornament::Tremblement, + Ornament::Schleifer, + ] { + push(Symbol::Ornament(ornament)); + } + for shape in [ + FermataShape::Normal, + FermataShape::Short, + FermataShape::Long, + FermataShape::VeryShort, + FermataShape::VeryLong, + ] { + for placement in [Placement::Above, Placement::Below] { + push(Symbol::Fermata { shape, placement }); + } + } + for strokes in [ + TremoloStrokes::One, + TremoloStrokes::Two, + TremoloStrokes::Three, + TremoloStrokes::Four, + TremoloStrokes::Five, + ] { + push(Symbol::Tremolo(strokes)); + } + push(Symbol::AugmentationDot); + push(Symbol::RepeatDot); + push(Symbol::Segno); + push(Symbol::Coda); + push(Symbol::BreathMark); + push(Symbol::Caesura); + push(Symbol::Arpeggio(Direction::Up)); + push(Symbol::Arpeggio(Direction::Down)); + for extra in ["brace", "bracket", "restHBar", "noteheadWholeFilled"] { + names.push(extra.to_string()); + } + names.sort(); + names.dedup(); + names +} + +// --------------------------------------------------------------------------- +// Fallback: hand-drawn outlines, fitted to Bravura's published bounding boxes +// so a checkout without a music font still engraves at the right size. +// --------------------------------------------------------------------------- + +const FALLBACK_UNITS_PER_EM: u16 = 1000; + +fn fallback_font() -> MusicFont { + let mut outlines = BTreeMap::new(); + let mut metrics = BTreeMap::new(); + for (name, commands, bbox) in [ + ( + "noteheadBlack", + notehead_shape(), + GlyphBox { + min_x: 0.0, + min_y: -0.5, + max_x: 1.18, + max_y: 0.5, + }, + ), + ( + "noteheadHalf", + notehead_shape(), + GlyphBox { + min_x: 0.0, + min_y: -0.5, + max_x: 1.18, + max_y: 0.5, + }, + ), + ( + "noteheadWhole", + notehead_shape(), + GlyphBox { + min_x: 0.0, + min_y: -0.5, + max_x: 1.688, + max_y: 0.5, + }, + ), + ( + "augmentationDot", + dot_shape(), + GlyphBox { + min_x: 0.0, + min_y: -0.1, + max_x: 0.2, + max_y: 0.1, + }, + ), + ( + "gClef", + g_clef_shape(), + GlyphBox { + min_x: 0.0, + min_y: -2.632, + max_x: 2.684, + max_y: 4.392, + }, + ), + ( + "fClef", + f_clef_shape(), + GlyphBox { + min_x: 0.0, + min_y: -1.0, + max_x: 2.736, + max_y: 2.72, + }, + ), + ] { + outlines.insert(name.to_string(), fit_outline(commands, bbox)); + metrics.insert( + name.to_string(), + GlyphMetrics { + bbox: Some(bbox), + advance: Some(bbox.width()), + stem_up_se: Some((bbox.max_x, 0.168)), + stem_down_nw: Some((bbox.min_x, -0.168)), + }, + ); + } + MusicFont { + source: "hand-drawn fallback outlines (no SMuFL font found; \ + set MAKEPAD_SCORE_MUSIC_FONT or place bravura.otf in resources/fonts)" + .to_string(), + real: false, + units_per_em: FALLBACK_UNITS_PER_EM, + engraving: Engraving::default(), + outlines, + metrics, + } +} + +/// Maps a hand-drawn path onto a target staff-space box, so the fallback lands +/// at exactly the size the engraver expects of the real glyph. +fn fit_outline(commands: Vec, target: GlyphBox) -> GlyphOutline { + let mut min_x = f32::INFINITY; + let mut min_y = f32::INFINITY; + let mut max_x = f32::NEG_INFINITY; + let mut max_y = f32::NEG_INFINITY; + let mut visit = |x: f32, y: f32| { + min_x = min_x.min(x); + min_y = min_y.min(y); + max_x = max_x.max(x); + max_y = max_y.max(y); + }; + for command in &commands { + match *command { + GlyphOutlineCommand::MoveTo(x, y) | GlyphOutlineCommand::LineTo(x, y) => visit(x, y), + GlyphOutlineCommand::QuadTo(_, _, x, y) => visit(x, y), + GlyphOutlineCommand::CubicTo(_, _, _, _, x, y) => visit(x, y), + GlyphOutlineCommand::Close => {} + } + } + let units = f32::from(FALLBACK_UNITS_PER_EM) / 4.0; + let scale_x = if max_x > min_x { + (target.width() as f32) * units / (max_x - min_x) + } else { + 1.0 + }; + let scale_y = if max_y > min_y { + (target.height() as f32) * units / (max_y - min_y) + } else { + 1.0 + }; + let map = |x: f32, y: f32| { + ( + (x - min_x) * scale_x + target.min_x as f32 * units, + (y - min_y) * scale_y + target.min_y as f32 * units, + ) + }; + let mapped = commands + .into_iter() + .map(|command| match command { + GlyphOutlineCommand::MoveTo(x, y) => { + let (x, y) = map(x, y); + GlyphOutlineCommand::MoveTo(x, y) + } + GlyphOutlineCommand::LineTo(x, y) => { + let (x, y) = map(x, y); + GlyphOutlineCommand::LineTo(x, y) + } + GlyphOutlineCommand::QuadTo(cx, cy, x, y) => { + let (cx, cy) = map(cx, cy); + let (x, y) = map(x, y); + GlyphOutlineCommand::QuadTo(cx, cy, x, y) + } + GlyphOutlineCommand::CubicTo(c1x, c1y, c2x, c2y, x, y) => { + let (c1x, c1y) = map(c1x, c1y); + let (c2x, c2y) = map(c2x, c2y); + let (x, y) = map(x, y); + GlyphOutlineCommand::CubicTo(c1x, c1y, c2x, c2y, x, y) + } + GlyphOutlineCommand::Close => GlyphOutlineCommand::Close, + }) + .collect::>(); + GlyphOutline { + units_per_em: FALLBACK_UNITS_PER_EM, + commands: Arc::from(mapped), + } +} + +fn notehead_shape() -> Vec { + use GlyphOutlineCommand::*; + vec![ + MoveTo(-520.0, -90.0), + CubicTo(-430.0, 260.0, 180.0, 430.0, 470.0, 190.0), + CubicTo(760.0, -50.0, 470.0, -390.0, 20.0, -420.0), + CubicTo(-410.0, -450.0, -610.0, -280.0, -520.0, -90.0), + Close, + ] +} + +fn dot_shape() -> Vec { + use GlyphOutlineCommand::*; + vec![ + MoveTo(-180.0, 0.0), + CubicTo(-180.0, 110.0, -100.0, 180.0, 0.0, 180.0), + CubicTo(110.0, 180.0, 180.0, 100.0, 180.0, 0.0), + CubicTo(180.0, -110.0, 100.0, -180.0, 0.0, -180.0), + CubicTo(-110.0, -180.0, -180.0, -100.0, -180.0, 0.0), + Close, + ] +} + +fn g_clef_shape() -> Vec { + use GlyphOutlineCommand::*; + vec![ + MoveTo(80.0, 660.0), + CubicTo(-300.0, 450.0, -360.0, 80.0, -80.0, -110.0), + CubicTo(210.0, -305.0, 490.0, -100.0, 335.0, 125.0), + CubicTo(215.0, 300.0, -30.0, 230.0, -35.0, 75.0), + CubicTo(-35.0, -20.0, 85.0, -55.0, 145.0, 15.0), + CubicTo(280.0, 175.0, 70.0, 305.0, -95.0, 220.0), + CubicTo(-360.0, 85.0, -270.0, -300.0, 65.0, -350.0), + LineTo(115.0, -800.0), + LineTo(245.0, -790.0), + LineTo(180.0, -335.0), + CubicTo(540.0, -210.0, 560.0, 250.0, 230.0, 430.0), + CubicTo(145.0, 480.0, 120.0, 590.0, 80.0, 660.0), + Close, + ] +} + +fn f_clef_shape() -> Vec { + use GlyphOutlineCommand::*; + vec![ + MoveTo(-430.0, 240.0), + CubicTo(-210.0, 570.0, 330.0, 470.0, 390.0, 90.0), + CubicTo(450.0, -300.0, 120.0, -550.0, -260.0, -430.0), + CubicTo(20.0, -300.0, 160.0, -90.0, 105.0, 120.0), + CubicTo(45.0, 340.0, -190.0, 390.0, -430.0, 240.0), + Close, + MoveTo(560.0, 210.0), + LineTo(760.0, 210.0), + LineTo(760.0, 410.0), + LineTo(560.0, 410.0), + Close, + MoveTo(560.0, -190.0), + LineTo(760.0, -190.0), + LineTo(760.0, 10.0), + LineTo(560.0, 10.0), + Close, + ] +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn repertoire_covers_the_working_symbols() { + let names = repertoire(); + for expected in [ + "noteheadBlack", + "noteheadHalf", + "noteheadWhole", + "restQuarter", + "rest8th", + "accidentalSharp", + "accidentalFlat", + "accidentalNatural", + "accidentalDoubleSharp", + "gClef", + "fClef", + "cClef", + "gClef8vb", + "flag8thUp", + "flag32ndDown", + "augmentationDot", + "timeSig4", + "articStaccatoAbove", + "articAccentBelow", + "fermataAbove", + ] { + assert!(names.iter().any(|name| name == expected), "missing {expected}"); + } + } + + #[test] + fn fallback_notehead_is_one_staff_space_tall() { + let font = fallback_font(); + let bbox = font.bbox("noteheadBlack"); + assert!((bbox.height() - 1.0).abs() < 1e-9); + assert!((bbox.width() - 1.18).abs() < 1e-9); + let outline = font.outlines.get("noteheadBlack").unwrap(); + let mut min_y = f32::INFINITY; + let mut max_y = f32::NEG_INFINITY; + for command in outline.commands.iter() { + if let GlyphOutlineCommand::CubicTo(_, _, _, _, _, y) | GlyphOutlineCommand::MoveTo(_, y) = + command + { + min_y = min_y.min(*y); + max_y = max_y.max(*y); + } + } + // 1000 units per em, four staff spaces to the em: 250 units tall. + assert!((max_y - min_y - 250.0).abs() < 1.0, "{min_y}..{max_y}"); + } + + #[test] + fn the_shipped_font_loads_when_present() { + let font = load_music_font(); + println!("music font source: {}", font.source()); + if !font.is_real() { + return; + } + let bbox = font.bbox("noteheadBlack"); + assert!((bbox.height() - 1.0).abs() < 0.02, "{bbox:?}"); + assert!((bbox.width() - 1.18).abs() < 0.05, "{bbox:?}"); + assert!(font.has("restQuarter")); + assert!(font.has("accidentalSharp")); + assert!(font.has("flag8thUp")); + assert!(font.engraving().beam_thickness > 0.0); + } +} diff --git a/libs/score_view/src/lib.rs b/libs/score_view/src/lib.rs new file mode 100644 index 000000000..d29a5f521 --- /dev/null +++ b/libs/score_view/src/lib.rs @@ -0,0 +1,27 @@ +//! Playback-free score engraving, retained pages, score builders, and a lean widget. + +pub use makepad_widgets; + +pub mod build; +pub mod document; +pub mod engrave; +pub mod font; +pub mod spacing; +mod title; +pub mod view; + +pub use build::*; +pub use document::*; +pub use font::{ + ensure_default_font, music_font, music_font_summary, set_embedded_music_font, EmbeddedFont, +}; +#[cfg(feature = "embed-bravura")] +pub use font::bravura; +pub use view::*; + +use makepad_widgets::ScriptVm; + +/// Register the draw-only score widget. +pub fn script_mod(vm: &mut ScriptVm) { + view::script_mod(vm); +} diff --git a/libs/score_view/src/spacing.rs b/libs/score_view/src/spacing.rs new file mode 100644 index 000000000..41d83b155 --- /dev/null +++ b/libs/score_view/src/spacing.rs @@ -0,0 +1,1053 @@ +//! Horizontal spacing and page planning. +//! +//! This is the seam between the semantic score and +//! [`makepad_score_layout`]'s constrained spring-and-rod solver. Nothing here +//! decides *how* to space music — the kernel does that — but everything here +//! decides *what the music actually is*, in numbers the kernel understands: +//! +//! * a **column** is one onset, a moment where something starts, merged +//! across every voice and both staves of the grand staff so the two hands +//! line up vertically; +//! * its **spring** (`natural`) is its duration run through the kernel's +//! duration curve, so a sixteenth asks for less room than a half note but +//! not sixteen times less; +//! * its **rod** (`minimum`) is measured ink: the real Bravura advance widths +//! of the noteheads at that onset, the second-interval head shift, the +//! augmentation dots, the accidentals hanging off the *next* column, and +//! the barline where the measure ends. +//! +//! The kernel then solves each system's chain to the system width and breaks +//! the measure list into systems and the systems into pages; this module +//! turns the solved widths back into page coordinates the engraver draws at. +//! +//! # Why these flexibilities +//! +//! A column's width under force `F` is `rod + I*q(d)*(1 + F)`: both the +//! stretch and the shrink flexibility are set to the column's *duration +//! space* `I*q(d)`, with `headroom` set to the rod. Three properties follow, +//! and they are exactly the classical engraving behaviour: +//! +//! 1. Ink never scales. Justifying a system moves whitespace around; it never +//! inflates or squeezes a notehead's own advance. +//! 2. Whitespace scales in proportion to duration space, so a system that has +//! to stretch keeps the *ratios* between a sixteenth's gap and a half +//! note's gap. That proportional invariance is what reads as "engraved". +//! 3. `F = -1` is exactly the point where all whitespace is gone and every +//! rod is touching. Since [`makepad_score_layout::BreakStyle::min_ratio`] +//! is `-1`, the line breaker's feasibility test and the spacing model's +//! collision limit become the same statement, with no fudge factor. + +use crate::document::PAGE_WIDTH_SP; +use crate::engrave::{ + measure_staff_columns, Column, MARGIN_LEFT, MARGIN_RIGHT, STAFF_SPAN, +}; +use crate::font::{music_font, MusicFont}; +use makepad_score::model::{KeySignature, Measure, MeasureId, Meter, Rational, Score, ScoreTime}; +use makepad_score_layout::{ + break_pages, BreakRule, DistanceStyle, IncrementalLayout, LayoutStyle, LineWidths, + MeasureSource, PageSpec, RelayoutStats, Sp, SpacingColumn, SystemLayout, SystemVertical, + TurnRule, +}; +use std::{collections::BTreeMap, ops::Range}; + +/// Page y of the top of the first system's block (its ink, not its staff). +const PAGE_MUSIC_TOP: f64 = 28.0; +/// Page y below which nothing but the folio may be printed. +const PAGE_MUSIC_BOTTOM: f64 = 222.0; + +/// One placed onset column: where its noteheads' left edges go. +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct ColumnPlacement { + /// Absolute score time of the onset. + pub onset: ScoreTime, + /// Page x of the unshifted notehead's left edge. + pub x: f64, +} + +/// One placed measure. +#[derive(Clone, Debug)] +pub struct MeasurePlacement { + pub measure: MeasureId, + /// Index in score order. + pub index: usize, + /// Page x of the measure's left boundary (the opening barline). + pub left: f64, + /// Page x of the measure's closing barline. + pub right: f64, + /// Onset columns in time order. + pub columns: Vec, +} + +impl MeasurePlacement { + /// Page x for an onset, or the measure's left boundary when the onset is + /// not a column of this measure (which the engraver never asks for). + pub fn x_of(&self, onset: ScoreTime) -> f64 { + self.columns + .iter() + .find(|column| column.onset == onset) + .map(|column| column.x) + .unwrap_or(self.left) + } + + /// Page x for a point in time inside the measure, interpolated between + /// the columns that bracket it. Used by the playback cursor. + pub fn x_at(&self, whole: f64, measure_start: f64, measure_end: f64) -> f64 { + let time = whole.clamp(measure_start, measure_end); + let mut previous = (measure_start, self.left); + for column in &self.columns { + let at = rational_f64(column.onset.0); + if at > time + 1e-12 { + let span = (at - previous.0).max(1e-9); + let t = ((time - previous.0) / span).clamp(0.0, 1.0); + return previous.1 + (column.x - previous.1) * t; + } + previous = (at, column.x); + } + let span = (measure_end - previous.0).max(1e-9); + let t = ((time - previous.0) / span).clamp(0.0, 1.0); + previous.1 + (self.right - previous.1) * t + } +} + +/// One placed system. +#[derive(Clone, Debug)] +pub struct SystemPlacement { + /// Page y of the top staff line of the upper staff. + pub top: f64, + /// Page y of the bottom staff line of the lower staff. + pub bottom: f64, + /// Page x where this system's music starts. + pub music_left: f64, + /// Page x of the system's right edge. + pub right: f64, + /// True for the system carrying the score's first measure. + pub show_meter: bool, + pub measures: Vec, +} + +/// A moment in the score, resolved to the page. +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct CursorLocation { + pub page: usize, + pub x_sp: f64, + pub top_sp: f64, + pub bottom_sp: f64, +} + +/// How far above and below the staves the playback cursor reaches, so it +/// clears ledger lines and stems without touching the neighbouring system. +const CURSOR_SYSTEM_PAD: f64 = 3.0; + +/// One placed page. +#[derive(Clone, Debug, Default)] +pub struct PagePlacement { + pub systems: Vec, +} + +/// Which pages a relayout invalidated. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum PagesDirty { + /// The break structure moved: everything must be repainted. + All, + /// Only these pages changed. + Only(Vec), +} + +/// Cached per-measure spacing input, kept beside the kernel's own cache so a +/// one-measure edit re-measures one measure's ink rather than the score's. +#[derive(Clone, Debug, Default)] +struct MeasureCache { + /// The onsets, in time order, matching `source.columns` one for one. + onsets: Vec, + /// Distance from this measure's closing barline back to the next + /// measure's first column. + lead_after: f64, + /// Ink reach above the upper staff's top line, in staff spaces. + above: f64, + /// Ink reach below the lower staff's bottom line. + below: f64, +} + +/// The document's horizontal spacing and page plan. +pub struct ScoreSpacing { + style: LayoutStyle, + page_width: f64, + staff_span: f64, + incremental: IncrementalLayout, + sources: Vec, + cache: Vec, + measure_ids: Vec, + /// Page x where music starts on a system that shows no time signature. + music_left: f64, + /// Page x where music starts on the score's very first system. + music_left_first: f64, + /// Whether the first percussion system reserves a drum-key column. + drum_key: bool, + widths: LineWidths, + systems: Vec, + pages: Vec, + /// Which systems each page carries, with its vertical adjustment ratio. + page_fills: Vec<(Range, f64)>, + /// Page index of every measure, by score order. + measure_page: Vec, + stats: RelayoutStats, +} + +impl Default for ScoreSpacing { + fn default() -> Self { + Self::new() + } +} + +impl ScoreSpacing { + pub fn new() -> Self { + Self { + style: LayoutStyle::default(), + page_width: PAGE_WIDTH_SP, + staff_span: STAFF_SPAN, + incremental: IncrementalLayout::new(), + sources: Vec::new(), + cache: Vec::new(), + measure_ids: Vec::new(), + music_left: MARGIN_LEFT + 8.0, + music_left_first: MARGIN_LEFT + 8.0, + drum_key: false, + widths: LineWidths::uniform(Sp(1.0)), + systems: Vec::new(), + pages: Vec::new(), + page_fills: Vec::new(), + measure_page: Vec::new(), + stats: RelayoutStats::default(), + } + } + + pub fn style(&self) -> &LayoutStyle { + &self.style + } + + pub fn set_page_width(&mut self, page_width: f64) { + self.page_width = page_width.max(MARGIN_LEFT + MARGIN_RIGHT + 1.0); + } + + pub fn set_drum_key(&mut self, drum_key: bool) { + self.drum_key = drum_key; + } + + pub fn pages(&self) -> &[PagePlacement] { + &self.pages + } + + pub fn page_count(&self) -> usize { + self.pages.len() + } + + /// Page width that lets every measured bar sit on one system at its + /// natural spring widths. Content-fit views use this as their widest + /// useful reflow candidate; making the page wider would only add ragged + /// paper after the final bar. + pub(crate) fn natural_page_width(&self) -> f64 { + let lead = self.style.distance.barline_to_note.0; + let natural: f64 = self + .sources + .iter() + .flat_map(|source| &source.columns) + .map(|column| column.natural.0) + .sum(); + (self.music_left_first - lead + natural + MARGIN_RIGHT) + .max(MARGIN_LEFT + MARGIN_RIGHT + 1.0) + } + + pub fn stats(&self) -> RelayoutStats { + self.stats + } + + pub fn page_of_measure(&self, index: usize) -> Option { + self.measure_page.get(index).copied() + } + + /// Where a moment in the score is on the page, for the playback cursor: + /// page index, page x, and the vertical extent of the system it lands in. + /// The system span is what keeps the cursor from ruling the whole sheet. + pub fn locate(&self, score: &Score, whole: f64) -> Option { + let last_index = self.measure_ids.len().checked_sub(1)?; + let index = self.measure_ids.iter().enumerate().position(|(index, id)| { + score.measures.get(id).is_some_and(|measure| { + let start = rational_f64(measure.start.0); + let end = start + rational_f64(measure.extent.0); + whole >= start && (whole < end || (index == last_index && whole == end)) + }) + })?; + let measure = score.measures.get(&self.measure_ids[index])?; + let start = rational_f64(measure.start.0); + let end = start + rational_f64(measure.extent.0); + let page = *self.measure_page.get(index)?; + let system = self + .pages + .get(page)? + .systems + .iter() + .find(|system| system.measures.iter().any(|placement| placement.index == index))?; + let placement = system + .measures + .iter() + .find(|placement| placement.index == index)?; + Some(CursorLocation { + page, + x_sp: placement.x_at(whole, start, end), + top_sp: system.top - CURSOR_SYSTEM_PAD, + bottom_sp: system.bottom + CURSOR_SYSTEM_PAD, + }) + } + + /// Re-measure every measure and lay the whole score out. Used on load and + /// after any edit that can move more than one measure (undo, redo). + pub fn rebuild(&mut self, score: &Score) { + let font = music_font(); + self.staff_span = crate::engrave::score_staff_span(score); + let measures = ordered_measures(score); + self.measure_ids = measures.iter().map(|measure| measure.id).collect(); + // Measure every bar's ink once; a bar's trailing rod needs the next + // bar's leading ink, which is the neighbour in this same list. + let inks: Vec = measures + .iter() + .map(|measure| measure_ink(score, font, measure, &self.style.distance)) + .collect(); + let previous: Vec = self.sources.iter().map(|source| source.revision).collect(); + self.sources.clear(); + self.cache.clear(); + for (index, measure) in measures.iter().enumerate() { + let revision = previous.get(index).copied().unwrap_or(0).wrapping_add(1); + let next_left = leading_ink(inks.get(index + 1)); + let (source, cache) = self.springs(measure, &inks[index], next_left, revision); + self.sources.push(source); + self.cache.push(cache); + } + self.plan_prefix(score, font); + self.relayout(); + self.repaginate(); + } + + /// One measure changed. Re-measures that measure (and its predecessor, + /// whose trailing rod reaches across the barline into it), then asks the + /// kernel for the cheapest relayout it can get away with. + pub fn touch_measure(&mut self, score: &Score, index: usize) -> PagesDirty { + if index >= self.sources.len() { + self.rebuild(score); + return PagesDirty::All; + } + let font = music_font(); + let measures = ordered_measures(score); + let mut touched = vec![index]; + if index > 0 { + touched.insert(0, index - 1); + } + for &at in &touched { + let revision = self.sources[at].revision.wrapping_add(1); + let Some(measure) = measures.get(at) else { continue }; + let ink = measure_ink(score, font, measure, &self.style.distance); + let next_left = leading_ink( + measures + .get(at + 1) + .map(|next| measure_ink(score, font, next, &self.style.distance)) + .as_ref(), + ); + let (source, cache) = self.springs(measure, &ink, next_left, revision); + // The predecessor is only really dirty when the edit changed the + // ink its trailing rod reaches into, so compare before bumping. + if at != index + && source.columns == self.sources[at].columns + && source.break_right == self.sources[at].break_right + { + continue; + } + self.sources[at] = source; + self.cache[at] = cache; + } + let prefix_before = self.music_left_first; + self.plan_prefix(score, font); + let before: Vec> = self.systems.iter().map(|s| s.measures.clone()).collect(); + self.relayout(); + let after: Vec> = self.systems.iter().map(|s| s.measures.clone()).collect(); + if before != after || self.music_left_first != prefix_before { + self.repaginate(); + return PagesDirty::All; + } + // Same breaks: only the pages carrying a re-solved system move. + let mut dirty: Vec = touched + .iter() + .filter_map(|&at| self.measure_page.get(at).copied()) + .collect(); + dirty.sort_unstable(); + dirty.dedup(); + for &page in &dirty { + self.place_page(page); + } + PagesDirty::Only(dirty) + } + + /// The kernel's incremental line layout over the cached measure sources. + fn relayout(&mut self) { + self.systems = self + .incremental + .layout(&self.sources, self.widths, &self.style) + .to_vec(); + self.stats = self.incremental.stats(); + } + + /// Where music starts, and therefore how wide a system is. + /// + /// The clef and key signature are drawn at every system start, so their + /// width comes off every system; the time signature is drawn once, so it + /// comes off the first system only. The key allowance is the *widest* + /// key the score uses, which keeps the music left edge aligned down the + /// page even across a key change. + fn plan_prefix(&mut self, score: &Score, font: &'static MusicFont) { + let mut fifths = 0_i8; + for measure in ordered_measures(score) { + if let Some(key) = score.maps.key_at(measure.start, None, None) { + if key.fifths.unsigned_abs() > fifths.unsigned_abs() { + fifths = key.fifths; + } + } + } + let meter = score + .maps + .meter_at(ScoreTime::ZERO, None, None) + .cloned() + .unwrap_or(Meter::Measured { + groups: vec![4], + unit: 4, + }); + let key = KeySignature { fifths, custom: Vec::new() }; + let lead = self.style.distance.barline_to_note.0; + self.music_left = + crate::engrave::prefix_width(font, &key, None, &self.style) + MARGIN_LEFT + lead; + self.music_left_first = + crate::engrave::prefix_width(font, &key, Some(&meter), &self.style) + MARGIN_LEFT + lead; + if self.drum_key { + self.music_left_first += crate::engrave::drum_key_width(score); + } + let right = self.page_width - MARGIN_RIGHT; + // The chain runs from the first column to one `barline_to_note` past + // the closing barline, so solving to this target lands that barline + // exactly on the right edge. + self.widths = LineWidths { + first: Sp(right - self.music_left_first + lead), + rest: Sp(right - self.music_left + lead), + }; + } + + /// Turn one measure's measured ink into springs and rods. + /// + /// `next_left` is the ink the *following* measure's first column hangs + /// left of its notehead — an accidental, say — which this measure's + /// trailing rod has to clear along with the barline. + fn springs( + &self, + measure: &Measure, + ink: &MeasureInk, + next_left: f64, + revision: u64, + ) -> (MeasureSource, MeasureCache) { + let extent = rational_f64(measure.extent.0).max(1e-9); + let start = rational_f64(measure.start.0); + let distance = &self.style.distance; + // The rod has to clear the barline the engraver actually draws, so + // take its thickness from the font's own engraving defaults. + let barline = music_font() + .engraving() + .thin_barline_thickness + .max(self.style.stroke.barline_thin.0); + let lead_after = if next_left > 0.0 { + (distance.barline_to_accidental.0 + next_left).max(distance.barline_to_note.0) + } else { + distance.barline_to_note.0 + }; + + let mut columns = Vec::with_capacity(ink.columns.len().max(1)); + for (at, column) in ink.columns.iter().enumerate() { + let onset = rational_f64(column.onset.0) - start; + let next = ink + .columns + .get(at + 1) + .map(|next| rational_f64(next.onset.0) - start) + .unwrap_or(extent); + // The spring's duration is the interval to the next onset: what + // this column has to *say*, as opposed to what it has to clear. + let duration = (next - onset).max(1.0 / 512.0); + let gap = if at + 1 < ink.columns.len() { + distance.note_to_note_min.0 + ink.columns[at + 1].left + } else { + distance.note_to_barline.0 + barline + lead_after + }; + columns.push(spring(column.right + gap, duration, &self.style)); + } + if columns.is_empty() { + // An empty measure still has to be wide enough to read as one. + columns.push(spring(distance.min_measure_width.0, extent, &self.style)); + } + let cache = MeasureCache { + onsets: ink.columns.iter().map(|column| column.onset).collect(), + lead_after, + above: ink.above, + below: ink.below, + }; + ( + MeasureSource { + revision, + columns, + break_right: BreakRule::Allowed, + spanner_penalty: 0.0, + }, + cache, + ) + } + + /// Stack the systems onto pages and place every column on every page. + fn repaginate(&mut self) { + let verticals: Vec = self + .systems + .iter() + .map(|system| { + let (above, below) = self.system_reach(&system.measures); + SystemVertical { + height: Sp(self.staff_span + above + below), + gap_natural: self.style.vertical.system_distance_min, + gap_min: self.style.vertical.system_distance_min * 0.7, + gap_stretch: self.style.vertical.system_distance_max + - self.style.vertical.system_distance_min, + turn_after: TurnRule::Allowed, + } + }) + .collect(); + let plan = break_pages( + &verticals, + PageSpec { + usable_height: Sp(PAGE_MUSIC_BOTTOM - PAGE_MUSIC_TOP), + }, + &self.style.breaking, + ); + self.pages.clear(); + self.measure_page = vec![0; self.sources.len()]; + // A score with nothing on it still gets one page to put its title on. + let fills: Vec> = if plan.pages.is_empty() { + vec![0..self.systems.len()] + } else { + plan.pages.iter().map(|page| page.systems.clone()).collect() + }; + for (page_index, fill) in fills.iter().enumerate() { + self.pages.push(PagePlacement::default()); + for system in fill.clone() { + for measure in self.systems[system].measures.clone() { + if let Some(slot) = self.measure_page.get_mut(measure) { + *slot = page_index; + } + } + } + } + let adjustments: Vec<(Range, f64)> = fills + .iter() + .cloned() + .zip( + plan.pages + .iter() + .map(|page| if page.justified { page.adjustment } else { 0.0 }) + .chain(std::iter::repeat(0.0)), + ) + .collect(); + self.page_fills = adjustments; + for page in 0..self.pages.len() { + self.place_page(page); + } + } + + fn system_reach(&self, measures: &Range) -> (f64, f64) { + let mut above = 3.0_f64; + let mut below = 3.0_f64; + for index in measures.clone() { + if let Some(cache) = self.cache.get(index) { + above = above.max(cache.above); + below = below.max(cache.below); + } + } + (above.min(14.0), below.min(14.0)) + } + + /// Turn one page's solved column widths into page coordinates. + fn place_page(&mut self, page_index: usize) { + let Some((fill, adjustment)) = self.page_fills.get(page_index).cloned() else { + return; + }; + let mut placed = PagePlacement::default(); + let mut y = PAGE_MUSIC_TOP; + for system_index in fill.clone() { + let system = &self.systems[system_index]; + let (above, below) = self.system_reach(&system.measures); + if system_index != fill.start { + let gap = self.style.vertical.system_distance_min.0 + + adjustment + * (self.style.vertical.system_distance_max.0 + - self.style.vertical.system_distance_min.0); + y += gap; + } + let top = y + above; + y += self.staff_span + above + below; + let show_meter = system.measures.start == 0; + let music_left = if show_meter { + self.music_left_first + } else { + self.music_left + }; + let mut x = music_left; + let mut widths = system.solution.widths.iter().map(|w| w.0); + let mut measures = Vec::with_capacity(system.measures.len()); + // Measure boundaries tile the system: each starts where the + // previous one's barline stands. + let mut left = music_left - self.style.distance.barline_to_note.0; + for index in system.measures.clone() { + let source = &self.sources[index]; + let cache = &self.cache[index]; + let mut columns = Vec::with_capacity(cache.onsets.len()); + for (at, _) in source.columns.iter().enumerate() { + if let Some(&onset) = cache.onsets.get(at) { + columns.push(ColumnPlacement { onset, x }); + } + x += widths.next().unwrap_or(0.0); + } + // The closing barline stands back from the next measure's + // first column by the same lead its trailing rod reserved; + // the system's last barline lands on the right edge. + let last = index + 1 == system.measures.end; + let lead = if last { + self.style.distance.barline_to_note.0 + } else { + cache.lead_after + }; + let right = x - lead; + measures.push(MeasurePlacement { + measure: self.measure_ids[index], + index, + left, + right, + columns, + }); + left = right; + } + placed.systems.push(SystemPlacement { + top, + bottom: top + self.staff_span, + music_left, + right: self.page_width - MARGIN_RIGHT, + show_meter, + measures, + }); + } + if let Some(slot) = self.pages.get_mut(page_index) { + *slot = placed; + } + } +} + +/// Build one column's spring from its rod and its duration. +/// +/// `headroom` is the rod, so the regularizer's notion of "whitespace" +/// (`width - headroom`) is exactly the duration space, and both flexibilities +/// are that same duration space — see the module docs for why. +fn spring(rod: f64, duration: f64, style: &LayoutStyle) -> SpacingColumn { + let space = style.spacing.spacing_increment.0 + * makepad_score_layout::duration_quanta(duration, &style.spacing); + SpacingColumn { + natural: Sp(rod + space), + minimum: Sp(rod), + stretch_flex: space.max(style.spacing.min_stretch_flex), + shrink_flex: space.max(style.spacing.min_shrink_flex), + headroom: Sp(rod), + duration_class: Some((duration * 1024.0).round().clamp(0.0, 4096.0) as u32), + } +} + +/// One onset's measured ink, merged over every voice and both staves. +#[derive(Clone, Copy, Debug)] +pub(crate) struct ColumnInk { + pub onset: ScoreTime, + /// Ink reaching left of the notehead origin: accidentals, and the heads + /// a down-stem chord pushes to the far side of its stem. + pub left: f64, + /// Ink reaching right of it: the notehead advance, second-interval head + /// shifts, augmentation dots. + pub right: f64, +} + +/// A measure's merged onset columns plus its vertical reach. +pub(crate) struct MeasureInk { + pub columns: Vec, + pub above: f64, + pub below: f64, +} + +/// Measure one measure: what ink sits at each onset, and how far the ink +/// reaches above and below the grand staff. +pub(crate) fn measure_ink( + score: &Score, + font: &'static MusicFont, + measure: &Measure, + distance: &DistanceStyle, +) -> MeasureInk { + let key = score + .maps + .key_at(measure.start, None, None) + .cloned() + .unwrap_or(KeySignature::C_MAJOR); + let frames = crate::engrave::score_staff_frames(score, 0.0); + let staff_span = frames.last().map_or(STAFF_SPAN, |staff| staff.bottom()); + let staves = measure_staff_columns(font, score, measure, &key, &frames); + let mut merged: BTreeMap = BTreeMap::new(); + let mut top = 0.0_f64; + let mut bottom = staff_span; + for voices in &staves { + for columns in voices { + for column in columns { + let (left, right) = column_extents(font, column, distance); + let entry = merged.entry(column.time).or_insert((0.0, 0.0)); + entry.0 = entry.0.max(left); + entry.1 = entry.1.max(right); + top = top.min(column.top_y()); + bottom = bottom.max(column.bottom_y()); + } + } + } + let lyric_verses = score + .lyrics + .iter() + .filter(|lyric| { + staves.iter().any(|voices| { + voices.iter().any(|columns| { + columns + .iter() + .any(|column| column.heads.iter().any(|head| head.note == lyric.note)) + }) + }) + }) + .map(|lyric| lyric.verse.max(1)) + .max() + .unwrap_or(0); + let lyric_below = if lyric_verses == 0 { + 3.0 + } else { + 4.5 + f64::from(lyric_verses - 1) * 1.8 + }; + MeasureInk { + columns: merged + .into_iter() + .map(|(onset, (left, right))| ColumnInk { onset, left, right }) + .collect(), + // A notehead is one staff space tall; stems, beams and flags reach + // roughly a stem length past the outermost head. + above: (-top + 1.0 + 2.0).max(3.0), + below: (bottom - staff_span + 1.0 + 2.0).max(lyric_below), + } +} + +/// How far one chord's ink reaches either side of its notehead origin. +fn column_extents(font: &'static MusicFont, column: &Column, distance: &DistanceStyle) -> (f64, f64) { + let head = column + .heads + .iter() + .map(|head| font.advance(&head.glyph).max(font.bbox(&head.glyph).width())) + .fold(0.0_f64, f64::max) + .max(0.6); + let shifted = column.heads.iter().any(|head| head.shifted); + // A second-interval head sits on the far side of the stem: to the right + // for an up stem, to the left for a down stem. + let (mut left, mut right) = match (shifted, column.stem_up) { + (false, _) => (0.0, head), + (true, true) => (0.0, head * 2.0), + (true, false) => (head, head), + }; + let accidental = column + .heads + .iter() + .filter_map(|head| head.accidental.as_deref()) + .map(|name| font.advance(name).max(font.bbox(name).width())) + .fold(0.0_f64, f64::max); + if accidental > 0.0 { + left += accidental + distance.accidental_to_note.0; + } + if column.value.dots > 0 { + let dot = font.advance("augmentationDot").max(0.3); + let dots = f64::from(column.value.dots); + right += distance.note_to_dot.0 + dots * dot + (dots - 1.0) * distance.dot_to_dot.0; + } + (left, right) +} + +/// How far the first column of a measure reaches left of its notehead. +fn leading_ink(ink: Option<&MeasureInk>) -> f64 { + ink.and_then(|ink| ink.columns.first()) + .map(|column| column.left) + .unwrap_or(0.0) +} + +pub(crate) fn ordered_measures(score: &Score) -> Vec<&Measure> { + let mut measures: Vec<&Measure> = score.measures.values().collect(); + measures.sort_by_key(|measure| (measure.ordinal, measure.start)); + measures +} + +pub(crate) fn rational_f64(value: Rational) -> f64 { + value.numerator() as f64 / value.denominator() as f64 +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::engrave::tests::{engrave, fixture, fixture_events, Placed}; + use makepad_score::model::Step; + use makepad_score_layout::duration_quanta; + + const SCALE: [Step; 7] = [ + Step::C, + Step::D, + Step::E, + Step::F, + Step::G, + Step::A, + Step::B, + ]; + + /// The x of every notehead on the page, left to right. + fn head_xs(score: &Score) -> Vec { + let mut xs: Vec = engrave(score) + .noteheads + .into_iter() + .map(|(x, _, _)| x) + .collect(); + xs.sort_by(f64::total_cmp); + xs + } + + fn run(count: usize, denominator: u64) -> Score { + let pitches: Vec<(Step, i8)> = (0..count).map(|i| (SCALE[i % 7], 4)).collect(); + fixture(&pitches, denominator) + } + + /// The headline defect this module exists to fix: a run of equal notes + /// must advance by one constant step, not bunch up at the barline. + #[test] + fn a_run_of_sixteenths_advances_in_equal_steps() { + let font = music_font(); + let style = LayoutStyle::default(); + let xs = head_xs(&run(16, 16)); + assert_eq!(xs.len(), 16); + let steps: Vec = xs.windows(2).map(|pair| pair[1] - pair[0]).collect(); + let first = steps[0]; + for step in &steps { + assert!( + (step - first).abs() < 1e-9, + "sixteenths are unevenly spaced: {steps:?}" + ); + } + // And every step clears the ink: notehead advance plus the house + // minimum whitespace between notes. + let rod = font.advance("noteheadBlack") + style.distance.note_to_note_min.0; + assert!(first > rod, "step {first} is tighter than the rod {rod}"); + } + + #[test] + fn locate_maps_bar_starts_and_the_score_end_to_engraved_x() { + let score = crate::document::demo_score(4).expect("the fixture is valid"); + let mut spacing = ScoreSpacing::new(); + spacing.rebuild(&score); + + let at_start = spacing.locate(&score, 0.0).expect("score start"); + let at_bar_two = spacing.locate(&score, 1.0).expect("second bar start"); + let at_end = spacing.locate(&score, 4.0).expect("score end"); + let placement = |index: usize| { + spacing + .pages + .iter() + .flat_map(|page| &page.systems) + .flat_map(|system| &system.measures) + .find(|measure| measure.index == index) + .expect("measure placement") + }; + let first = placement(0); + let second = placement(1); + let last = placement(3); + + assert_eq!(at_start.x_sp, first.x_at(0.0, 0.0, 1.0)); + assert_eq!(at_bar_two.x_sp, second.x_at(1.0, 1.0, 2.0)); + assert_eq!(at_end.x_sp, last.right); + assert_eq!(at_end.page, spacing.page_of_measure(3).unwrap()); + } + + /// A single bar is not smeared across the page: below the style's + /// fill threshold the last system stays ragged at its natural width. + #[test] + fn a_one_bar_score_stays_ragged() { + let drawn = engrave(&run(16, 16)); + let margin = PAGE_WIDTH_SP - MARGIN_RIGHT; + assert!( + drawn.system_right < margin - 10.0, + "a one-bar score was stretched to {} of {margin}", + drawn.system_right + ); + // But it still starts where music starts, and the notes fill it. + let last = drawn.noteheads.iter().map(|(x, _, _)| *x).fold(0.0, f64::max); + assert!(last < drawn.system_right && last > drawn.system_right - 6.0); + } + + /// Space follows the duration curve, not the clock: a half note gets the + /// curve's ratio more whitespace than a quarter, never four times more. + #[test] + fn a_long_note_earns_curve_much_room_not_clock_much() { + let font = music_font(); + let style = LayoutStyle::default(); + let xs = head_xs(&fixture_events(&[ + Placed { onset: (0, 1), duration: (1, 2), step: Step::G, octave: 4 }, + Placed { onset: (1, 2), duration: (1, 4), step: Step::A, octave: 4 }, + Placed { onset: (3, 4), duration: (1, 4), step: Step::B, octave: 4 }, + ])); + assert_eq!(xs.len(), 3); + let gap = style.distance.note_to_note_min.0; + let white_half = (xs[1] - xs[0]) - (font.advance("noteheadHalf") + gap); + let white_quarter = (xs[2] - xs[1]) - (font.advance("noteheadBlack") + gap); + let want = duration_quanta(0.5, &style.spacing) / duration_quanta(0.25, &style.spacing); + let got = white_half / white_quarter; + assert!( + (got - want).abs() < 1e-6, + "whitespace ratio {got} should follow the duration curve {want}" + ); + // Sanity: the clock ratio would have been 2.0. + assert!(got < 1.5); + } + + /// The rods are measured ink, not a guess: for a plain run they are the + /// font's own notehead advance plus the house note-to-note minimum, and + /// the last one also has to clear the barline. + #[test] + fn rods_are_measured_from_the_font() { + let font = music_font(); + let style = LayoutStyle::default(); + let score = run(8, 8); + let measures = ordered_measures(&score); + let ink = measure_ink(&score, font, measures[0], &style.distance); + assert_eq!(ink.columns.len(), 8); + for column in &ink.columns { + assert_eq!(column.left, 0.0); + assert!((column.right - font.advance("noteheadBlack")).abs() < 1e-9); + } + let mut spacing = ScoreSpacing::new(); + spacing.rebuild(&score); + let rods: Vec = spacing.sources[0] + .columns + .iter() + .map(|column| column.minimum.0) + .collect(); + let inner = font.advance("noteheadBlack") + style.distance.note_to_note_min.0; + for rod in &rods[..7] { + assert!((rod - inner).abs() < 1e-9, "inner rod {rod} != {inner}"); + } + // The trailing rod carries the note-to-barline space, the barline + // itself and the lead into the next measure. + assert!(rods[7] > inner + style.distance.note_to_barline.0); + } + + /// Every column of a system is a spring whose whitespace is its duration + /// space scaled by one shared force. That is the invariant the engraved + /// picture rests on, so pin it directly on the solved widths. + #[test] + fn one_force_scales_every_column_s_duration_space() { + let score = run(12, 16); + let mut spacing = ScoreSpacing::new(); + spacing.rebuild(&score); + let system = &spacing.systems[0]; + let force = system.solution.force; + for (column, width) in spacing.sources[0] + .columns + .iter() + .zip(&system.solution.widths) + { + let want = column.minimum.0 + (column.natural.0 - column.minimum.0) * (1.0 + force); + assert!( + (width.0 - want).abs() < 1e-9, + "column width {} is not rod + duration space * (1 + F)", + width.0 + ); + assert!(width.0 >= column.minimum.0 - 1e-12, "a rod was violated"); + } + } + + /// Systems no longer hold a constant four measures: the breaker decides, + /// and a bar of sixteenths costs more room than a bar of quarters. + #[test] + fn measures_per_system_follows_the_music() { + let dense = { + let mut score = run(16, 16); + grow(&mut score, 8); + score + }; + let sparse = { + let mut score = run(4, 4); + grow(&mut score, 8); + score + }; + let mut a = ScoreSpacing::new(); + a.rebuild(&dense); + let mut b = ScoreSpacing::new(); + b.rebuild(&sparse); + let per = |s: &ScoreSpacing| s.systems[0].measures.len(); + assert!( + per(&a) < per(&b), + "sixteenths {} should not fit as densely as quarters {}", + per(&a), + per(&b) + ); + } + + /// Repeat a one-measure fixture `count` times, so a score has something + /// for the line breaker to break. + fn grow(score: &mut Score, count: u32) { + let first = ordered_measures(score)[0].id; + let template = score.measures[&first].clone(); + let events: Vec<_> = score + .voices + .values() + .map(|voice| (voice.id, voice.events.clone())) + .collect(); + let mut ids = makepad_score::model::IdGenerator::new(0x7e58); + for ordinal in 1..count { + let start = ScoreTime::new(i64::from(ordinal), 1).unwrap(); + let id = ids.next::().unwrap(); + score.measures.insert( + id, + Measure { + id, + ordinal, + label: (ordinal + 1).to_string(), + start, + extent: template.extent, + }, + ); + score.flow.nodes.push(makepad_score::model::FlowNode { + measure: id, + ordinal, + }); + for (voice, source) in &events { + let mut copies = Vec::with_capacity(source.len()); + for event in source { + let mut event = event.clone(); + event.id = ids.next::().unwrap(); + event.onset = event.onset.checked_add_time(start).unwrap(); + if let makepad_score::model::EventKind::Chord(notes) = &mut event.kind { + for note in notes { + note.id = ids.next::().unwrap(); + } + } + copies.push(event); + } + score.voices.get_mut(voice).unwrap().events.extend(copies); + } + } + } +} diff --git a/libs/score_ui/src/title.rs b/libs/score_view/src/title.rs similarity index 100% rename from libs/score_ui/src/title.rs rename to libs/score_view/src/title.rs diff --git a/libs/score_view/src/view.rs b/libs/score_view/src/view.rs new file mode 100644 index 000000000..79dba58b5 --- /dev/null +++ b/libs/score_view/src/view.rs @@ -0,0 +1,951 @@ +//! Lean draw-only score widget. + +use crate::{ + document::{DocumentOptions, ScoreDocument, PAGE_HEIGHT_SP, PAGE_WIDTH_SP}, + font, + spacing::rational_f64, +}; +use makepad_score::model::Score; +use makepad_score_render as render; +use makepad_score_render::MakepadScoreRenderer; +use makepad_widgets::{ + scroll_bar::{ScrollAxis, ScrollBarAction}, + *, +}; + +script_mod! { + use mod.prelude.widgets_internal.* + use mod.widgets.* + + mod.widgets.ScoreFit = #(ScoreFit::script_api(vm)) + mod.widgets.splat(mod.widgets.ScoreFit) + + mod.widgets.ScoreViewBase = #(ScoreView::register_widget(vm)) + mod.widgets.ScoreView = set_type_default() do mod.widgets.ScoreViewBase { + width: Fill + height: Fill + fit: mod.widgets.ScoreFit.Width + hide_labels: false + pan_zoom_gestures: false + dark: false + draw_bg +: { + color: theme.color_bg_app + draw_depth: 0.0 + } + draw_vector +: {draw_depth: 2.0} + draw_glyph +: { + aa_pad_px: 3.0 + draw_depth: 3.0 + } + draw_text +: { + draw_depth: 4.0 + color: theme.color_label_outer + text_style: theme.font_regular{font_size: 9.0} + } + scroll_bar_y: mod.widgets.ScrollBar { + bar_size: 9.0 + min_handle_size: 28.0 + } + } +} + +const VIEW_MARGIN: f64 = 8.0; +const PAGE_GAP: f64 = 8.0; +const MIN_ZOOM: f64 = 0.25; +const MAX_ZOOM: f64 = 8.0; +const CONTENT_REFLOW_STEPS: usize = 4; +const MAX_CONTENT_PAGE_WIDTH: f64 = PAGE_WIDTH_SP * 4.0; + +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Script, ScriptHook)] +pub enum ScoreFit { + #[pick] + #[default] + Width, + Page, + Content, +} + +#[derive(Clone, Copy, Debug)] +struct ContentFitLayout { + transform: render::Transform, +} + +fn content_fit_layout( + bounds: render::Rect, + view_size: render::Point, +) -> ContentFitLayout { + let available_width = (view_size.x - VIEW_MARGIN * 2.0).max(1.0); + let available_height = (view_size.y - VIEW_MARGIN * 2.0).max(1.0); + let width_scale = available_width / bounds.width().max(0.01); + let scale = width_scale + .min(available_height / bounds.height().max(0.01)) + .max(0.01); + let translation = render::Point::new( + (view_size.x - bounds.width() * scale) * 0.5 - bounds.min.x * scale, + (view_size.y - bounds.height() * scale) * 0.5 - bounds.min.y * scale, + ); + ContentFitLayout { transform: render::Transform { translation, scale } } +} + +fn content_layout_candidate( + document: &mut ScoreDocument, + hide_labels: bool, + page_width: f64, + view_size: render::Point, +) -> Option<(f64, f64, usize)> { + // The reflow only runs in Content mode, so the compact-page options + // (drum key included) are the base; only the page width is the variable. + let options = DocumentOptions { + page_size: render::Point::new(page_width, PAGE_HEIGHT_SP), + ..DocumentOptions::content(document.score(), hide_labels) + }; + document.set_options(options).ok()?; + let bounds = document.content_bounds(0)?; + let available_width = (view_size.x - VIEW_MARGIN * 2.0).max(1.0); + let available_height = (view_size.y - VIEW_MARGIN * 2.0).max(1.0); + let scale = (available_width / bounds.width().max(0.01)) + .min(available_height / bounds.height().max(0.01)); + let fill = (bounds.width() * scale / available_width) + .min(bounds.height() * scale / available_height); + Some(( + bounds.width() / bounds.height().max(0.01), + fill, + document.system_count(0), + )) +} + +/// Reflow content toward the view aspect. The bounds aspect is monotonic in +/// useful page width apart from system-break steps, so keep the best sampled +/// break while four binary iterations close around the target aspect. +fn reflow_content_for_view( + document: &mut ScoreDocument, + hide_labels: bool, + view_size: render::Point, +) -> Option { + if view_size.x <= 0.0 || view_size.y <= 0.0 { + return None; + } + let minimum = PAGE_WIDTH_SP * 0.5; + let widest = document + .spacing() + .natural_page_width() + .clamp(minimum, MAX_CONTENT_PAGE_WIDTH); + let target_aspect = (view_size.x - VIEW_MARGIN * 2.0).max(1.0) + / (view_size.y - VIEW_MARGIN * 2.0).max(1.0); + let mut low = minimum.min(widest); + let mut high = widest; + let prefer_single_system = target_aspect >= 2.0; + let mut best = (false, f64::NEG_INFINITY, high); + + for width in [low, high] { + if let Some((_, fill, systems)) = + content_layout_candidate(document, hide_labels, width, view_size) + { + let preferred = (systems == 1) == prefer_single_system; + if (preferred && !best.0) || (preferred == best.0 && fill > best.1) { + best = (preferred, fill, width); + } + } + } + for _ in 0..CONTENT_REFLOW_STEPS { + let width = (low + high) * 0.5; + let Some((aspect, fill, systems)) = + content_layout_candidate(document, hide_labels, width, view_size) + else { + break; + }; + let preferred = (systems == 1) == prefer_single_system; + if (preferred && !best.0) || (preferred == best.0 && fill > best.1) { + best = (preferred, fill, width); + } + if prefer_single_system && systems > 1 { + low = width; + } else if !prefer_single_system && systems == 1 { + high = width; + } else if aspect < target_aspect { + low = width; + } else { + high = width; + } + } + content_layout_candidate(document, hide_labels, best.2, view_size)?; + Some(best.2) +} + +fn compose_view_transform( + base: render::Transform, + viewport: render::Rect, + zoom: f64, + offset: DVec2, +) -> render::Transform { + let center = viewport.center(); + render::Transform { + translation: render::Point::new( + center.x + (base.translation.x - center.x) * zoom + offset.x, + center.y + (base.translation.y - center.y) * zoom + offset.y, + ), + scale: base.scale * zoom, + } +} + +fn clamp_pan_offset( + base: render::Transform, + bounds: render::Rect, + viewport: render::Rect, + zoom: f64, + offset: DVec2, +) -> DVec2 { + let unpanned = compose_view_transform(base, viewport, zoom, DVec2::default()).rect(bounds); + let keep_x = (unpanned.width() * 0.25).min(viewport.width() * 0.25); + let keep_y = (unpanned.height() * 0.25).min(viewport.height() * 0.25); + dvec2( + offset.x.clamp( + viewport.min.x + keep_x - unpanned.max.x, + viewport.max.x - keep_x - unpanned.min.x, + ), + offset.y.clamp( + viewport.min.y + keep_y - unpanned.max.y, + viewport.max.y - keep_y - unpanned.min.y, + ), + ) +} + +fn apply_wheel_zoom( + base: render::Transform, + bounds: render::Rect, + viewport: render::Rect, + zoom: &mut f64, + offset: &mut DVec2, + at: DVec2, + delta: f64, +) { + let before = compose_view_transform(base, viewport, *zoom, *offset); + let score_at = render::Point::new( + (at.x - before.translation.x) / before.scale, + (at.y - before.translation.y) / before.scale, + ); + *zoom = (*zoom * (-delta * 0.0025).exp()).clamp(MIN_ZOOM, MAX_ZOOM); + let without_offset = compose_view_transform(base, viewport, *zoom, DVec2::default()); + *offset = dvec2( + at.x - without_offset.translation.x - score_at.x * without_offset.scale, + at.y - without_offset.translation.y - score_at.y * without_offset.scale, + ); + *offset = clamp_pan_offset(base, bounds, viewport, *zoom, *offset); +} + +fn reset_pan_zoom(zoom: &mut f64, offset: &mut DVec2) { + *zoom = 1.0; + *offset = DVec2::default(); +} + +#[derive(Script, ScriptHook, Widget)] +pub struct ScoreView { + #[uid] + uid: WidgetUid, + #[source] + source: ScriptObjectRef, + #[walk] + walk: Walk, + #[layout] + layout: Layout, + #[redraw] + #[live] + draw_bg: DrawColor, + #[live] + draw_vector: DrawVector, + #[live] + draw_glyph: DrawGlyph, + #[live] + draw_text: DrawText, + #[live] + fit: ScoreFit, + #[live] + hide_labels: bool, + #[live] + pan_zoom_gestures: bool, + /// Draw with the designed dark palette (charcoal paper, warm ink) for + /// hosts whose own surface is dark; the paper itself is `draw_bg`. + #[live] + dark: bool, + #[live] + scroll_bar_y: ScrollBar, + #[rust] + area: Area, + #[rust] + document: ScoreDocument, + #[rust] + renderer: MakepadScoreRenderer, + #[rust] + glyphs_ready: bool, + #[rust] + zoom: f64, + #[rust] + offset: DVec2, + #[rust] + scroll_y: f64, + #[rust] + content_height: f64, + #[rust] + content_layout_size: DVec2, + #[rust] + chosen_page_width: f64, + #[rust] + playhead: Option, + #[rust] + grab: Option<(DVec2, DVec2)>, +} + +impl ScoreView { + pub fn set_score(&mut self, cx: &mut Cx, score: Score) { + font::ensure_default_font(); + self.invalidate_content_layout(); + let options = self.document_options(&score); + if self.document.set_score_with_options(score, options).is_err() { + self.document.clear(); + } + self.reset_navigation(); + self.playhead = None; + self.redraw(cx); + } + + pub fn clear(&mut self, cx: &mut Cx) { + self.document.clear(); + self.invalidate_content_layout(); + self.reset_navigation(); + self.playhead = None; + self.redraw(cx); + } + + /// Show a playback cursor at a time measured in whole notes from the + /// score start. Values outside the score are pinned to its endpoints. + pub fn set_playhead(&mut self, cx: &mut Cx, at: Option) { + let end = self + .document + .score() + .measures + .values() + .map(|measure| { + rational_f64(measure.start.0) + rational_f64(measure.extent.0) + }) + .max_by(f64::total_cmp); + let playhead = at.and_then(|at| { + end.filter(|_| at.is_finite()) + .map(|end| at.clamp(0.0, end)) + }); + if self.playhead != playhead { + self.playhead = playhead; + self.redraw(cx); + } + } + + pub fn set_zoom(&mut self, cx: &mut Cx, zoom: f64) { + self.zoom = zoom.clamp(MIN_ZOOM, MAX_ZOOM); + self.redraw(cx); + } + + pub fn fit_width(&mut self, cx: &mut Cx, on: bool) { + self.set_fit(cx, if on { ScoreFit::Width } else { ScoreFit::Page }); + } + + pub fn set_fit(&mut self, cx: &mut Cx, fit: ScoreFit) { + if self.fit == fit { + return; + } + self.fit = fit; + self.invalidate_content_layout(); + self.rebuild_for_display_options(); + self.reset_navigation(); + self.redraw(cx); + } + + pub fn set_hide_labels(&mut self, cx: &mut Cx, hide_labels: bool) { + if self.hide_labels == hide_labels { + return; + } + self.hide_labels = hide_labels; + self.invalidate_content_layout(); + self.rebuild_for_display_options(); + self.reset_navigation(); + self.redraw(cx); + } + + pub fn score(&self) -> &Score { + self.document.score() + } + + pub fn document(&self) -> &ScoreDocument { + &self.document + } + + fn effective_zoom(&self) -> f64 { + if self.zoom > 0.0 { self.zoom } else { 1.0 } + } + + fn gestures_enabled(&self) -> bool { + self.pan_zoom_gestures || self.fit == ScoreFit::Content + } + + fn invalidate_content_layout(&mut self) { + self.content_layout_size = DVec2::default(); + self.chosen_page_width = 0.0; + } + + fn reset_navigation(&mut self) { + reset_pan_zoom(&mut self.zoom, &mut self.offset); + self.scroll_y = 0.0; + self.grab = None; + } + + fn document_options(&self, score: &Score) -> DocumentOptions { + if self.fit == ScoreFit::Content { + DocumentOptions::content(score, self.hide_labels) + } else { + DocumentOptions { + hide_labels: self.hide_labels, + ..DocumentOptions::default() + } + } + } + + fn rebuild_for_display_options(&mut self) { + let options = self.document_options(self.document.score()); + if self.document.set_options(options).is_err() { + self.document.clear(); + } + } + + fn ensure_content_layout(&mut self, view_size: DVec2) { + if self.fit != ScoreFit::Content + || ((view_size.x - self.content_layout_size.x).abs() < 0.5 + && (view_size.y - self.content_layout_size.y).abs() < 0.5) + { + return; + } + if let Some(width) = reflow_content_for_view( + &mut self.document, + self.hide_labels, + render::Point::new(view_size.x, view_size.y), + ) { + self.chosen_page_width = width; + self.content_layout_size = view_size; + } + } + + fn content_bounds(&self) -> render::Rect { + self.document.content_bounds(0).unwrap_or_else(|| { + let size = self + .document + .pages() + .first() + .map(|page| page.page_size()) + .unwrap_or(render::Point::new(1.0, 1.0)); + render::Rect::from_xywh(0.0, 0.0, size.x, size.y) + }) + } + + fn viewport(rect: Rect) -> render::Rect { + render::Rect::from_xywh(rect.pos.x, rect.pos.y, rect.size.x, rect.size.y) + } + + fn fit_transform(&self, rect: Rect) -> render::Transform { + let page_size = self + .document + .pages() + .first() + .map(|page| page.page_size()) + .unwrap_or(render::Point::new(1.0, 1.0)); + let (scale, local) = match self.fit { + ScoreFit::Width => { + let scale = ((rect.size.x - VIEW_MARGIN * 2.0).max(1.0) / page_size.x) + .max(0.01); + ( + scale, + render::Point::new( + (rect.size.x - page_size.x * scale) * 0.5, + VIEW_MARGIN, + ), + ) + } + ScoreFit::Page => { + let scale = ((rect.size.x - VIEW_MARGIN * 2.0).max(1.0) / page_size.x) + .min((rect.size.y - VIEW_MARGIN * 2.0).max(1.0) / page_size.y) + .max(0.01); + let y = if self.document.page_count() <= 1 { + (rect.size.y - page_size.y * scale) * 0.5 + } else { + VIEW_MARGIN + }; + ( + scale, + render::Point::new((rect.size.x - page_size.x * scale) * 0.5, y), + ) + } + ScoreFit::Content => { + let layout = content_fit_layout( + self.content_bounds(), + render::Point::new(rect.size.x, rect.size.y), + ); + (layout.transform.scale, layout.transform.translation) + } + }; + render::Transform { + translation: render::Point::new(rect.pos.x + local.x, rect.pos.y + local.y), + scale, + } + } + + /// The one composed score-to-view transform. Rendering and overlays must + /// both use this so fit, cursor-anchored zoom, and pan never diverge. + fn view_transform(&self, rect: Rect) -> render::Transform { + let mut transform = compose_view_transform( + self.fit_transform(rect), + Self::viewport(rect), + self.effective_zoom(), + self.offset, + ); + if self.fit != ScoreFit::Content { + transform.translation.y -= self.scroll_y; + } + transform + } + + fn clamp_pan(&mut self, rect: Rect) { + let scroll = if self.fit == ScoreFit::Content { + DVec2::default() + } else { + dvec2(0.0, -self.scroll_y) + }; + let combined = clamp_pan_offset( + self.fit_transform(rect), + self.content_bounds(), + Self::viewport(rect), + self.effective_zoom(), + self.offset + scroll, + ); + self.offset = combined - scroll; + } + + fn apply_wheel_zoom(&mut self, rect: Rect, at: DVec2, delta: f64) { + let base = self.fit_transform(rect); + let bounds = self.content_bounds(); + let viewport = Self::viewport(rect); + let mut zoom = self.effective_zoom(); + let scroll = if self.fit == ScoreFit::Content { + DVec2::default() + } else { + dvec2(0.0, -self.scroll_y) + }; + let mut combined = self.offset + scroll; + apply_wheel_zoom( + base, + bounds, + viewport, + &mut zoom, + &mut combined, + at, + delta, + ); + self.zoom = zoom; + self.offset = combined - scroll; + } + + fn max_scroll(&self, rect: Rect) -> f64 { + (self.content_height - rect.size.y).max(0.0) + } + + fn set_scroll(&mut self, cx: &mut Cx, rect: Rect, value: f64) { + let value = value.clamp(0.0, self.max_scroll(rect)); + if (value - self.scroll_y).abs() > f64::EPSILON { + self.scroll_y = value; + self.redraw(cx); + } + } + + fn ensure_glyphs(&mut self) { + if self.glyphs_ready { + return; + } + font::ensure_default_font(); + let font_ref = render::MusicFontRef(0); + for (name, outline) in font::music_font().outlines() { + let _ = self.renderer.register_glyph( + &mut self.draw_glyph, + font_ref, + render::SmuflGlyph::new(name.to_string()), + outline, + ); + } + self.glyphs_ready = true; + } +} + +impl Widget for ScoreView { + fn handle_event(&mut self, cx: &mut Cx, event: &Event, _scope: &mut Scope) { + let mut bar_scroll = None; + if self.fit != ScoreFit::Content { + self.scroll_bar_y.handle_event_with(cx, event, &mut |_cx, action| { + if let ScrollBarAction::Scroll { scroll_pos, .. } = action { + bar_scroll = Some(scroll_pos); + } + }); + } + let rect = self.area.rect(cx); + if let Some(scroll) = bar_scroll { + self.set_scroll(cx, rect, scroll); + } + let gestures_enabled = self.gestures_enabled(); + match event.hits(cx, self.area) { + Hit::FingerScroll(event) => { + if gestures_enabled { + let horizontal_pan = self.effective_zoom() > 1.0 + 1e-9 + && event.scroll.x.abs() > f64::EPSILON; + if horizontal_pan { + self.offset.x -= event.scroll.x; + self.clamp_pan(rect); + } + let zoom_delta = if event.scroll.y.abs() > f64::EPSILON { + Some(event.scroll.y) + } else if !horizontal_pan && event.scroll.x.abs() > f64::EPSILON { + Some(event.scroll.x) + } else { + None + }; + if let Some(delta) = zoom_delta { + self.apply_wheel_zoom(rect, event.abs, delta); + } + self.redraw(cx); + } else { + let delta = if event.scroll.y.abs() > f64::EPSILON { + event.scroll.y + } else { + event.scroll.x + }; + self.set_scroll(cx, rect, self.scroll_y + delta); + } + } + Hit::FingerDown(event) if gestures_enabled && event.is_primary_hit() => { + if event.tap_count >= 2 { + self.reset_navigation(); + cx.set_cursor(MouseCursor::Grab); + self.redraw(cx); + } else { + self.grab = Some((event.abs, self.offset)); + cx.set_cursor(MouseCursor::Grabbing); + } + } + Hit::FingerMove(event) if gestures_enabled => { + if let Some((origin, offset)) = self.grab { + self.offset = offset + event.abs - origin; + self.clamp_pan(rect); + self.redraw(cx); + } + } + Hit::FingerUp(_) if gestures_enabled => { + self.grab = None; + cx.set_cursor(MouseCursor::Grab); + } + Hit::FingerHoverIn(_) | Hit::FingerHoverOver(_) if gestures_enabled => { + cx.set_cursor(MouseCursor::Grab); + } + Hit::FingerHoverOut(_) if gestures_enabled => { + cx.set_cursor(MouseCursor::Default); + } + _ => {} + } + } + + fn draw_walk(&mut self, cx: &mut Cx2d, _scope: &mut Scope, walk: Walk) -> DrawStep { + self.ensure_glyphs(); + let rect = cx.walk_turtle(walk); + self.ensure_content_layout(rect.size); + self.draw_bg.draw_abs(cx, rect); + cx.begin_turtle( + Walk { + abs_pos: Some(rect.pos), + width: Size::Fixed(rect.size.x), + height: Size::Fixed(rect.size.y), + margin: Inset::default(), + metrics: Metrics::default(), + }, + Layout { clip_x: true, clip_y: true, ..Layout::default() }, + ); + + let first_page_size = self + .document + .pages() + .first() + .map(|page| page.page_size()) + .unwrap_or(render::Point::new(1.0, 1.0)); + let scale = self.fit_transform(rect).scale * self.effective_zoom(); + self.content_height = if self.fit == ScoreFit::Content { + rect.size.y + } else { + VIEW_MARGIN * 2.0 + + self.document.page_count() as f64 * first_page_size.y * scale + + self.document.page_count().saturating_sub(1) as f64 * PAGE_GAP + }; + self.scroll_y = self.scroll_y.clamp(0.0, self.max_scroll(rect)); + if self.gestures_enabled() { + self.clamp_pan(rect); + } + let first_transform = self.view_transform(rect); + let views = self + .document + .pages() + .iter() + .enumerate() + .map(|(index, page)| render::PageView { + page: page.clone(), + transform: render::Transform { + translation: render::Point::new( + first_transform.translation.x, + first_transform.translation.y + + index as f64 * (first_page_size.y * scale + PAGE_GAP), + ), + scale: first_transform.scale, + }, + }) + .collect::>(); + let viewport = render::Rect::from_xywh(rect.pos.x, rect.pos.y, rect.size.x, rect.size.y); + let playback_cursor = self.playhead.and_then(|whole| { + self.document + .spacing() + .locate(self.document.score(), whole) + .map(|location| render::PlaybackPosition { + page: render::PageId(location.page as u32), + x_sp: location.x_sp, + system_span_sp: Some((location.top_sp, location.bottom_sp)), + }) + }); + let overlays = render::OverlayState { + playback_cursor, + ..render::OverlayState::default() + }; + let plan = render::RenderPlanner.plan( + &views, + viewport, + &overlays, + render::OverlayMetrics::default(), + ); + let mut text = render::SingleFontTextBackend { + font: render::TextFontRef(0), + draw_text: &mut self.draw_text, + }; + let _ = self.renderer.draw( + cx, + &plan, + if self.dark { render::ScorePalette::dark() } else { render::ScorePalette::light() }, + &mut self.draw_glyph, + &mut self.draw_vector, + &mut text, + render::GpuDrawOptions { + device_scale: cx.current_dpi_factor(), + ..render::GpuDrawOptions::default() + }, + ); + + if self.fit != ScoreFit::Content { + let view = Rect { pos: DVec2::default(), size: rect.size }; + let total = self.content_height.max(rect.size.y); + self.scroll_bar_y.set_scroll_view_total(cx, total); + self.scroll_bar_y.set_scroll_pos_no_action(cx, self.scroll_y); + self.scroll_bar_y.draw_scroll_bar( + cx, + ScrollAxis::Vertical, + view, + dvec2(rect.size.x, total), + ); + } + cx.end_turtle_with_area(&mut self.area); + DrawStep::done() + } +} + +impl ScoreViewRef { + pub fn set_score(&self, cx: &mut Cx, score: Score) { + if let Some(mut view) = self.borrow_mut() { + view.set_score(cx, score); + } + } + + pub fn clear(&self, cx: &mut Cx) { + if let Some(mut view) = self.borrow_mut() { + view.clear(cx); + } + } + + pub fn set_playhead(&self, cx: &mut Cx, at: Option) { + if let Some(mut view) = self.borrow_mut() { + view.set_playhead(cx, at); + } + } + + pub fn set_zoom(&self, cx: &mut Cx, zoom: f64) { + if let Some(mut view) = self.borrow_mut() { + view.set_zoom(cx, zoom); + } + } + + pub fn fit_width(&self, cx: &mut Cx, on: bool) { + if let Some(mut view) = self.borrow_mut() { + view.fit_width(cx, on); + } + } + + pub fn set_fit(&self, cx: &mut Cx, fit: ScoreFit) { + if let Some(mut view) = self.borrow_mut() { + view.set_fit(cx, fit); + } + } + + pub fn set_hide_labels(&self, cx: &mut Cx, hide_labels: bool) { + if let Some(mut view) = self.borrow_mut() { + view.set_hide_labels(cx, hide_labels); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{build_drum_score, BuildOptions, DrumHit, DrumVoice}; + + #[test] + fn set_playhead_none_clears_the_stored_cursor() { + let mut cx = Cx::new(Box::new(|_cx: &mut Cx, _event: &Event| {})); + let mut std = (); + let mut vm = ScriptVm { + host: &mut cx, + std: &mut std, + bx: Box::new(ScriptVmBase::new()), + }; + let mut view = ScoreView::script_new(&mut vm); + drop(vm); + view.playhead = Some(1.0); + + view.set_playhead(&mut cx, None); + + assert_eq!(view.playhead, None); + } + + fn four_bar_drum_score() -> Score { + let voices = [ + DrumVoice::Kick, + DrumVoice::HiHatClosed, + DrumVoice::Snare, + DrumVoice::HiHatClosed, + ]; + let hits: Vec<_> = (0..64) + .map(|step| DrumHit { + time_beats: step as f64 * 0.25, + voice: voices[step % voices.len()], + velocity: 1.0, + }) + .collect(); + build_drum_score( + &hits, + &BuildOptions { bars: 4, ..BuildOptions::default() }, + ) + } + + fn drum_document() -> ScoreDocument { + crate::font::ensure_default_font(); + let score = four_bar_drum_score(); + ScoreDocument::with_options( + score.clone(), + DocumentOptions::content(&score, true), + ) + .expect("the drum fixture engraves") + } + + #[test] + fn width_remains_the_default_fit() { + assert_eq!(ScoreFit::default(), ScoreFit::Width); + } + + #[test] + fn wide_content_reflows_to_one_system_and_fills_the_view() { + let mut document = drum_document(); + let view = render::Point::new(1640.0, 400.0); + let chosen = reflow_content_for_view(&mut document, true, view).unwrap(); + let bounds = document.content_bounds(0).unwrap(); + let layout = content_fit_layout(bounds, view); + let fitted = layout.transform.rect(bounds); + assert_eq!( + document.system_count(0), + 1, + "chosen page width {chosen}, natural {}", + document.spacing().natural_page_width() + ); + assert!(fitted.width() >= view.x * 0.8, "{fitted:?}, width {chosen}"); + assert!(fitted.min.x >= VIEW_MARGIN - 1e-9, "{fitted:?}"); + assert!(fitted.min.y >= VIEW_MARGIN - 1e-9, "{fitted:?}"); + assert!(fitted.max.x <= view.x - VIEW_MARGIN + 1e-9, "{fitted:?}"); + assert!(fitted.max.y <= view.y - VIEW_MARGIN + 1e-9, "{fitted:?}"); + } + + #[test] + fn square_content_reflows_to_a_stack_and_fills_the_view() { + let mut document = drum_document(); + let view = render::Point::new(400.0, 400.0); + let chosen = reflow_content_for_view(&mut document, true, view).unwrap(); + let bounds = document.content_bounds(0).unwrap(); + let layout = content_fit_layout(bounds, view); + let fitted = layout.transform.rect(bounds); + assert!(document.system_count(0) >= 2, "chosen page width {chosen}"); + assert!(fitted.height() >= view.y * 0.7, "{fitted:?}, width {chosen}"); + assert!(fitted.min.x >= VIEW_MARGIN - 1e-9, "{fitted:?}"); + assert!(fitted.min.y >= VIEW_MARGIN - 1e-9, "{fitted:?}"); + assert!(fitted.max.x <= view.x - VIEW_MARGIN + 1e-9, "{fitted:?}"); + assert!(fitted.max.y <= view.y - VIEW_MARGIN + 1e-9, "{fitted:?}"); + } + + #[test] + fn wheel_zoom_keeps_the_score_point_under_the_cursor() { + let bounds = render::Rect::from_xywh(0.0, 0.0, 300.0, 120.0); + let viewport = render::Rect::from_xywh(0.0, 0.0, 800.0, 400.0); + let base = content_fit_layout(bounds, render::Point::new(800.0, 400.0)).transform; + let at = dvec2(310.0, 175.0); + let mut zoom = 1.0; + let mut offset = DVec2::default(); + let before = compose_view_transform(base, viewport, zoom, offset); + let score_at = render::Point::new( + (at.x - before.translation.x) / before.scale, + (at.y - before.translation.y) / before.scale, + ); + + apply_wheel_zoom( + base, + bounds, + viewport, + &mut zoom, + &mut offset, + at, + -120.0, + ); + + let mapped = compose_view_transform(base, viewport, zoom, offset).point(score_at); + assert!((mapped.x - at.x).abs() <= 0.5, "{mapped:?} != {at:?}"); + assert!((mapped.y - at.y).abs() <= 0.5, "{mapped:?} != {at:?}"); + } + + #[test] + fn pan_is_clamped_and_reset_returns_to_fit() { + let bounds = render::Rect::from_xywh(0.0, 0.0, 300.0, 120.0); + let viewport = render::Rect::from_xywh(0.0, 0.0, 800.0, 400.0); + let base = content_fit_layout(bounds, render::Point::new(800.0, 400.0)).transform; + let zoom = 2.0; + let offset = clamp_pan_offset(base, bounds, viewport, zoom, dvec2(50_000.0, -50_000.0)); + let visible = compose_view_transform(base, viewport, zoom, offset).rect(bounds); + let visible_width = visible.max.x.min(viewport.max.x) - visible.min.x.max(viewport.min.x); + let visible_height = visible.max.y.min(viewport.max.y) - visible.min.y.max(viewport.min.y); + assert!(visible_width >= viewport.width() * 0.25 - 1e-9, "{visible:?}"); + assert!(visible_height >= viewport.height() * 0.25 - 1e-9, "{visible:?}"); + + let mut zoom = zoom; + let mut offset = offset; + reset_pan_zoom(&mut zoom, &mut offset); + assert_eq!(zoom, 1.0); + assert_eq!(offset, DVec2::default()); + } +} diff --git a/libs/score_view/tests/embed_app/Cargo.toml b/libs/score_view/tests/embed_app/Cargo.toml new file mode 100644 index 000000000..aa74c9909 --- /dev/null +++ b/libs/score_view/tests/embed_app/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "makepad-score-view-embed-test" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies] +makepad-score-view = { path = "../.." } diff --git a/libs/score_view/tests/embed_app/src/main.rs b/libs/score_view/tests/embed_app/src/main.rs new file mode 100644 index 000000000..920cc7f3b --- /dev/null +++ b/libs/score_view/tests/embed_app/src/main.rs @@ -0,0 +1,177 @@ +use makepad_score_view::{ + build_drum_score, makepad_widgets::*, BuildOptions, DrumHit, DrumVoice, +}; + +app_main!(App); + +script_mod! { + use mod.prelude.widgets.* + use mod.widgets.* + + mod.widgets.TextureSiblingBase = #(TextureSibling::register_widget(vm)) + mod.widgets.TextureSibling = set_type_default() do mod.widgets.TextureSiblingBase { + width: 600 + height: 64 + draw_tex +: { + tex: texture_2d(float) + pixel: fn() { + return self.tex.sample_as_bgra(self.pos) + } + } + } + + load_all_resources() do #(App::script_component(vm)) { + ui: Root { + main_window := Window { + window.inner_size: vec2(1400, 360) + body +: { + flow: Down + spacing: 8 + padding: 8 + show_bg: true + draw_bg +: { color: #182029 } + + score_host := View { + width: 1318 + height: 181 + score := ScoreView { + width: Fill + height: Fill + draw_bg +: { color: #f4f1ea } + } + } + controls := View { + width: Fit + height: 30 + flow: Right + spacing: 8 + resize := Button { text: "resize" } + status := Label { text: "1318x181" } + } + texture_host := View { + width: 600 + height: 64 + texture_sibling := mod.widgets.TextureSibling { + width: Fill + height: Fill + } + } + } + } + } + } +} + +#[derive(Script, ScriptHook, Widget)] +pub struct TextureSibling { + #[uid] + uid: WidgetUid, + #[source] + source: ScriptObjectRef, + #[walk] + walk: Walk, + #[layout] + layout: Layout, + #[redraw] + #[live] + draw_tex: DrawQuad, + #[rust] + area: Area, + #[rust] + texture: Option, +} + +impl Widget for TextureSibling { + fn draw_walk(&mut self, cx: &mut Cx2d, _scope: &mut Scope, walk: Walk) -> DrawStep { + cx.begin_turtle(walk, self.layout); + let rect = cx.turtle().rect(); + let texture = self + .texture + .get_or_insert_with(|| { + Texture::new_with_format( + cx, + TextureFormat::VecBGRAu8_32 { + width: 4, + height: 4, + data: Some(vec![0xff00_ff00; 16]), + updated: TextureUpdated::Full, + }, + ) + }) + .clone(); + self.draw_tex.draw_vars.set_texture(0, &texture); + self.draw_tex.draw_abs(cx, rect); + cx.end_turtle_with_area(&mut self.area); + DrawStep::done() + } + + fn handle_event(&mut self, _cx: &mut Cx, _event: &Event, _scope: &mut Scope) {} +} + +#[derive(Script, ScriptHook)] +pub struct App { + #[live] + ui: WidgetRef, +} + +impl MatchEvent for App { + fn handle_startup(&mut self, cx: &mut Cx) { + let voices = [ + DrumVoice::Kick, + DrumVoice::HiHatClosed, + DrumVoice::Snare, + DrumVoice::HiHatOpen, + DrumVoice::TomHigh, + DrumVoice::Ride, + DrumVoice::Crash, + ]; + let hits: Vec<_> = (0..64) + .map(|step| DrumHit { + time_beats: step as f64 * 0.25, + voice: voices[step % voices.len()], + velocity: 0.8, + }) + .collect(); + let score = build_drum_score( + &hits, + &BuildOptions { + bars: 4, + bpm: Some(124.0), + title: Some("Embedded score".to_string()), + ..BuildOptions::default() + }, + ); + self.ui + .widget(cx, ids!(score)) + .borrow_mut::() + .expect("score fixture lost its ScoreView") + .set_score(cx, score); + } + + fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions) { + if self.ui.button(cx, ids!(resize)).clicked(actions) { + let mut host = self.ui.widget(cx, ids!(score_host)); + script_apply_eval!(cx, host, { + width: 600 + height: 160 + }); + self.ui + .label(cx, ids!(status)) + .set_text(cx, "600x160"); + self.ui.redraw(cx); + } + } +} + +impl AppMain for App { + fn script_mod(vm: &mut ScriptVm) -> ScriptValue { + makepad_score_view::makepad_widgets::script_mod(vm); + makepad_score_view::script_mod(vm); + self::script_mod(vm) + } + + fn handle_event(&mut self, cx: &mut Cx, event: &Event) { + self.match_event(cx, event); + self.ui.handle_event(cx, event, &mut Scope::empty()); + } +} diff --git a/libs/score_view/tests/embedded.rs b/libs/score_view/tests/embedded.rs new file mode 100644 index 000000000..171d80255 --- /dev/null +++ b/libs/score_view/tests/embedded.rs @@ -0,0 +1,106 @@ +//! The VJ regression in miniature: a clipped, page-sized score is followed by +//! a textured sibling in the same pass, then resized and redrawn in-process. + +use makepad_test::{run_with_config, Selector, TestApp, TestConfig, WidgetSnapshot}; +use makepad_zune_png::makepad_zune_core::bytestream::ZCursor; +use makepad_zune_png::PngDecoder; +use std::path::{Path, PathBuf}; + +struct Image { + width: usize, + height: usize, + rgba: Vec, +} + +impl Image { + fn read(path: &Path) -> Self { + let bytes = std::fs::read(path) + .unwrap_or_else(|error| panic!("cannot read {}: {error}", path.display())); + let mut decoder = PngDecoder::new(ZCursor::new(&bytes)); + let pixels = decoder.decode_raw().expect("decode headless screenshot"); + let (width, height) = decoder.dimensions().expect("screenshot dimensions"); + let components = decoder + .colorspace() + .expect("screenshot color space") + .num_components(); + assert!(components >= 3); + let mut rgba = vec![0; width * height * 4]; + for index in 0..width * height { + let source = index * components; + rgba[index * 4..index * 4 + 3] + .copy_from_slice(&pixels[source..source + 3]); + rgba[index * 4 + 3] = if components == 4 { pixels[source + 3] } else { 255 }; + } + Self { width, height, rgba } + } + + fn pixels_in<'a>(&'a self, rect: &WidgetSnapshot) -> impl Iterator { + let x0 = (rect.x + 2).max(0) as usize; + let y0 = (rect.y + 2).max(0) as usize; + let x1 = (rect.x + rect.width - 2).max(0) as usize; + let y1 = (rect.y + rect.height - 2).max(0) as usize; + (y0..y1.min(self.height)).flat_map(move |y| { + (x0..x1.min(self.width)).map(move |x| { + let offset = (y * self.width + x) * 4; + &self.rgba[offset..offset + 4] + }) + }) + } +} + +fn assert_frame(app: &TestApp, expected_size: (i64, i64)) -> PathBuf { + let score = app.locator(Selector::id("score_host")).wait_visible().snapshot(); + assert_eq!((score.width, score.height), expected_size); + let sibling = app + .locator(Selector::id("texture_host")) + .wait_visible() + .snapshot(); + let path = app.screenshot(); + let image = Image::read(&path); + + let green = image + .pixels_in(&sibling) + .filter(|pixel| pixel[1] > 220 && pixel[0] < 24 && pixel[2] < 24) + .count(); + let sibling_pixels = (sibling.width * sibling.height) as usize; + assert!( + green * 2 > sibling_pixels, + "textured sibling after ScoreView was depth-occluded: {green}/{sibling_pixels} green pixels in {}", + path.display() + ); + + let dark_score_ink = image + .pixels_in(&score) + .filter(|pixel| pixel[0] < 96 && pixel[1] < 96 && pixel[2] < 96) + .count(); + assert!( + dark_score_ink > 100, + "ScoreView did not exercise its glyph/vector paths (only {dark_score_ink} dark pixels) in {}", + path.display() + ); + path +} + +#[test] +fn score_view_keeps_textured_siblings_at_two_sizes() { + let fixture = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/embed_app"); + let mut config = TestConfig::new( + &fixture, + "makepad-score-view-embed-test", + "embedded::score_view_keeps_textured_siblings_at_two_sizes", + ) + .expect("headless fixture config"); + config + .env + .insert("MAKEPAD_HEADLESS_DPI".to_string(), "1".to_string()); + + run_with_config(config, |app: TestApp| { + app.locator(Selector::id("status")).wait_text("1318x181"); + let first = assert_frame(&app, (1318, 181)); + app.locator(Selector::id("resize")).click(); + app.locator(Selector::id("status")).wait_text("600x160"); + let second = assert_frame(&app, (600, 160)); + assert_ne!(first, second, "two frames should produce distinct captures"); + }) + .expect("headless ScoreView regression"); +} diff --git a/platform/src/os/apple/metal.rs b/platform/src/os/apple/metal.rs index 593823360..c851134e4 100644 --- a/platform/src/os/apple/metal.rs +++ b/platform/src/os/apple/metal.rs @@ -1200,24 +1200,40 @@ impl Cx { metal_cx: &MetalCx, command_buffer: ObjcId, kind_id: usize, - width: usize, - height: usize, + expected_width: usize, + expected_height: usize, in_texture: ObjcId, - alloc: Option, + _alloc: Option, window_id: Option, ) -> Option { let request_ids = self.take_studio_screenshot_request_ids_for_window(kind_id as u32, window_id); - let (tex_width, tex_height) = if let Some(alloc) = alloc { - (alloc.width, alloc.height) - } else { - (width, height) - }; // A pending grab/probe request, or a screen-capture sink that is due a // frame for this window: either way the drawable has to be blitted into // a shared texture before it is presented. let wants_capture = crate::screen_capture::capture_wants_window(window_id); if !request_ids.is_empty() || wants_capture { + // `copyFromTexture:toTexture:` copies complete mip levels and Metal + // requires their dimensions to match exactly. During a live resize + // the pass rectangle can lag the CAMetalDrawable by a frame, so + // sizing this staging texture from `pass_rect` made a remote grab + // abort in MTLPickLargestMip. The source MTLTexture is authoritative: + // allocate and report the capture at its actual dimensions. + let tex_width: usize = unsafe { msg_send![in_texture, width] }; + let tex_height: usize = unsafe { msg_send![in_texture, height] }; + if tex_width == 0 || tex_height == 0 { + crate::error!("screenshot source texture has zero size"); + return None; + } + if tex_width != expected_width || tex_height != expected_height { + crate::log!( + "screenshot source is {}x{}, pass expected {}x{}", + tex_width, + tex_height, + expected_width, + expected_height + ); + } let descriptor = RcObjcId::from_owned( NonNull::new(unsafe { msg_send![class!(MTLTextureDescriptor), new] }).unwrap(), ); @@ -1247,8 +1263,8 @@ impl Cx { }; return Some(ScreenshotInfo { request_ids, - width: width as _, - height: height as _, + width: tex_width as _, + height: tex_height as _, window_id, texture, }); diff --git a/platform/src/os/cx_shared.rs b/platform/src/os/cx_shared.rs index e65406649..1ed6413f1 100644 --- a/platform/src/os/cx_shared.rs +++ b/platform/src/os/cx_shared.rs @@ -758,7 +758,7 @@ impl Cx { self.call_event_handler(&Event::KeyUp(e)); } StudioToApp::TextInput(e) => { - #[cfg(target_vendor = "apple")] + #[cfg(all(target_vendor = "apple", not(headless)))] crate::os::apple::metal::note_input_event(); self.call_event_handler(&Event::TextInput(e)); } From cb97fc569f8b7bb28dd3b54373df62384aea5fb3 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 02:51:44 +0200 Subject: [PATCH 048/417] =?UTF-8?q?vj:=20the=20loop=20splat=20=E2=80=94=20?= =?UTF-8?q?a=20song=20sliced=20into=20per-stem,=20beat-quantized=20loops?= =?UTF-8?q?=20on=20the=20APC40=20grid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eight song sections by drums, bass, vocals, other and mix; launch and swap on the bar, right-click halves and quarters, per-cell waveforms with score blocks, a full-width score popup (drums, bass tab, melody with lyrics) played back through the piano and the sample kit, an NMF drum transcriber, Basic Pitch for pitched stems and Beat This! grid refinement when installed, beat jump and phase-flip buttons, a loading overlay for the grid, and the shared model install panel in INSTALL MODELS. Co-Authored-By: Claude Fable 5.1 --- apps/vj/Cargo.toml | 11 +- apps/vj/resources/icons/fast_forward.svg | 1 + apps/vj/src/apc40.rs | 209 +- apps/vj/src/beat_eval.rs | 22 +- apps/vj/src/console_scale.rs | 67 - apps/vj/src/decks.rs | 206 ++ apps/vj/src/loop_blocks.rs | 109 ++ apps/vj/src/loop_splat.rs | 528 +++++ apps/vj/src/loop_splat_model.rs | 269 +++ apps/vj/src/loop_splat_view.rs | 1197 +++++++++++ apps/vj/src/loop_transcribe.rs | 2288 ++++++++++++++++++++++ apps/vj/src/main.rs | 1814 ++++++++++++++++- apps/vj/src/mixer.rs | 1020 +++++++++- apps/vj/src/music_view.rs | 402 +++- apps/vj/src/notes_map.rs | 288 +++ apps/vj/src/score_preview.rs | 145 ++ apps/vj/src/wave_analysis.rs | 534 ++++- 17 files changed, 8904 insertions(+), 206 deletions(-) create mode 100644 apps/vj/resources/icons/fast_forward.svg create mode 100644 apps/vj/src/loop_blocks.rs create mode 100644 apps/vj/src/loop_splat.rs create mode 100644 apps/vj/src/loop_splat_model.rs create mode 100644 apps/vj/src/loop_splat_view.rs create mode 100644 apps/vj/src/loop_transcribe.rs create mode 100644 apps/vj/src/notes_map.rs create mode 100644 apps/vj/src/score_preview.rs diff --git a/apps/vj/Cargo.toml b/apps/vj/Cargo.toml index f542d3de2..dbf8e4251 100644 --- a/apps/vj/Cargo.toml +++ b/apps/vj/Cargo.toml @@ -18,6 +18,9 @@ default-run = "makepad-vj" [dependencies] makepad-app-asset-server = { path = "../asset-server" } makepad-widgets = { path = "../../widgets" } +makepad-score-view = { path = "../../libs/score_view" } +makepad-piano-model = { path = "../../libs/piano_model" } +makepad-drumkit = { path = "../../libs/drumkit" } makepad-asset-data = { path = "../../libs/asset/data" } # Own MP3 / Ogg Vorbis decoders for the music decks and SFX pads. makepad-audio-decode = { path = "../../libs/audio_decode" } @@ -35,7 +38,13 @@ makepad-asset-client = { path = "../../libs/asset/client" } # First-use model install (stem splitter + whisper): the asset-ai service's # resumable, sha256-verified downloader. Featureless — the same slice the # asset UI links — so none of the model backends come along. -makepad-ai-hub = { path = "../../libs/ai/hub", default-features = false } +makepad-ai-hub = { path = "../../libs/ai/hub", default-features = false, features = ["local"] } +# Hub-installed local models the DJ page runs in-process: Basic Pitch for +# the bass/melody scores, Beat This! for beats and downbeats; the shared +# install panel does download + licence acknowledgement. +makepad-ai-hub-ui = { path = "../../libs/ai/hub_ui" } +makepad-ai-notes = { path = "../../libs/ai/models/notes" } +makepad-ai-beats = { path = "../../libs/ai/models/beats" } makepad-asset-creator = { path = "../../libs/asset/creator" } # DREAM runs execute here now # The chat pane itself — ONE component, shared with the asset UI and the # game sandbox: the session on the server's chat broker, the worker thread, diff --git a/apps/vj/resources/icons/fast_forward.svg b/apps/vj/resources/icons/fast_forward.svg new file mode 100644 index 000000000..6c3f305de --- /dev/null +++ b/apps/vj/resources/icons/fast_forward.svg @@ -0,0 +1 @@ + diff --git a/apps/vj/src/apc40.rs b/apps/vj/src/apc40.rs index a90298d35..40ff356af 100644 --- a/apps/vj/src/apc40.rs +++ b/apps/vj/src/apc40.rs @@ -6,6 +6,8 @@ //! matching Makepad MIDI ports and dispatches actions to its existing cue, //! deck, and SFX engines. +use crate::loop_splat_view::{SplatCellView, SplatRowView, SplatViewModel, SPLAT_COLS, SPLAT_ROWS}; + pub const PAD_COUNT: usize = 40; pub const PAGE_SIZE: usize = PAD_COUNT; @@ -18,6 +20,11 @@ pub const NOTE_UP: u8 = 0x5e; pub const NOTE_DOWN: u8 = 0x5f; pub const NOTE_RIGHT: u8 = 0x60; pub const NOTE_LEFT: u8 = 0x61; +/// Hardware communications protocol v1.2: scene buttons are notes 0x52..0x56 +/// on channel 0; clip-stop is note 0x34 on strip channels 0..7. +pub const NOTE_SCENE_FIRST: u8 = 0x52; +pub const NOTE_SCENE_LAST: u8 = 0x56; +pub const NOTE_CLIP_STOP: u8 = 0x34; pub const CC_MASTER: u8 = 0x0e; pub const CC_CROSSFADER: u8 = 0x0f; /// Channel volume faders: CC 7 on MIDI channels 0..7. @@ -45,6 +52,16 @@ pub enum ApcAction { index: usize, pressed: bool, }, + Scene { + surface: ApcSurface, + row: u8, + pressed: bool, + }, + ClipStop { + surface: ApcSurface, + col: u8, + pressed: bool, + }, Surface(ApcSurface), VideoPlayPause, VideoStop, @@ -56,6 +73,8 @@ pub enum ApcAction { TrackKnob { index: usize, value: f32 }, /// Bottom (device) knob row. DeviceKnob { index: usize, value: f32 }, + BankLeft, + BankRight, BankChanged, } @@ -75,6 +94,23 @@ impl Apc40State { let pressed = status == 0x9 && data[2] != 0; if is_note { let note = data[1]; + let channel = data[0] & 0x0f; + if self.model == ApcModel::Apc40Mk2 { + if channel == 0 && (NOTE_SCENE_FIRST..=NOTE_SCENE_LAST).contains(¬e) { + return Some(ApcAction::Scene { + surface: self.surface, + row: note - NOTE_SCENE_FIRST, + pressed, + }); + } + if note == NOTE_CLIP_STOP && channel < 8 { + return Some(ApcAction::ClipStop { + surface: self.surface, + col: channel, + pressed, + }); + } + } if let Some(pad) = self.model.pad_index(note) { return Some(ApcAction::Pad { surface: self.surface, @@ -117,12 +153,20 @@ impl Apc40State { Some(ApcAction::BankChanged) } NOTE_LEFT => { - self.bank = self.bank.saturating_sub(self.row_step()); - Some(ApcAction::BankChanged) + if self.surface == ApcSurface::Music { + Some(ApcAction::BankLeft) + } else { + self.bank = self.bank.saturating_sub(self.row_step()); + Some(ApcAction::BankChanged) + } } NOTE_RIGHT => { - self.bank = self.bank.saturating_add(self.row_step()); - Some(ApcAction::BankChanged) + if self.surface == ApcSurface::Music { + Some(ApcAction::BankRight) + } else { + self.bank = self.bank.saturating_add(self.row_step()); + Some(ApcAction::BankChanged) + } } _ => None, }; @@ -430,6 +474,68 @@ pub fn palette_velocity(r: u8, g: u8, b: u8) -> u8 { best } +fn splat_row_rgb(row: SplatRowView, value: f32) -> (u8, u8, u8) { + let color = row.color(); + let channel = |v: f32| (v * value * 255.0).round().clamp(0.0, 255.0) as u8; + (channel(color[0]), channel(color[1]), channel(color[2])) +} + +fn splat_row_velocities(row: SplatRowView) -> (u8, u8) { + let (r, g, b) = splat_row_rgb(row, 1.0); + let full = palette_velocity(r, g, b); + let (r, g, b) = splat_row_rgb(row, 0.35); + let candidate = palette_velocity(r, g, b); + let full_rgb = PAD_PALETTE[full as usize]; + let dim_rgb = PAD_PALETTE[candidate as usize]; + let (full_h, full_s, full_v) = hsv( + (full_rgb >> 16) as u8, + (full_rgb >> 8) as u8, + full_rgb as u8, + ); + let (dim_h, dim_s, dim_v) = hsv( + (dim_rgb >> 16) as u8, + (dim_rgb >> 8) as u8, + dim_rgb as u8, + ); + let hue_delta = (full_h - dim_h).abs().min(360.0 - (full_h - dim_h).abs()); + let same_hue = if full_s < 0.18 { + dim_s < 0.18 + } else { + dim_s >= 0.30 && hue_delta <= 24.0 + }; + let dim = if same_hue && dim_v + 0.05 < full_v { + candidate + } else { + full + }; + (full, dim) +} + +pub fn splat_pad_led(cell: SplatCellView, row: SplatRowView) -> PadLed { + let (full, dim) = splat_row_velocities(row); + match cell { + SplatCellView::Empty | SplatCellView::Silent => PadLed::Off, + SplatCellView::Ready { .. } => PadLed::Color(dim), + SplatCellView::Queued { .. } => PadLed::NextColor(full), + SplatCellView::Playing { .. } => PadLed::LiveColor(full), + } +} + +pub fn splat_led_frame(model: &SplatViewModel, surface: ApcSurface) -> LedFrame { + let mut frame = LedFrame { + surface, + ..LedFrame::default() + }; + let cols = model.cols.min(SPLAT_COLS); + for row in 0..SPLAT_ROWS { + for col in 0..cols { + frame.pads[row * SPLAT_COLS + col] = + splat_pad_led(model.cells[row][col], SplatRowView::ALL[row]); + } + } + frame +} + /// Hue buckets in the dominant-colour histogram (15° each). const HUE_BUCKETS: usize = 24; /// A pixel must be at least this saturated / lit to vote for a hue. @@ -605,6 +711,95 @@ pub fn is_apc40_port(name: &str) -> bool { #[cfg(test)] mod tests { use super::*; + use crate::loop_splat::SplatPart; + + #[test] + fn scene_and_clip_stop_buttons_decode_press_and_release() { + let mut state = Apc40State { + surface: ApcSurface::Music, + ..Apc40State::default() + }; + assert_eq!( + state.decode([0x90, NOTE_SCENE_FIRST, 127]), + Some(ApcAction::Scene { + surface: ApcSurface::Music, + row: 0, + pressed: true, + }) + ); + assert_eq!( + state.decode([0x80, NOTE_SCENE_LAST, 0]), + Some(ApcAction::Scene { + surface: ApcSurface::Music, + row: 4, + pressed: false, + }) + ); + assert_eq!( + state.decode([0x93, NOTE_CLIP_STOP, 127]), + Some(ApcAction::ClipStop { + surface: ApcSurface::Music, + col: 3, + pressed: true, + }) + ); + assert_eq!( + state.decode([0x97, NOTE_CLIP_STOP, 0]), + Some(ApcAction::ClipStop { + surface: ApcSurface::Music, + col: 7, + pressed: false, + }) + ); + } + + #[test] + fn splat_rows_have_distinct_full_colours_and_dimmer_ready_colours() { + let full: Vec = SplatRowView::ALL + .iter() + .map(|row| splat_row_velocities(*row).0) + .collect(); + let unique: std::collections::HashSet = full.iter().copied().collect(); + assert_eq!(unique.len(), SPLAT_ROWS); + for row in [ + SplatRowView::Drums, + SplatRowView::Bass, + SplatRowView::Vocals, + SplatRowView::Other, + ] { + let (full, dim) = splat_row_velocities(row); + assert_ne!(dim, full, "{row:?}"); + } + let row = SplatRowView::Vocals; + let (velocity, _) = splat_row_velocities(row); + assert_eq!( + splat_pad_led( + SplatCellView::Playing { + energy: 0.8, + phase: 0.25, + part: SplatPart { num: 1, den: 2 }, + }, + row, + ), + PadLed::LiveColor(velocity) + ); + } + + #[test] + fn splat_frame_starts_at_the_top_left_pad() { + let mut model = SplatViewModel::empty(crate::loop_splat_view::SplatDeck::A); + model.cols = SPLAT_COLS; + model.cells[0][0] = SplatCellView::Playing { + energy: 1.0, + phase: 0.5, + part: SplatPart::WHOLE, + }; + let frame = splat_led_frame(&model, ApcSurface::Music); + let expected = splat_pad_led(model.cells[0][0], SplatRowView::Drums); + assert_eq!(frame.pads[0], expected); + assert_eq!(ApcModel::Apc40Mk2.pad_note(0), 32); + assert_eq!(frame.surface, ApcSurface::Music); + } #[test] fn channel_faders_and_both_knob_rows_decode() { @@ -686,6 +881,11 @@ mod tests { assert_eq!(state.bank, 40); state.clamp_bank(40); assert_eq!(state.bank, 0); + + state.surface = ApcSurface::Music; + assert_eq!(state.decode([0x90, NOTE_LEFT, 127]), Some(ApcAction::BankLeft)); + assert_eq!(state.decode([0x90, NOTE_RIGHT, 127]), Some(ApcAction::BankRight)); + assert_eq!(state.bank, 0); } #[test] @@ -873,4 +1073,3 @@ mod tests { assert!(ps > 0.3 && (80.0..170.0).contains(&ph), "green pad, got h={ph}"); } } - diff --git a/apps/vj/src/beat_eval.rs b/apps/vj/src/beat_eval.rs index 23677bb71..b9c0466ba 100644 --- a/apps/vj/src/beat_eval.rs +++ b/apps/vj/src/beat_eval.rs @@ -2131,8 +2131,26 @@ fn one_track_diagnostics() { // Where inside the analysis the period comes from, stage by stage. let envelopes = super::build_envelopes(&pcm); let hop_rate = envelopes.sample_rate / envelopes.hop as f64; - let grid = analyze(&pcm).grid; - eprintln!("published grid: {:.4} BPM, first beat {:.4}s", grid.bpm, grid.first_beat_secs); + let analysis = analyze(&pcm); + let grid = analysis.grid; + eprintln!( + "published grid: {:.4} BPM, first beat {:.4}s, downbeat phase {}, confidence {:.3}, \ + {} arrangement changes at {:?}", + grid.bpm, + grid.first_beat_secs, + grid.downbeat_phase, + grid.confidence, + analysis.changes_secs.len(), + analysis.changes_secs.iter().map(|s| (s * 10.0).round() / 10.0).collect::>(), + ); + match crate::loop_splat::build_splat(&analysis, None) { + Some(splat) => eprintln!( + "loop splat: {} sections, bars per column {:?}", + splat.sections.len(), + splat.bars_per_col + ), + None => eprintln!("loop splat: REFUSED (has_grid {}, confidence {:.3} < 0.35?)", grid.has_grid(), grid.confidence), + } let report = evaluate(&path, &pcm); let oracle_period = 60.0 / report.oracle_bpm; let beats = seconds / oracle_period; diff --git a/apps/vj/src/console_scale.rs b/apps/vj/src/console_scale.rs index 5ab18442d..81f803b37 100644 --- a/apps/vj/src/console_scale.rs +++ b/apps/vj/src/console_scale.rs @@ -114,31 +114,6 @@ pub fn console_scale(physical_width: f64, physical_height: f64, native_dpi: f64) console_dpi(physical_width, physical_height, native_dpi) / native_dpi } -/// The window width, in layout points, below which the explorer and the -/// queue stop standing side by side and take turns behind tabs. -/// -/// The queue is a fixed 320 points at every width, so the explorer gets -/// whatever is left; 560 is where its columns are already down to the narrow -/// set and the titles start losing their tails. 880 is the two together. -/// -/// On a 1.5x display with the console at its 0.75 floor that is about 990 -/// device pixels. -pub const LISTS_TAB_POINTS: f64 = 880.0; - -/// Whether the explorer and the queue have to take turns. -/// -/// `physical_width` is the width the LISTS get, not the window's — see -/// [`lists_span`]. Standing beside the decks they have about a third of it, -/// and the queue's fixed 320 points would eat almost all of that: the -/// explorer came out 36 points wide before this took the lists' own share -/// as its input. -pub fn console_lists_tabbed(physical_width: f64, physical_height: f64, native_dpi: f64) -> bool { - if !physical_width.is_finite() || !native_dpi.is_finite() || native_dpi <= 0.0 { - return false; - } - physical_width / console_dpi(physical_width, physical_height, native_dpi) < LISTS_TAB_POINTS -} - /// The physical width the LISTS get: the window, or their share of it once /// they stand beside the decks. pub fn lists_span(physical_width: f64, physical_height: f64, native_dpi: f64) -> f64 { @@ -726,32 +701,6 @@ mod tests { assert!((0.25..0.30).contains(&narrower), "{narrower} off {comfortable} to {at}"); } - #[test] - fn the_lists_take_turns_only_once_they_cannot_stand_side_by_side() { - let px = |points: f64, native: f64| points * native * MIN_SCALE; - for dpi in [1.0, 1.5, 2.0] { - let at = px(LISTS_TAB_POINTS, dpi); - assert!(!console_lists_tabbed(at + 1.0, TALL, dpi), "room for both"); - assert!(!console_lists_tabbed(at, TALL, dpi), "exactly enough is enough"); - assert!(console_lists_tabbed(at - 1.0, TALL, dpi), "not any more"); - assert!(console_lists_tabbed(300.0, TALL, dpi)); - } - // The lists give up side-by-side BEFORE the mixer joins the deck - // tabs: a console narrow enough to tab its mixer has long since had - // to choose between its two lists. - let native = 1.5; - let lists = px(LISTS_TAB_POINTS, native); - let mixer = px( - FLANKS_POINTS / 2.0 - + crate::music_view::STRIP_SWEEP_MIN - + crate::music_view::STRIP_ROW_SLACK, - native, - ); - assert!(mixer < lists, "{mixer} should come after {lists}"); - // And on the display this was specified against, about 990 pixels. - assert!((lists - 990.0).abs() < 1.0, "{lists} should be about 990 device pixels"); - } - #[test] fn the_status_bar_takes_a_second_line_only_when_its_controls_will_not_fit() { let px = |points: f64, native: f64| points * native * MIN_SCALE; @@ -839,22 +788,6 @@ mod tests { assert_ne!(console_tabs_for(span), TabStage::None); } - #[test] - fn the_lists_take_turns_once_they_are_down_to_their_share() { - // The window that prompted this: standing beside the decks, the - // lists get about a third — far too little for a 320-point queue and - // a readable explorer side by side, so they tab. - let native = 1.5; - let (w, h) = (1077.0 * native, 490.0 * native); - assert!(console_lists_beside(w, h, native)); - let span = lists_span(w, h, native); - assert!(console_lists_tabbed(span, TALL, native), "their share is {span}px"); - // Stacked, they have the window and the same call says otherwise. - let tall = 900.0 * native; - assert_eq!(lists_span(w, tall, native), w); - assert!(!console_lists_tabbed(w, TALL, native), "the whole window is plenty"); - } - #[test] fn the_mixer_is_never_hidden_while_both_panels_still_stand() { // The invariant, stated once and checked everywhere: two deck panels diff --git a/apps/vj/src/decks.rs b/apps/vj/src/decks.rs index 433a91b5d..72cd7567a 100644 --- a/apps/vj/src/decks.rs +++ b/apps/vj/src/decks.rs @@ -22,8 +22,10 @@ //! [`DeckEngine::observe`], so every sync decision in the tests is exactly //! the decision the running app makes. +use crate::loop_splat::{SplatGrid, SplatPart, SplatRow, SplatSnapshot, SPLAT_COLS}; use crate::wave_analysis::TrackGrid; use makepad_asset_data::{AssetId, AssetRevisionId, BlobId, MediaType}; +use std::sync::Arc; pub type DeckGen = u64; @@ -476,6 +478,13 @@ pub struct LoopSpan { pub end_secs: f64, } +#[derive(Clone, Debug)] +pub struct SplatUiState { + pub grid: Arc, + pub enabled: bool, + pub last: SplatSnapshot, +} + impl LoopSpan { pub fn len_secs(&self) -> f64 { self.end_secs - self.start_secs @@ -505,6 +514,9 @@ pub enum SyncMode { pub struct DeckState { pub load: DeckLoad, pub playing: bool, + /// The operator flipped the grid onto the other pulse (see + /// [`DeckEngine::flip_beat_phase`]); a second flip undoes the first. + pub phase_flipped: bool, /// Armed loop length in beats; 0 = MAN, free placement. This says what /// `[` and `]` will do NEXT and nothing else — a running manual span /// has no beat count to describe it. @@ -539,6 +551,7 @@ pub struct DeckState { pub duration_secs: f64, /// Analysed beat grid, once the worker has one. pub grid: Option, + pub splat: Option, /// Source-time playhead, mirrored from the mixer. pub position_secs: f64, /// Playback rate multiplier; 1.0 = the track's own tempo. @@ -594,6 +607,7 @@ impl Default for DeckState { load: DeckLoad::Empty, playing: false, loop_beats: 4, + phase_flipped: false, loop_span: None, loop_armed: None, loop_memory: None, @@ -606,6 +620,7 @@ impl Default for DeckState { norm_gain: 1.0, duration_secs: 0.0, grid: None, + splat: None, position_secs: 0.0, rate: 1.0, pitch: 0.0, @@ -750,6 +765,13 @@ pub enum DeckCmd { SetFilter { deck: DeckId, position: f32 }, /// One stem lane's gain, 0 = muted. SetStemGain { deck: DeckId, stem: usize, gain: f32 }, + SplatSet { deck: DeckId, grid: Arc }, + SplatEnable { deck: DeckId, on: bool }, + SplatLaunch { deck: DeckId, row: SplatRow, col: u8, part: SplatPart }, + /// `timed`: wait for the next bar; otherwise stop at once. + SplatStopRow { deck: DeckId, row: SplatRow, timed: bool }, + SplatLaunchScene { deck: DeckId, col: u8 }, + SplatStopAll { deck: DeckId, timed: bool }, /// Drop the deck's track entirely: mixer voice cleared, host mirrors /// wiped. The channel strip stands, exactly as it does across a load. UnloadTrack { deck: DeckId }, @@ -837,10 +859,82 @@ impl DeckEngine { &self.decks[id.index()] } + pub fn splat(&self, deck: DeckId) -> Option<&SplatUiState> { + self.deck(deck).splat.as_ref() + } + fn deck_mut(&mut self, id: DeckId) -> &mut DeckState { &mut self.decks[id.index()] } + pub fn splat_set(&mut self, deck: DeckId, grid: Arc) -> Vec { + if !self.deck(deck).is_loaded() { + return Vec::new(); + } + let enabled = self.splat(deck).is_some_and(|splat| splat.enabled); + let last = self.splat(deck).map(|splat| splat.last).unwrap_or_default(); + self.deck_mut(deck).splat = Some(SplatUiState { + grid: grid.clone(), + enabled, + last, + }); + vec![DeckCmd::SplatSet { deck, grid }] + } + + pub fn splat_enable(&mut self, deck: DeckId, on: bool) -> Vec { + let Some(splat) = self.deck_mut(deck).splat.as_mut() else { return Vec::new() }; + splat.enabled = on; + vec![DeckCmd::SplatEnable { deck, on }] + } + + pub fn splat_launch( + &mut self, + deck: DeckId, + row: SplatRow, + col: u8, + part: SplatPart, + ) -> Vec { + let Some(splat) = self.splat(deck) else { return Vec::new() }; + let col_index = col as usize; + if !part.is_valid() + || col_index >= SPLAT_COLS + || splat.grid.cells[row.index()][col_index].is_none_or(|cell| cell.silent) + { + return Vec::new(); + } + vec![DeckCmd::SplatLaunch { deck, row, col, part }] + } + + pub fn splat_stop_row(&mut self, deck: DeckId, row: SplatRow, timed: bool) -> Vec { + self.splat(deck) + .is_some() + .then_some(DeckCmd::SplatStopRow { deck, row, timed }) + .into_iter() + .collect() + } + + pub fn splat_scene(&mut self, deck: DeckId, col: u8) -> Vec { + if self.splat(deck).is_none() || col as usize >= SPLAT_COLS { + return Vec::new(); + } + vec![DeckCmd::SplatLaunchScene { deck, col }] + } + + pub fn splat_stop_all(&mut self, deck: DeckId, timed: bool) -> Vec { + self.splat(deck) + .is_some() + .then_some(DeckCmd::SplatStopAll { deck, timed }) + .into_iter() + .collect() + } + + pub fn observe_splat(&mut self, deck: DeckId, snapshot: Option) { + if let (Some(state), Some(snapshot)) = (self.deck_mut(deck).splat.as_mut(), snapshot) { + state.enabled = snapshot.active; + state.last = snapshot; + } + } + /// The deck a new track should land on when the caller says `Auto`: /// never the live one. Preference order — an empty deck, then a /// non-playing deck, then the deck the crossfader is turned away from, @@ -909,6 +1003,7 @@ impl DeckEngine { // sync the next load to a tempo it never had. Tone and stem knobs // stay where the operator left them, like a real channel strip. state.grid = None; + state.splat = None; state.position_secs = 0.0; state.synced = false; state.auto_opt_out = false; @@ -931,6 +1026,7 @@ impl DeckEngine { state.playing = false; state.duration_secs = duration_secs; state.position_secs = 0.0; + state.splat = None; // A span was measured against the OUTGOING track's beats and means // nothing on this one, so it goes — along with anything half-placed // or remembered. The armed LENGTH is the operator's, and stays. @@ -1526,6 +1622,7 @@ impl DeckEngine { state.playing = false; state.duration_secs = 0.0; state.grid = None; + state.splat = None; state.position_secs = 0.0; state.synced = false; state.ext_sync = false; @@ -2121,6 +2218,66 @@ impl DeckEngine { cmds } + /// Beat jump: move the playhead by whole beats of the deck's own grid. + /// A whole-beat move keeps the deck's phase, so the beat-quantized + /// re-lock that follows every seek lands it exactly where it was put. + pub fn beat_jump(&mut self, deck: DeckId, beats: f64) -> Vec { + let state = self.deck(deck); + if !state.is_loaded() || !beats.is_finite() { + return Vec::new(); + } + let beat_secs = state + .grid + .filter(|grid| grid.has_grid()) + .map(|grid| grid.beat_secs) + .unwrap_or(0.5); + let secs = state.position_secs + beats * beat_secs; + self.seek_secs(deck, secs) + } + + /// Flip the deck's grid half a beat. The analyser's known failure mode + /// is a perfectly steady grid on the OFF pulse: same tempo, every ruling + /// on a real transient, and sync then holds the two tracks exactly half + /// a beat apart. Moving every ruling by half a beat puts the grid on the + /// other pulse; the caller re-publishes the flipped grid wherever else + /// it lives (analysis, loop grid, cache). Returns the flipped grid. + pub fn flip_beat_phase(&mut self, deck: DeckId) -> Option<(TrackGrid, Vec)> { + let state = self.deck_mut(deck); + let grid = state.grid.as_mut()?; + if !grid.has_grid() { + return None; + } + // The rulings land in the same places either way; which way the + // DOWNBEAT moves is the choice. Forward the first time, back the + // second, so two presses are exactly no presses. + let half = grid.beat_secs * 0.5; + if state.phase_flipped { + grid.first_beat_secs -= half; + if grid.first_beat_secs < 0.0 { + // The first ruling at or after zero is now the old first + // beat's successor, one beat later in the bar. + grid.first_beat_secs += grid.beat_secs; + grid.downbeat_phase = (grid.downbeat_phase + 1) % 4; + } + } else { + grid.first_beat_secs += half; + if grid.first_beat_secs >= grid.beat_secs { + // The first ruling at or after zero is now the one BEFORE + // the old first beat, one beat earlier in the bar. + grid.first_beat_secs -= grid.beat_secs; + grid.downbeat_phase = (grid.downbeat_phase + 3) % 4; + } + } + state.phase_flipped = !state.phase_flipped; + let flipped = *grid; + let cmds = if self.deck(deck).synced || self.auto_sync { + self.apply_auto_sync_with(Some(SyncQuantize::Beat)) + } else { + Vec::new() + }; + Some((flipped, cmds)) + } + /// The phase a snapped landing must preserve: the one that SURVIVES. /// Every seek is followed by a beat-quantized auto-sync re-lock, so on /// a follower deck the deck's own playhead phase is about to be @@ -3270,6 +3427,55 @@ mod tests { assert!((plan.rate - 1.0).abs() < 1e-9, "rate {}", plan.rate); } + #[test] + fn flipping_the_pulse_moves_every_ruling_half_a_beat_and_keeps_the_bars() { + let mut engine = DeckEngine::new(); + let (deck, gen) = load_gen(&engine.click(item(1), DeckTarget::A)); + engine.track_ready(deck, gen, 240.0); + // 120 BPM, first beat at 0.4 s and it is beat 2 of its bar. + let grid = TrackGrid { + bpm: 120.0, + beat_secs: 0.5, + first_beat_secs: 0.4, + downbeat_phase: 2, + confidence: 0.9, + }; + engine.grid_ready(DeckId::A, gen, grid); + let (flipped, _) = engine.flip_beat_phase(DeckId::A).expect("a grid to flip"); + // 0.4 + 0.25 = 0.65 wraps to 0.15: the ruling before the old first + // beat, one beat earlier in the bar. + assert!((flipped.first_beat_secs - 0.15).abs() < 1e-9, "{flipped:?}"); + assert_eq!(flipped.downbeat_phase, 1); + // The downbeat's absolute time moved by exactly half a beat. + let old_downbeat: f64 = 0.4 + 2.0 * 0.5; + let new_downbeat = 0.15 + 3.0 * 0.5; + assert!((new_downbeat - old_downbeat).abs() - 0.25 < 1e-9); + // Flipping again goes BACK half a beat: exactly the original grid, + // bars included. + let (again, _) = engine.flip_beat_phase(DeckId::A).unwrap(); + assert!((again.first_beat_secs - 0.4).abs() < 1e-9, "{again:?}"); + assert_eq!(again.downbeat_phase, 2); + assert!(!engine.deck(DeckId::A).phase_flipped); + } + + #[test] + fn a_beat_jump_moves_by_whole_beats_of_the_decks_grid() { + let mut engine = DeckEngine::new(); + let (deck, gen) = load_gen(&engine.click(item(1), DeckTarget::A)); + engine.track_ready(deck, gen, 240.0); + engine.grid_ready( + DeckId::A, + gen, + TrackGrid { bpm: 120.0, beat_secs: 0.5, first_beat_secs: 0.0, downbeat_phase: 0, confidence: 0.9 }, + ); + engine.seek_secs(DeckId::A, 10.0); + let cmds = engine.beat_jump(DeckId::A, 16.0); + assert!(cmds.iter().any(|cmd| matches!(cmd, DeckCmd::SeekSeconds { secs, .. } if (*secs - 18.0).abs() < 1e-9)), "{cmds:?}"); + assert!((engine.deck(DeckId::A).position_secs - 18.0).abs() < 1e-9); + engine.beat_jump(DeckId::A, -64.0); + assert_eq!(engine.deck(DeckId::A).position_secs, 0.0, "clamped at the start"); + } + #[test] fn a_bar_sync_lands_on_a_downbeat() { let leader = SyncView { grid: grid(120.0, 0.0), position_secs: 8.0, rate: 1.0 }; diff --git a/apps/vj/src/loop_blocks.rs b/apps/vj/src/loop_blocks.rs new file mode 100644 index 000000000..58840ada3 --- /dev/null +++ b/apps/vj/src/loop_blocks.rs @@ -0,0 +1,109 @@ +//! Pure conversion from loop transcriptions to compact splat-cell rolls. + +use makepad_score_view::build::{DrumHit, DrumVoice, PitchedNote}; + +#[derive(Clone, Debug, PartialEq)] +pub struct CellBlocks { + pub bars: u8, + pub blocks: Vec, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct Block { + pub start_beats: f32, + pub len_beats: f32, + /// Bottom-up lane index. + pub lane: u8, + pub lanes: u8, + pub velocity: f32, +} + +pub fn drum_blocks(hits: &[DrumHit], bars: u8) -> CellBlocks { + let blocks = hits + .iter() + .map(|hit| Block { + start_beats: hit.time_beats as f32, + len_beats: 0.125, + lane: match hit.voice { + DrumVoice::Kick => 0, + DrumVoice::Snare | DrumVoice::SideStick => 1, + DrumVoice::HiHatClosed | DrumVoice::HiHatOpen | DrumVoice::HiHatPedal => 2, + DrumVoice::TomHigh + | DrumVoice::TomMid + | DrumVoice::TomLow + | DrumVoice::TomFloor => 3, + DrumVoice::Ride | DrumVoice::RideBell | DrumVoice::Crash => 4, + }, + lanes: 5, + velocity: hit.velocity.clamp(0.0, 1.0), + }) + .collect(); + CellBlocks { bars, blocks } +} + +pub fn pitched_blocks(notes: &[PitchedNote], bars: u8) -> CellBlocks { + let Some((min_midi, max_midi)) = notes + .iter() + .map(|note| note.midi) + .min() + .zip(notes.iter().map(|note| note.midi).max()) + else { + return CellBlocks { bars, blocks: Vec::new() }; + }; + let lanes = max_midi.saturating_sub(min_midi).saturating_add(1).clamp(1, 24); + let blocks = notes + .iter() + .map(|note| Block { + start_beats: note.onset_beats as f32, + len_beats: note.duration_beats.max(0.0) as f32, + lane: note.midi.saturating_sub(min_midi).min(lanes - 1), + lanes, + velocity: note.velocity.clamp(0.0, 1.0), + }) + .collect(); + CellBlocks { bars, blocks } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn drum_lane_assignment_groups_voices_bottom_to_top() { + let hits = [ + DrumHit { time_beats: 0.0, voice: DrumVoice::Kick, velocity: 0.5 }, + DrumHit { time_beats: 0.5, voice: DrumVoice::Snare, velocity: 0.5 }, + DrumHit { time_beats: 1.0, voice: DrumVoice::HiHatOpen, velocity: 0.5 }, + DrumHit { time_beats: 1.5, voice: DrumVoice::TomFloor, velocity: 0.5 }, + DrumHit { time_beats: 2.0, voice: DrumVoice::Crash, velocity: 0.5 }, + ]; + let result = drum_blocks(&hits, 4); + assert_eq!(result.bars, 4); + assert_eq!(result.blocks.iter().map(|block| block.lane).collect::>(), [0, 1, 2, 3, 4]); + assert!(result.blocks.iter().all(|block| block.lanes == 5 && block.len_beats == 0.125)); + } + + #[test] + fn pitched_lanes_follow_local_range_and_clamp_to_twenty_four() { + let notes = [ + PitchedNote { onset_beats: 0.0, duration_beats: 0.5, midi: 20, velocity: 0.2 }, + PitchedNote { onset_beats: 0.5, duration_beats: 1.0, midi: 32, velocity: 0.6 }, + PitchedNote { onset_beats: 1.5, duration_beats: 1.5, midi: 80, velocity: 1.2 }, + ]; + let result = pitched_blocks(¬es, 2); + assert_eq!(result.blocks.iter().map(|block| block.lanes).collect::>(), [24; 3]); + assert_eq!(result.blocks.iter().map(|block| block.lane).collect::>(), [0, 12, 23]); + assert_eq!(result.blocks[2].velocity, 1.0); + } + + #[test] + fn single_pitch_and_empty_input_have_stable_lane_counts() { + let note = PitchedNote { onset_beats: 0.0, duration_beats: 1.0, midi: 64, velocity: 0.7 }; + let single = pitched_blocks(&[note], 1); + assert_eq!((single.blocks[0].lane, single.blocks[0].lanes), (0, 1)); + + let empty = pitched_blocks(&[], 8); + assert_eq!(empty, CellBlocks { bars: 8, blocks: Vec::new() }); + assert_eq!(drum_blocks(&[], 2), CellBlocks { bars: 2, blocks: Vec::new() }); + } +} diff --git a/apps/vj/src/loop_splat.rs b/apps/vj/src/loop_splat.rs new file mode 100644 index 000000000..5c57c3c7e --- /dev/null +++ b/apps/vj/src/loop_splat.rs @@ -0,0 +1,528 @@ +//! Beat-quantized loop-splat slicing. +//! +//! The slicer first enumerates only complete 4/4 bars from the analysed +//! downbeat grid. Arrangement changes are snapped to those bars, nudged to +//! nearby four-bar phrase boundaries, and reduced to seven cuts by greedy +//! farthest-point selection. Missing cuts are filled by repeatedly splitting +//! the longest eligible section at a four-bar boundary. Each stem then picks +//! the densest steady power-of-two loop in its section; the mix uses the +//! section head. All results stay in source seconds so callers can precompute +//! the exact frame-domain representation for their own source rate. + +use crate::decks::LoopSpan; +use crate::music_dsp::{StemKind, STEM_COUNT}; +use crate::wave_analysis::{TrackAnalysis, ZOOM_COLS_PER_SEC}; + +pub const SPLAT_COLS: usize = 8; +pub const SPLAT_ROWS: usize = 5; +/// `TrackGrid::confidence` measures how many rulings sit on a SHARP onset, +/// not whether the grid is right: a piano-and-strings record with a +/// 0.996-F grid against the reference scores 0.28 because its onsets are +/// soft. So this only keeps out the no-rhythm case (silence and noise score +/// near zero); the per-cell energy gate decides what is actually loopable. +const MIN_GRID_CONFIDENCE: f32 = 0.12; + +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub struct SplatPart { + pub num: u8, + pub den: u8, +} + +impl SplatPart { + pub const WHOLE: Self = Self { num: 0, den: 1 }; + + pub const fn is_valid(self) -> bool { + matches!(self.den, 1 | 2 | 4) && self.num < self.den + } +} + +impl Default for SplatPart { + fn default() -> Self { + Self::WHOLE + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +#[repr(usize)] +pub enum SplatRow { + Drums = 0, + Bass = 1, + Vocals = 2, + Other = 3, + Mix = 4, +} + +impl SplatRow { + pub const ALL: [SplatRow; SPLAT_ROWS] = [ + SplatRow::Drums, + SplatRow::Bass, + SplatRow::Vocals, + SplatRow::Other, + SplatRow::Mix, + ]; + + pub fn stem(self) -> Option { + match self { + SplatRow::Drums => Some(StemKind::Drums), + SplatRow::Bass => Some(StemKind::Bass), + SplatRow::Vocals => Some(StemKind::Vocals), + SplatRow::Other => Some(StemKind::Other), + SplatRow::Mix => None, + } + } + + pub fn index(self) -> usize { + self as usize + } + + pub fn from_index(index: usize) -> Option { + Self::ALL.get(index).copied() + } +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct SplatCell { + /// Source seconds, aligned to whole bars. + pub span: LoopSpan, + pub bars: u8, + pub energy: f32, + /// A stem with negligible activity in this section is not launchable. + pub silent: bool, +} + +#[derive(Clone, Debug, PartialEq)] +pub struct SplatSection { + pub start_secs: f64, + pub end_secs: f64, + pub bars: u32, +} + +#[derive(Clone, Debug, PartialEq)] +pub struct SplatGrid { + pub bpm: f64, + pub bar_secs: f64, + pub first_bar_secs: f64, + pub sections: Vec, + pub cells: [[Option; SPLAT_COLS]; SPLAT_ROWS], + pub bars_per_col: [u8; SPLAT_COLS], +} + +/// Per-beat mean level per stem. Beat `i` begins at +/// `first_beat_secs + i * beat_secs`. +#[derive(Clone, Debug, Default)] +pub struct StemLevels { + pub beat_secs: f64, + pub first_beat_secs: f64, + pub levels: [Vec; STEM_COUNT], +} + +impl StemLevels { + /// Build per-beat stereo RMS without depending on the mixer's stem table. + /// The callback returns an unscaled floating-point frame for one lane; + /// `None` represents a missing frame and contributes silence. + pub fn from_stems( + beat_secs: f64, + first_beat_secs: f64, + sample_rate: u32, + frame_count: usize, + mut frame: F, + ) -> Self + where + F: FnMut(StemKind, usize) -> Option<[f32; 2]>, + { + let rate = sample_rate.max(1) as f64; + if !beat_secs.is_finite() || beat_secs <= 0.0 || frame_count == 0 { + return Self { beat_secs, first_beat_secs, ..Self::default() }; + } + let duration = frame_count as f64 / rate; + let beat_count = ((duration - first_beat_secs).max(0.0) / beat_secs).ceil() as usize; + let mut levels: [Vec; STEM_COUNT] = std::array::from_fn(|_| { + Vec::with_capacity(beat_count) + }); + for stem in StemKind::ALL { + for beat in 0..beat_count { + let start_secs = first_beat_secs + beat as f64 * beat_secs; + let end_secs = (start_secs + beat_secs).min(duration); + let start = (start_secs.max(0.0) * rate).floor() as usize; + let end = (end_secs.max(0.0) * rate).ceil() as usize; + let mut sum = 0.0f64; + let count = end.saturating_sub(start); + for index in start..end.min(frame_count) { + if let Some(value) = frame(stem, index) { + sum += (value[0] as f64 * value[0] as f64 + + value[1] as f64 * value[1] as f64) + * 0.5; + } + } + levels[stem.index()].push(if count == 0 { + 0.0 + } else { + (sum / count as f64).sqrt() as f32 + }); + } + } + Self { beat_secs, first_beat_secs, levels } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Default)] +pub struct SplatSnapshot { + pub active: bool, + pub playing: [Option<(u8, SplatPart)>; SPLAT_ROWS], + pub queued: [Option<(u8, SplatPart)>; SPLAT_ROWS], + pub bar_index: i64, + pub bar_phase: f32, + pub row_phase: [f32; SPLAT_ROWS], +} + +/// Build a deterministic section grid. A weak beat grid, invalid timing, or +/// fewer than two complete bars cannot produce a splat. +pub fn build_splat( + analysis: &TrackAnalysis, + stem_levels: Option<&StemLevels>, +) -> Option { + let track_grid = analysis.grid; + if !track_grid.has_grid() + || track_grid.confidence < MIN_GRID_CONFIDENCE + || !analysis.duration_secs.is_finite() + || analysis.duration_secs <= 0.0 + { + return None; + } + let bar_secs = track_grid.beat_secs * 4.0; + if !bar_secs.is_finite() || bar_secs <= 0.0 { + return None; + } + let bar_zero = track_grid.first_beat_secs + - track_grid.downbeat_phase as f64 * track_grid.beat_secs; + let first_index = ((-bar_zero) / bar_secs - 1e-10).ceil(); + let first_bar_secs = bar_zero + first_index * bar_secs; + let whole_bars = ((analysis.duration_secs - first_bar_secs + 1e-10) / bar_secs) + .floor() + .max(0.0) as u32; + if whole_bars < 2 { + return None; + } + + let mut boundaries: Vec = analysis + .changes_secs + .iter() + .copied() + .filter(|secs| secs.is_finite()) + .map(|secs| ((secs - first_bar_secs) / bar_secs).round() as i64) + .filter_map(|bar| { + if bar < 0 { + return None; + } + let bar = bar as u32; + let phrase = ((bar as f64 / 4.0).round() as i64 * 4).max(0) as u32; + let bar = if bar.abs_diff(phrase) <= 1 { phrase } else { bar }; + (bar >= 2 && whole_bars.saturating_sub(bar) >= 2).then_some(bar) + }) + .collect(); + boundaries.sort_unstable(); + boundaries.dedup(); + + if boundaries.len() > SPLAT_COLS - 1 { + boundaries = farthest_boundaries(&boundaries, SPLAT_COLS - 1); + } + while boundaries.len() < SPLAT_COLS - 1 { + let mut edges = Vec::with_capacity(boundaries.len() + 2); + edges.push(0); + edges.extend(boundaries.iter().copied()); + edges.push(whole_bars); + let Some((start, end)) = edges + .windows(2) + .map(|pair| (pair[0], pair[1])) + .filter(|(start, end)| end - start >= 8) + .max_by_key(|(start, end)| (end - start, std::cmp::Reverse(*start))) + else { + break; + }; + let midpoint = (start + end) as f64 * 0.5; + let mut split = ((midpoint / 4.0).round() as u32) * 4; + split = split.clamp(start + 4, end - 4); + if boundaries.binary_search(&split).is_ok() { + break; + } + boundaries.push(split); + boundaries.sort_unstable(); + } + + let mut edges = Vec::with_capacity(boundaries.len() + 2); + edges.push(0); + edges.extend(boundaries); + edges.push(whole_bars); + let sections: Vec = edges + .windows(2) + .map(|pair| SplatSection { + start_secs: first_bar_secs + pair[0] as f64 * bar_secs, + end_secs: first_bar_secs + pair[1] as f64 * bar_secs, + bars: pair[1] - pair[0], + }) + .collect(); + let mut grid = SplatGrid { + bpm: track_grid.bpm, + bar_secs, + first_bar_secs, + sections, + cells: [[None; SPLAT_COLS]; SPLAT_ROWS], + bars_per_col: [0; SPLAT_COLS], + }; + for col in 0..grid.sections.len() { + let bars = largest_power_of_two(grid.sections[col].bars.min(4) as u8); + rebuild_column(&mut grid, analysis, stem_levels, col, bars); + } + Some(grid) +} + +fn largest_power_of_two(value: u8) -> u8 { + if value == 0 { + 0 + } else { + 1 << (7 - value.leading_zeros() as u8) + } +} + +fn farthest_boundaries(candidates: &[u32], keep: usize) -> Vec { + if candidates.len() <= keep { + return candidates.to_vec(); + } + let mut selected = vec![candidates[0], *candidates.last().unwrap()]; + while selected.len() < keep { + let next = candidates + .iter() + .copied() + .filter(|candidate| !selected.contains(candidate)) + .max_by_key(|candidate| { + let spacing = selected + .iter() + .map(|picked| candidate.abs_diff(*picked)) + .min() + .unwrap_or(0); + (spacing, std::cmp::Reverse(*candidate)) + }); + let Some(next) = next else { break }; + selected.push(next); + } + selected.sort_unstable(); + selected +} + +fn rebuild_column( + grid: &mut SplatGrid, + analysis: &TrackAnalysis, + stem_levels: Option<&StemLevels>, + col: usize, + bars: u8, +) { + let Some(section) = grid.sections.get(col).cloned() else { return }; + grid.bars_per_col[col] = bars; + let len_secs = bars as f64 * grid.bar_secs; + let mix_energy = mix_energy(analysis, section.start_secs, section.start_secs + len_secs); + grid.cells[SplatRow::Mix.index()][col] = Some(SplatCell { + span: LoopSpan { + start_secs: section.start_secs, + end_secs: section.start_secs + len_secs, + }, + bars, + energy: mix_energy, + silent: false, + }); + + for row in SplatRow::ALL.into_iter().filter(|row| row.stem().is_some()) { + let (start_secs, energy, silent) = match stem_levels { + Some(levels) => choose_stem_window(levels, row.stem().unwrap(), §ion, bars, grid.bar_secs), + None => (section.start_secs, mix_energy, false), + }; + grid.cells[row.index()][col] = Some(SplatCell { + span: LoopSpan { start_secs, end_secs: start_secs + len_secs }, + bars, + energy, + silent, + }); + } +} + +fn mix_energy(analysis: &TrackAnalysis, start_secs: f64, end_secs: f64) -> f32 { + if analysis.tiles.zoom.is_empty() { + return 0.5; + } + let start = (start_secs * ZOOM_COLS_PER_SEC).floor().max(0.0) as usize; + let end = (end_secs * ZOOM_COLS_PER_SEC).ceil().max(start as f64 + 1.0) as usize; + let end = end.min(analysis.tiles.zoom.len()); + if start >= end { + return 0.0; + } + analysis.tiles.zoom[start..end] + .iter() + .map(|column| column[3] as f32 / 255.0) + .sum::() + / (end - start) as f32 +} + +fn choose_stem_window( + levels: &StemLevels, + stem: StemKind, + section: &SplatSection, + bars: u8, + bar_secs: f64, +) -> (f64, f32, bool) { + let lane = &levels.levels[stem.index()]; + let p95 = percentile_95(lane); + let whole = level_stats(levels, lane, section.start_secs, section.end_secs).0; + let silent = p95 <= f32::EPSILON || whole < p95 * 0.08; + let windows = section.bars.saturating_sub(bars as u32) + 1; + let mut best = (f32::NEG_INFINITY, section.start_secs, 0.0f32); + for offset in 0..windows { + let start = section.start_secs + offset as f64 * bar_secs; + let (mean, std_dev) = level_stats(levels, lane, start, start + bars as f64 * bar_secs); + let score = mean - 0.5 * std_dev; + if score > best.0 + 1e-7 { + best = (score, start, mean); + } + } + let energy = if p95 > f32::EPSILON { + (best.2 / p95).clamp(0.0, 1.0) + } else { + 0.0 + }; + (best.1, energy, silent) +} + +fn level_stats(levels: &StemLevels, lane: &[f32], start_secs: f64, end_secs: f64) -> (f32, f32) { + if lane.is_empty() || levels.beat_secs <= 0.0 { + return (0.0, 0.0); + } + let start = ((start_secs - levels.first_beat_secs) / levels.beat_secs) + .round() + .max(0.0) as usize; + let end = ((end_secs - levels.first_beat_secs) / levels.beat_secs) + .round() + .max(start as f64 + 1.0) as usize; + let end = end.min(lane.len()); + if start >= end { + return (0.0, 0.0); + } + let slice = &lane[start..end]; + let mean = slice.iter().copied().sum::() / slice.len() as f32; + let variance = slice + .iter() + .map(|value| { + let delta = *value - mean; + delta * delta + }) + .sum::() + / slice.len() as f32; + (mean, variance.sqrt()) +} + +fn percentile_95(values: &[f32]) -> f32 { + if values.is_empty() { + return 0.0; + } + let mut sorted = values.to_vec(); + sorted.sort_by(|a, b| a.total_cmp(b)); + let index = ((sorted.len() as f64 * 0.95).ceil() as usize) + .saturating_sub(1) + .min(sorted.len() - 1); + sorted[index] +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::wave_analysis::{TempoMap, TrackGrid, WaveTiles}; + + fn analysis(duration_secs: f64, changes_secs: Vec, confidence: f32) -> TrackAnalysis { + TrackAnalysis { + duration_secs, + sample_rate: 48_000, + grid: TrackGrid { + bpm: 120.0, + beat_secs: 0.5, + first_beat_secs: 0.25, + downbeat_phase: 0, + confidence, + }, + tempo_map: TempoMap::default(), + tiles: WaveTiles { + zoom: vec![[0, 0, 0, 128]; (duration_secs * ZOOM_COLS_PER_SEC) as usize], + overview: Vec::new(), + }, + changes_secs, + } + } + + #[test] + fn sections_are_complete_contiguous_bar_spans() { + let source = analysis(200.0, vec![17.9, 34.2, 65.0, 97.0, 130.0, 163.0], 0.9); + let grid = build_splat(&source, None).unwrap(); + assert!(grid.sections.len() <= SPLAT_COLS); + assert_eq!(grid.sections.first().unwrap().start_secs, grid.first_bar_secs); + for pair in grid.sections.windows(2) { + assert!((pair[0].end_secs - pair[1].start_secs).abs() < 1e-9); + } + for section in &grid.sections { + let bars = (section.start_secs - grid.first_bar_secs) / grid.bar_secs; + assert!((bars - bars.round()).abs() < 1e-9); + assert!((section.end_secs - section.start_secs - section.bars as f64 * grid.bar_secs).abs() < 1e-9); + } + for col in 0..grid.sections.len() { + let bars = grid.bars_per_col[col]; + assert!(bars.is_power_of_two() && bars <= 8); + assert!(bars as u32 <= grid.sections[col].bars); + } + } + + #[test] + fn dense_steady_window_and_silence_are_detected() { + let source = analysis(128.25, vec![], 0.9); + let beat_count = 256; + let mut levels = StemLevels { + beat_secs: 0.5, + first_beat_secs: 0.25, + levels: std::array::from_fn(|_| vec![0.1; beat_count]), + }; + // First section is split to eight bars. Its four bars starting at + // bar two are the unique dense, steady drums window. + for beat in 8..24 { + levels.levels[StemKind::Drums.index()][beat] = 0.8; + } + levels.levels[StemKind::Vocals.index()].fill(0.01); + for beat in 80..100 { + levels.levels[StemKind::Vocals.index()][beat] = 1.0; + } + let grid = build_splat(&source, Some(&levels)).unwrap(); + let drums = grid.cells[SplatRow::Drums.index()][0].unwrap(); + assert!((drums.span.start_secs - (grid.first_bar_secs + 2.0 * grid.bar_secs)).abs() < 1e-9); + assert!(!drums.silent); + let vocals = grid.cells[SplatRow::Vocals.index()][0].unwrap(); + assert!(vocals.silent); + } + + #[test] + fn degenerate_and_many_change_inputs_are_bounded() { + assert!(build_splat(&analysis(200.0, vec![], 0.0), None).is_none()); + assert!(build_splat(&analysis(4.24, vec![], 0.9), None).is_none()); + let three_bars = build_splat(&analysis(6.25, vec![], 0.9), None).unwrap(); + assert_eq!(three_bars.sections.iter().map(|section| section.bars).sum::(), 3); + let empty = build_splat(&analysis(200.0, vec![], 0.9), None).unwrap(); + assert!(!empty.sections.is_empty()); + let changes = (1..=40).map(|index| index as f64 * 4.1).collect(); + let many = build_splat(&analysis(200.0, changes, 0.9), None).unwrap(); + assert!(many.sections.len() <= SPLAT_COLS); + assert_eq!(many.sections.len(), SPLAT_COLS); + } + + #[test] + fn stem_levels_builder_uses_per_beat_rms() { + let levels = StemLevels::from_stems(0.5, 0.0, 8, 8, |stem, frame| { + let value = if stem == StemKind::Bass && frame < 4 { 0.5 } else { 0.0 }; + Some([value, value]) + }); + assert_eq!(levels.levels[StemKind::Bass.index()].len(), 2); + assert!((levels.levels[StemKind::Bass.index()][0] - 0.5).abs() < 1e-6); + assert_eq!(levels.levels[StemKind::Bass.index()][1], 0.0); + } +} diff --git a/apps/vj/src/loop_splat_model.rs b/apps/vj/src/loop_splat_model.rs new file mode 100644 index 000000000..86fefcc9b --- /dev/null +++ b/apps/vj/src/loop_splat_model.rs @@ -0,0 +1,269 @@ +//! Pure mapping from the loop-splat engine state to the compact grid view. + +use crate::decks::DeckId; +use crate::loop_splat::{SplatGrid, SplatRow, SplatSnapshot, SPLAT_COLS}; +use crate::loop_splat_view::{SplatCellView, SplatDeck, SplatRowView, SplatViewModel}; + +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] +pub struct SplatCoverage { + pub stems_present: bool, + /// Model-rate frames separated so far (`StemsMsg::Coverage.model_frames`). + pub covered_frames: usize, + pub complete: bool, + pub model_rate: u32, +} + +pub fn splat_deck(deck: DeckId) -> SplatDeck { + match deck { + DeckId::A => SplatDeck::A, + DeckId::B => SplatDeck::B, + } +} + +pub fn splat_row(row: SplatRowView) -> SplatRow { + match row { + SplatRowView::Drums => SplatRow::Drums, + SplatRowView::Bass => SplatRow::Bass, + SplatRowView::Vocals => SplatRow::Vocals, + SplatRowView::Other => SplatRow::Other, + SplatRowView::Mix => SplatRow::Mix, + } +} + +pub fn splat_view_model( + deck: DeckId, + grid: &SplatGrid, + enabled: bool, + snapshot: Option<&SplatSnapshot>, + coverage: &SplatCoverage, + duration_secs: f64, +) -> SplatViewModel { + let mut model = SplatViewModel::empty(splat_deck(deck)); + model.enabled = snapshot.map_or(enabled, |snapshot| snapshot.active); + model.cols = grid.sections.len(); + model.col_bars = grid.bars_per_col; + model.duration_secs = if duration_secs.is_finite() { + duration_secs.clamp(0.0, f32::MAX as f64) as f32 + } else { + 0.0 + }; + for (target, section) in model.col_start_secs.iter_mut().zip(&grid.sections) { + *target = section.start_secs; + } + model.bar_phase = snapshot.map_or(0.0, |snapshot| snapshot.bar_phase); + + for (row_index, row) in SplatRow::ALL.into_iter().enumerate() { + for col in 0..SPLAT_COLS { + let Some(cell) = grid.cells[row_index][col] else { continue }; + model.spans[row_index][col] = ( + cell.span.start_secs as f32, + cell.span.len_secs().max(0.0) as f32, + ); + if row.stem().is_some() + && (!coverage.stems_present + || cell.span.end_secs * coverage.model_rate as f64 + > coverage.covered_frames as f64) + { + continue; + } + if cell.silent { + model.cells[row_index][col] = SplatCellView::Silent; + continue; + } + model.cells[row_index][col] = match snapshot { + Some(snapshot) + if snapshot.playing[row_index] + .is_some_and(|(playing_col, _)| playing_col == col as u8) => + { + let (_, part) = snapshot.playing[row_index].unwrap(); + SplatCellView::Playing { + energy: cell.energy, + phase: snapshot.row_phase[row_index], + part, + } + } + Some(snapshot) + if snapshot.queued[row_index] + .is_some_and(|(queued_col, _)| queued_col == col as u8) => + { + let (_, part) = snapshot.queued[row_index].unwrap(); + SplatCellView::Queued { energy: cell.energy, part } + } + _ => SplatCellView::Ready { energy: cell.energy }, + }; + } + } + model +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::decks::LoopSpan; + use crate::loop_splat::{SplatCell, SplatPart, SplatSection, SPLAT_ROWS}; + + fn cell(start_secs: f64, end_secs: f64, energy: f32, silent: bool) -> SplatCell { + SplatCell { + span: LoopSpan { start_secs, end_secs }, + bars: 1, + energy, + silent, + } + } + + fn grid(cols: usize) -> SplatGrid { + let sections = (0..cols) + .map(|col| SplatSection { + start_secs: col as f64 * 2.0, + end_secs: (col + 1) as f64 * 2.0, + bars: 1, + }) + .collect(); + let mut bars_per_col = [0; SPLAT_COLS]; + bars_per_col[..cols].fill(1); + SplatGrid { + bpm: 120.0, + bar_secs: 2.0, + first_bar_secs: 0.0, + sections, + cells: [[None; SPLAT_COLS]; SPLAT_ROWS], + bars_per_col, + } + } + + fn coverage(covered_frames: usize) -> SplatCoverage { + SplatCoverage { + stems_present: true, + covered_frames, + complete: false, + model_rate: 10, + } + } + + #[test] + fn coverage_gates_stems_but_never_the_mix() { + let mut grid = grid(2); + grid.cells[SplatRow::Drums.index()][0] = Some(cell(0.0, 2.0, 0.6, false)); + grid.cells[SplatRow::Drums.index()][1] = Some(cell(2.0, 4.0, 0.7, false)); + grid.cells[SplatRow::Mix.index()][1] = Some(cell(2.0, 4.0, 0.8, false)); + + let model = splat_view_model(DeckId::A, &grid, false, None, &coverage(20), 4.0); + assert_eq!(model.cells[SplatRow::Drums.index()][0], SplatCellView::Ready { energy: 0.6 }); + assert_eq!(model.cells[SplatRow::Drums.index()][1], SplatCellView::Empty); + assert_eq!(model.cells[SplatRow::Mix.index()][1], SplatCellView::Ready { energy: 0.8 }); + + let no_stems = SplatCoverage { stems_present: false, ..coverage(usize::MAX) }; + let model = splat_view_model(DeckId::A, &grid, false, None, &no_stems, 4.0); + assert_eq!(model.cells[SplatRow::Drums.index()][0], SplatCellView::Empty); + assert_eq!(model.cells[SplatRow::Mix.index()][1], SplatCellView::Ready { energy: 0.8 }); + } + + #[test] + fn playing_precedes_queued_and_snapshot_owns_enabled_and_phase() { + let mut grid = grid(2); + let row = SplatRow::Bass.index(); + grid.cells[row][0] = Some(cell(0.0, 2.0, 0.4, false)); + grid.cells[row][1] = Some(cell(2.0, 4.0, 0.9, false)); + let mut snapshot = SplatSnapshot { + active: true, + bar_phase: 0.3, + ..SplatSnapshot::default() + }; + let playing_part = SplatPart { num: 1, den: 2 }; + let queued_part = SplatPart { num: 3, den: 4 }; + snapshot.playing[row] = Some((0, playing_part)); + snapshot.queued[row] = Some((0, SplatPart::WHOLE)); + snapshot.row_phase[row] = 0.75; + let vocals = SplatRow::Vocals.index(); + grid.cells[vocals][1] = Some(cell(2.0, 4.0, 0.5, false)); + snapshot.queued[vocals] = Some((1, queued_part)); + + let model = splat_view_model( + DeckId::B, + &grid, + false, + Some(&snapshot), + &coverage(usize::MAX), + 4.0, + ); + assert!(model.enabled); + assert_eq!(model.bar_phase, 0.3); + assert_eq!( + model.cells[row][0], + SplatCellView::Playing { + energy: 0.4, + phase: 0.75, + part: playing_part, + } + ); + assert_eq!( + model.cells[vocals][1], + SplatCellView::Queued { energy: 0.5, part: queued_part } + ); + } + + #[test] + fn silent_cells_remain_silent() { + let mut grid = grid(1); + let row = SplatRow::Other.index(); + grid.cells[row][0] = Some(cell(0.0, 2.0, 0.1, true)); + let mut snapshot = SplatSnapshot::default(); + snapshot.playing[row] = Some((0, SplatPart::WHOLE)); + let model = splat_view_model( + DeckId::A, + &grid, + true, + Some(&snapshot), + &coverage(usize::MAX), + 2.0, + ); + assert_eq!(model.cells[row][0], SplatCellView::Silent); + } + + #[test] + fn columns_and_section_starts_are_copied() { + let mut grid = grid(3); + grid.bars_per_col[..3].copy_from_slice(&[1, 2, 4]); + let model = splat_view_model(DeckId::B, &grid, true, None, &coverage(0), 6.25); + assert_eq!(model.deck, SplatDeck::B); + assert_eq!(model.cols, 3); + assert_eq!(&model.col_bars[..3], &[1, 2, 4]); + assert_eq!(&model.col_start_secs[..3], &[0.0, 2.0, 4.0]); + assert_eq!(model.duration_secs, 6.25); + } + + #[test] + fn cell_spans_are_copied_and_missing_cells_stay_zero() { + let mut grid = grid(2); + let drums = SplatRow::Drums.index(); + let mix = SplatRow::Mix.index(); + grid.cells[drums][0] = Some(cell(1.25, 2.75, 0.6, false)); + grid.cells[mix][1] = Some(cell(4.0, 5.5, 0.8, true)); + + let model = splat_view_model( + DeckId::A, + &grid, + false, + None, + &coverage(usize::MAX), + 8.0, + ); + + assert_eq!(model.spans[drums][0], (1.25, 1.5)); + assert_eq!(model.spans[mix][1], (4.0, 1.5)); + assert_eq!(model.spans[drums][1], (0.0, 0.0)); + } + + #[test] + fn an_empty_grid_maps_to_an_empty_model() { + let model = splat_view_model(DeckId::A, &grid(0), false, None, &coverage(0), 0.0); + assert_eq!(model, SplatViewModel::empty(SplatDeck::A)); + } + + #[test] + fn engine_and_view_row_orders_agree() { + for (engine, view) in SplatRow::ALL.into_iter().zip(SplatRowView::ALL) { + assert_eq!(engine, splat_row(view)); + } + } +} diff --git a/apps/vj/src/loop_splat_view.rs b/apps/vj/src/loop_splat_view.rs new file mode 100644 index 000000000..d86878767 --- /dev/null +++ b/apps/vj/src/loop_splat_view.rs @@ -0,0 +1,1197 @@ +//! Compact view-model and direct-draw widget for the loop splat. + +use crate::loop_blocks::CellBlocks; +use crate::loop_splat::SplatPart; +use crate::music_view::{WavePyramid, STEM_COLORS}; +use crate::wave_analysis::ZOOM_COLS_PER_SEC; +use makepad_widgets::*; +use std::sync::Arc; + +pub const SPLAT_COLS: usize = 8; +pub const SPLAT_ROWS: usize = 5; + +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum SplatRowView { + Drums, + Bass, + Vocals, + Other, + Mix, +} + +impl SplatRowView { + pub const ALL: [Self; SPLAT_ROWS] = [ + Self::Drums, + Self::Bass, + Self::Vocals, + Self::Other, + Self::Mix, + ]; + + pub fn label(self) -> &'static str { + match self { + Self::Drums => "DRUMS", + Self::Bass => "BASS", + Self::Vocals => "VOCALS", + Self::Other => "OTHER", + Self::Mix => "MIX", + } + } + + pub fn color(self) -> [f32; 4] { + match self { + Self::Drums => STEM_COLORS[1], + Self::Bass => STEM_COLORS[2], + Self::Vocals => STEM_COLORS[0], + Self::Other => STEM_COLORS[3], + Self::Mix => [0.80, 0.82, 0.85, 1.0], + } + } +} + +#[derive(Clone, Copy, PartialEq, Debug)] +pub enum SplatCellView { + Empty, + Silent, + Ready { energy: f32 }, + Queued { energy: f32, part: SplatPart }, + Playing { energy: f32, phase: f32, part: SplatPart }, +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum SplatDeck { + A, + B, +} + +#[derive(Clone, Debug)] +pub struct SplatViewModel { + pub deck: SplatDeck, + pub enabled: bool, + pub cols: usize, + pub col_bars: [u8; SPLAT_COLS], + pub col_start_secs: [f64; SPLAT_COLS], + /// Each cell's source-time start and length. Missing cells stay zeroed. + pub spans: [[(f32, f32); SPLAT_COLS]; SPLAT_ROWS], + pub duration_secs: f32, + pub cells: [[SplatCellView; SPLAT_COLS]; SPLAT_ROWS], + pub blocks: [[Option>; SPLAT_COLS]; SPLAT_ROWS], + pub bar_phase: f32, + /// The score-popup preview cursor: row, column, and loop phase. + pub preview: Option<(usize, usize, f32)>, + /// What the deck is still doing before the grid is complete (text, progress 0..1; + /// `None` progress = indeterminate). Drawn as an overlay over the grid. + pub status: Option<(String, Option)>, +} + +impl PartialEq for SplatViewModel { + fn eq(&self, other: &Self) -> bool { + self.deck == other.deck + && self.enabled == other.enabled + && self.cols == other.cols + && self.col_bars == other.col_bars + && self.col_start_secs == other.col_start_secs + && self.spans == other.spans + && self.duration_secs == other.duration_secs + && self.cells == other.cells + && self.bar_phase == other.bar_phase + && self.preview == other.preview + && self.status == other.status + && self.blocks.iter().flatten().zip(other.blocks.iter().flatten()).all( + |(left, right)| match (left, right) { + (Some(left), Some(right)) => Arc::ptr_eq(left, right), + (None, None) => true, + _ => false, + }, + ) + } +} + +impl SplatViewModel { + pub fn empty(deck: SplatDeck) -> Self { + Self { + deck, + enabled: false, + cols: 0, + col_bars: [0; SPLAT_COLS], + col_start_secs: [0.0; SPLAT_COLS], + spans: [[(0.0, 0.0); SPLAT_COLS]; SPLAT_ROWS], + duration_secs: 0.0, + cells: [[SplatCellView::Empty; SPLAT_COLS]; SPLAT_ROWS], + blocks: std::array::from_fn(|_| std::array::from_fn(|_| None)), + bar_phase: 0.0, + preview: None, + status: None, + } + } +} + +impl Default for SplatViewModel { + fn default() -> Self { + Self::empty(SplatDeck::A) + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Default)] +pub enum LoopSplatAction { + /// `timed` = shift held: stop on the next bar instead of at once. + Cell { row: SplatRowView, col: u8, timed: bool, part: SplatPart }, + StopRow { row: SplatRowView, timed: bool }, + LaunchColumn { col: u8, timed: bool }, + FocusDeck(SplatDeck), + ToggleEnabled, + ToggleScore, + #[default] + None, +} + +/// One instanced material for every grid cell. The shader interprets +/// `state` as empty/silent/ready/queued/playing in that order. +#[derive(Script, ScriptHook)] +#[repr(C)] +pub struct DrawSplatCell { + #[deref] + pub draw_super: DrawQuad, + #[live] + pub color: Vec4f, + #[live] + pub phase: f32, + /// Progress through the current bar: the countdown to a queued launch. + #[live] + pub bar_phase: f32, + #[live] + pub state: f32, + #[live] + pub hover: f32, + #[live] + pub part_x0: f32, + #[live(1.0)] + pub part_x1: f32, + #[live] + pub part_y0: f32, + #[live(1.0)] + pub part_y1: f32, + /// Source span in finest-level pyramid columns. + #[live] + pub span_start: f32, + #[live] + pub span_cols: f32, + /// vocals/drums/bass/other = 0/1/2/3; mix = 4. + #[live] + pub channel: f32, + #[live(1.0)] + pub tex_w: f32, + #[live(1.0)] + pub tex_h: f32, + #[live] + pub lo_row: f32, + #[live(1.0)] + pub lo_cols: f32, + #[live(1.0)] + pub lo_scale: f32, + #[live] + pub hi_row: f32, + #[live(1.0)] + pub hi_cols: f32, + #[live(2.0)] + pub hi_scale: f32, + #[live] + pub lod_blend: f32, + #[live] + pub has_mix: f32, + #[live] + pub has_stems: f32, + #[live] + pub has_blocks: f32, +} + +#[derive(Script, ScriptHook)] +#[repr(C)] +pub struct DrawSplatBlock { + #[deref] + pub draw_super: DrawQuad, + #[live] + pub color: Vec4f, + #[live] + pub alpha: f32, +} + +/// Convert the model's `(start_secs, len_secs)` span to the waveform +/// pyramid's finest-column timebase. +pub(crate) fn span_to_pyramid_columns(span: (f32, f32)) -> (f32, f32) { + let rate = ZOOM_COLS_PER_SEC as f32; + if !span.0.is_finite() || !span.1.is_finite() { + return (0.0, 0.0); + } + (span.0.max(0.0) * rate, span.1.max(0.0) * rate) +} + +const PAD: f64 = 8.0; +const COL_HEAD_H: f64 = 18.0; +const ROW_HEAD_W: f64 = 76.0; +const CELL_MIN: f64 = 44.0; +const CELL_INSET: f64 = 2.0; +const SLOT_INSET: f64 = 2.0; +const BLOCK_INSET: f64 = 4.0; +const BLOCK_GAP: f64 = 1.0; +const BLOCK_MIN_W: f64 = 2.0; +const BLOCK_MIN_H: f64 = 2.0; +const LAUNCH_H: f64 = 18.0; +const FOOT_GAP: f64 = 4.0; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +enum SplatHit { + Cell { row: usize, col: usize, part: SplatPart }, + StopRow(usize), + LaunchColumn(usize), +} + +#[derive(Clone, Copy)] +struct SplatGeometry { + grid: Rect, + col_head_y: f64, + cell_h: f64, + launch_y: f64, + cols: usize, +} + +impl SplatGeometry { + fn new(rect: Rect, cols: usize) -> Self { + let cols = cols.clamp(1, SPLAT_COLS); + let inner_x = rect.pos.x + PAD; + let inner_w = (rect.size.x - PAD * 2.0).max(1.0); + let grid_x = inner_x + ROW_HEAD_W; + let grid_w = (inner_w - ROW_HEAD_W).max(cols as f64); + let col_head_y = rect.pos.y + PAD; + let grid_y = col_head_y + COL_HEAD_H; + let footer = FOOT_GAP + LAUNCH_H; + let available = (rect.pos.y + rect.size.y - PAD - footer - grid_y) / SPLAT_ROWS as f64; + let cell_w = grid_w / cols as f64; + let cell_h = cell_w.min(available).max(CELL_MIN); + let grid = Rect { + pos: dvec2(grid_x, grid_y), + size: dvec2(grid_w, cell_h * SPLAT_ROWS as f64), + }; + let launch_y = grid.pos.y + grid.size.y + FOOT_GAP; + Self { + grid, + col_head_y, + cell_h, + launch_y, + cols, + } + } + + fn col_w(self) -> f64 { + self.grid.size.x / self.cols as f64 + } + + fn cell_rect(self, row: usize, col: usize) -> Rect { + Rect { + pos: dvec2( + self.grid.pos.x + col as f64 * self.col_w() + CELL_INSET, + self.grid.pos.y + row as f64 * self.cell_h + CELL_INSET, + ), + size: dvec2( + (self.col_w() - CELL_INSET * 2.0).max(1.0), + (self.cell_h - CELL_INSET * 2.0).max(1.0), + ), + } + } + + fn cell_bounds(self, row: usize, col: usize) -> Rect { + Rect { + pos: dvec2( + self.grid.pos.x + col as f64 * self.col_w(), + self.grid.pos.y + row as f64 * self.cell_h, + ), + size: dvec2(self.col_w(), self.cell_h), + } + } + + fn part_rect(self, row: usize, col: usize, part: SplatPart) -> Rect { + slot_rect(self.cell_rect(row, col), part) + } + + fn row_stop(self, row: usize) -> Rect { + Rect { + pos: dvec2( + self.grid.pos.x - 18.0, + self.grid.pos.y + row as f64 * self.cell_h + (self.cell_h - 14.0) * 0.5, + ), + size: dvec2(14.0, 14.0), + } + } + + fn launch(self, col: usize) -> Rect { + Rect { + pos: dvec2(self.grid.pos.x + col as f64 * self.col_w() + CELL_INSET, self.launch_y), + size: dvec2((self.col_w() - CELL_INSET * 2.0).max(1.0), LAUNCH_H - 2.0), + } + } + + fn hit(self, pos: DVec2) -> Option { + if let Some((row, col)) = cell_at_cols(self.grid, pos, self.cols) { + let part = part_at(self.cell_bounds(row, col), pos)?; + return Some(SplatHit::Cell { row, col, part }); + } + for row in 0..SPLAT_ROWS { + if self.row_stop(row).contains(pos) { + return Some(SplatHit::StopRow(row)); + } + } + for col in 0..self.cols { + if self.launch(col).contains(pos) { + return Some(SplatHit::LaunchColumn(col)); + } + } + None + } +} + +fn slot_area(rect: Rect) -> Rect { + Rect { + pos: rect.pos + dvec2(SLOT_INSET, SLOT_INSET), + size: dvec2( + (rect.size.x - SLOT_INSET * 2.0).max(0.0), + (rect.size.y - SLOT_INSET * 2.0).max(0.0), + ), + } +} + +fn slot_rect(rect: Rect, part: SplatPart) -> Rect { + if part == SplatPart::WHOLE { + return rect; + } + let area = slot_area(rect); + let den = f64::from(part.den.max(1)); + let x0 = f64::from(part.num.min(part.den.saturating_sub(1))) / den; + let (y0, y1) = if part.den == 2 { (0.0, 0.5) } else { (0.5, 1.0) }; + Rect { + pos: dvec2(area.pos.x + area.size.x * x0, area.pos.y + area.size.y * y0), + size: dvec2(area.size.x / den, area.size.y * (y1 - y0)), + } +} + +fn part_at(rect: Rect, pos: DVec2) -> Option { + if rect.size.x <= 0.0 || rect.size.y <= 0.0 || !rect.contains(pos) { + return None; + } + let x = ((pos.x - rect.pos.x) / rect.size.x).clamp(0.0, 1.0 - f64::EPSILON); + let y = (pos.y - rect.pos.y) / rect.size.y; + let den = if y < 0.5 { 2 } else { 4 }; + Some(SplatPart { + num: (x * f64::from(den)).floor() as u8, + den, + }) +} + +fn cell_at_cols(rect: Rect, pos: DVec2, cols: usize) -> Option<(usize, usize)> { + if cols == 0 || rect.size.x <= 0.0 || rect.size.y <= 0.0 || !rect.contains(pos) { + return None; + } + let col = (((pos.x - rect.pos.x) / rect.size.x) * cols as f64).floor() as usize; + let row = (((pos.y - rect.pos.y) / rect.size.y) * SPLAT_ROWS as f64).floor() as usize; + (row < SPLAT_ROWS && col < cols).then_some((row, col)) +} + +pub(crate) fn cell_at(rect: Rect, pos: DVec2) -> Option<(usize, usize)> { + cell_at_cols(rect, pos, SPLAT_COLS) +} + +#[derive(Script, ScriptHook, Widget)] +pub struct VjLoopSplat { + #[uid] + uid: WidgetUid, + #[source] + source: ScriptObjectRef, + #[walk] + walk: Walk, + #[layout] + layout: Layout, + #[live] + draw_cell: DrawSplatCell, + #[live] + draw_block: DrawSplatBlock, + #[live] + draw_chrome: DrawColor, + #[live] + draw_text: DrawText, + #[live] + draw_small: DrawText, + #[redraw] + #[area] + area: Area, + #[rust] + model: SplatViewModel, + #[rust] + mix_pyramid: Option, + #[rust] + stem_pyramid: Option, + #[rust] + hover: Option, + #[rust] + pressed: Option, + #[rust] + selected: Option<(SplatRowView, u8)>, + #[rust] + anim_frame: NextFrame, +} + +impl VjLoopSplat { + pub fn set_model(&mut self, cx: &mut Cx, mut model: SplatViewModel) { + model.cols = model.cols.min(SPLAT_COLS); + model.bar_phase = model.bar_phase.clamp(0.0, 1.0); + model.preview = model.preview.and_then(|(row, col, phase)| { + (row < SPLAT_ROWS && col < model.cols) + .then_some((row, col, phase.clamp(0.0, 1.0))) + }); + if self.model != model { + self.model = model; + self.area.redraw(cx); + } + } + + pub fn model(&self) -> &SplatViewModel { + &self.model + } + + pub fn set_waves( + &mut self, + cx: &mut Cx, + mix: Option, + stems: Option, + ) { + if self.mix_pyramid != mix || self.stem_pyramid != stems { + self.mix_pyramid = mix; + self.stem_pyramid = stems; + self.area.redraw(cx); + } + } + + pub fn set_selected(&mut self, cx: &mut Cx, row: SplatRowView, col: u8) { + let selected = ((col as usize) < SPLAT_COLS).then_some((row, col)); + if self.selected != selected { + self.selected = selected; + self.area.redraw(cx); + } + } + + pub fn selected(&self) -> Option<(SplatRowView, u8)> { + self.selected + } + + fn animates(&self) -> bool { + if matches!(self.model.status, Some((_, None))) { + return true; + } + self.model + .cells + .iter() + .flatten() + .any(|cell| matches!(cell, SplatCellView::Queued { .. } | SplatCellView::Playing { .. } )) + } + + fn hit_at(&self, cx: &Cx, pos: DVec2) -> Option { + if self.model.cols == 0 { + return None; + } + SplatGeometry::new(self.area.rect(cx), self.model.cols).hit(pos) + } + + fn hovered_part(&self, row: usize, col: usize) -> Option { + match self.hover { + Some(SplatHit::Cell { + row: hit_row, + col: hit_col, + part, + }) if hit_row == row && hit_col == col => Some(part), + _ => None, + } + } + + fn emit(&mut self, cx: &mut Cx, hit: SplatHit, timed: bool) { + let action = match hit { + SplatHit::Cell { row, col, part } => { + let row = SplatRowView::ALL[row]; + self.set_selected(cx, row, col as u8); + LoopSplatAction::Cell { row, col: col as u8, timed, part } + } + SplatHit::StopRow(row) => LoopSplatAction::StopRow { row: SplatRowView::ALL[row], timed }, + SplatHit::LaunchColumn(col) => LoopSplatAction::LaunchColumn { col: col as u8, timed }, + }; + cx.widget_action(self.widget_uid(), action); + } + + fn draw_box(&mut self, cx: &mut Cx2d, rect: Rect, color: Vec4f) { + self.draw_chrome.color = color; + self.draw_chrome.draw_abs(cx, rect); + } + + fn text_width(&self, cx: &mut Cx2d, text: &str, small: bool) -> f64 { + let draw = if small { &self.draw_small } else { &self.draw_text }; + let laid = draw.layout(cx, 0.0, 0.0, None, false, Align::default(), text); + laid.size_in_lpxs.width as f64 * draw.font_scale as f64 + } + + fn draw_centered( + &mut self, + cx: &mut Cx2d, + rect: Rect, + text: &str, + color: Vec4f, + small: bool, + ) { + let width = self.text_width(cx, text, small); + let pos = dvec2( + rect.pos.x + (rect.size.x - width) * 0.5, + rect.pos.y + (rect.size.y - if small { 9.0 } else { 11.0 }) * 0.5, + ); + let draw = if small { + &mut self.draw_small + } else { + &mut self.draw_text + }; + draw.color = color; + draw.draw_abs(cx, pos, text); + } + + fn draw_cell_at( + &mut self, + cx: &mut Cx2d, + rect: Rect, + row: SplatRowView, + cell: SplatCellView, + hover: bool, + enabled: bool, + span: (f32, f32), + has_blocks: bool, + ) { + let mut c = row.color(); + if !enabled { + c[0] *= 0.55; + c[1] *= 0.55; + c[2] *= 0.55; + } + self.draw_cell.color = vec4(c[0], c[1], c[2], c[3]); + let (state, phase, part) = match cell { + SplatCellView::Empty => (0.0, 0.0, SplatPart::WHOLE), + SplatCellView::Silent => (1.0, 0.0, SplatPart::WHOLE), + SplatCellView::Ready { .. } => (2.0, 0.0, SplatPart::WHOLE), + SplatCellView::Queued { part, .. } => (3.0, 0.0, part), + SplatCellView::Playing { phase, part, .. } => (4.0, phase, part), + }; + self.draw_cell.state = state; + self.draw_cell.bar_phase = self.model.bar_phase.clamp(0.0, 1.0); + self.draw_cell.phase = phase.clamp(0.0, 1.0); + self.draw_cell.hover = if hover { 1.0 } else { 0.0 }; + let part_rect = slot_rect(rect, part); + let width = rect.size.x.max(1.0); + let height = rect.size.y.max(1.0); + self.draw_cell.part_x0 = ((part_rect.pos.x - rect.pos.x) / width) as f32; + self.draw_cell.part_x1 = ((part_rect.pos.x + part_rect.size.x - rect.pos.x) / width) as f32; + self.draw_cell.part_y0 = ((part_rect.pos.y - rect.pos.y) / height) as f32; + self.draw_cell.part_y1 = ((part_rect.pos.y + part_rect.size.y - rect.pos.y) / height) as f32; + self.draw_cell.has_blocks = if has_blocks { 1.0 } else { 0.0 }; + self.draw_cell.channel = match row { + SplatRowView::Vocals => 0.0, + SplatRowView::Drums => 1.0, + SplatRowView::Bass => 2.0, + SplatRowView::Other => 3.0, + SplatRowView::Mix => 4.0, + }; + let (span_start, mut span_cols) = span_to_pyramid_columns(span); + let duration_cols = self.model.duration_secs.max(0.0) * ZOOM_COLS_PER_SEC as f32; + self.draw_cell.span_start = span_start.min(duration_cols); + span_cols = span_cols.min((duration_cols - self.draw_cell.span_start).max(0.0)); + self.draw_cell.span_cols = span_cols; + if let Some(pyramid) = self.mix_pyramid.as_ref() { + self.draw_cell.tex_w = pyramid.width.max(1) as f32; + self.draw_cell.tex_h = pyramid.height.max(1) as f32; + let inner_width = (rect.size.x - 8.0).max(1.0); + let cols_per_px = (span_cols as f64 / inner_width).max(0.001); + let (lo, lo_scale, hi, hi_scale, blend) = pyramid.levels_for(cols_per_px); + self.draw_cell.lo_row = lo.base_row as f32; + self.draw_cell.lo_cols = lo.cols.max(1) as f32; + self.draw_cell.lo_scale = lo_scale as f32; + self.draw_cell.hi_row = hi.base_row as f32; + self.draw_cell.hi_cols = hi.cols.max(1) as f32; + self.draw_cell.hi_scale = hi_scale as f32; + self.draw_cell.lod_blend = blend as f32; + } else { + self.draw_cell.tex_w = 1.0; + self.draw_cell.tex_h = 1.0; + self.draw_cell.lo_cols = 1.0; + self.draw_cell.hi_cols = 1.0; + self.draw_cell.lo_scale = 1.0; + self.draw_cell.hi_scale = 2.0; + self.draw_cell.lod_blend = 0.0; + } + self.draw_cell.draw_abs(cx, rect); + } + + fn draw_blocks_at( + &mut self, + cx: &mut Cx2d, + rect: Rect, + row: SplatRowView, + cell: SplatCellView, + blocks: &CellBlocks, + ) { + let alpha = match cell { + SplatCellView::Ready { .. } | SplatCellView::Queued { .. } => 0.85, + SplatCellView::Playing { .. } => 1.0, + SplatCellView::Empty | SplatCellView::Silent => return, + }; + let inner = Rect { + pos: rect.pos + dvec2(BLOCK_INSET, BLOCK_INSET), + size: dvec2( + (rect.size.x - BLOCK_INSET * 2.0).max(1.0), + (rect.size.y - BLOCK_INSET * 2.0).max(1.0), + ), + }; + let total_beats = f64::from(blocks.bars) * 4.0; + if total_beats <= 0.0 { + return; + } + let px_per_beat = inner.size.x / total_beats; + let stem = row.color(); + for block in &blocks.blocks { + let lanes = block.lanes.max(1) as f64; + let lane = block.lane.min(block.lanes.saturating_sub(1)) as f64; + let slot_h = inner.size.y / lanes; + let height = (slot_h - BLOCK_GAP).max(BLOCK_MIN_H).min(inner.size.y); + let y = inner.pos.y + inner.size.y - (lane + 1.0) * slot_h + + (slot_h - height) * 0.5; + let start = f64::from(block.start_beats).clamp(0.0, total_beats); + let x = inner.pos.x + start * px_per_beat; + let width = (f64::from(block.len_beats.max(0.0)) * px_per_beat - BLOCK_GAP) + .max(BLOCK_MIN_W) + .min((inner.pos.x + inner.size.x - x).max(0.0)); + if width <= 0.0 { + continue; + } + // A quiet event is still 70% stem colour; the loudest events + // approach white without losing the row hue entirely. + let whiten = block.velocity.clamp(0.3, 1.0) * 0.9; + self.draw_block.color = vec4( + stem[0] + (1.0 - stem[0]) * whiten, + stem[1] + (1.0 - stem[1]) * whiten, + stem[2] + (1.0 - stem[2]) * whiten, + 1.0, + ); + self.draw_block.alpha = alpha; + self.draw_block.draw_abs(cx, Rect { pos: dvec2(x, y), size: dvec2(width, height) }); + } + } + + fn draw_selection(&mut self, cx: &mut Cx2d, rect: Rect) { + let white = Vec4f::from_u32(0xffffffff); + for edge in [ + Rect { pos: rect.pos, size: dvec2(rect.size.x, 1.0) }, + Rect { + pos: dvec2(rect.pos.x, rect.pos.y + rect.size.y - 1.0), + size: dvec2(rect.size.x, 1.0), + }, + Rect { pos: rect.pos, size: dvec2(1.0, rect.size.y) }, + Rect { + pos: dvec2(rect.pos.x + rect.size.x - 1.0, rect.pos.y), + size: dvec2(1.0, rect.size.y), + }, + ] { + self.draw_box(cx, edge, white); + } + } + + fn draw_slot_guides( + &mut self, + cx: &mut Cx2d, + rect: Rect, + row: SplatRowView, + hovered: SplatPart, + ) { + // The slot under the pointer: a clear lift plus a frame in the row + // colour, so the six targets read at a glance before the click. + let slot = slot_rect(rect, hovered); + let color = row.color(); + self.draw_box(cx, slot, vec4(1.0, 1.0, 1.0, 0.16)); + let frame = vec4(color[0], color[1], color[2], 0.9); + for edge in [ + Rect { pos: slot.pos, size: dvec2(slot.size.x, 1.0) }, + Rect { pos: dvec2(slot.pos.x, slot.pos.y + slot.size.y - 1.0), size: dvec2(slot.size.x, 1.0) }, + Rect { pos: slot.pos, size: dvec2(1.0, slot.size.y) }, + Rect { pos: dvec2(slot.pos.x + slot.size.x - 1.0, slot.pos.y), size: dvec2(1.0, slot.size.y) }, + ] { + self.draw_box(cx, edge, frame); + } + let area = slot_area(rect); + let divider = vec4(color[0], color[1], color[2], 0.5); + let half_y = area.pos.y + area.size.y * 0.5; + self.draw_box( + cx, + Rect { + pos: dvec2(area.pos.x, half_y - 0.5), + size: dvec2(area.size.x, 1.0), + }, + divider, + ); + self.draw_box( + cx, + Rect { + pos: dvec2(area.pos.x + area.size.x * 0.5 - 0.5, area.pos.y), + size: dvec2(1.0, area.size.y * 0.5), + }, + divider, + ); + for quarter in 1..4 { + self.draw_box( + cx, + Rect { + pos: dvec2( + area.pos.x + area.size.x * quarter as f64 * 0.25 - 0.5, + half_y, + ), + size: dvec2(1.0, area.size.y * 0.5), + }, + divider, + ); + } + } +} + +impl VjLoopSplatRef { + pub fn splat_action(&self, actions: &Actions) -> LoopSplatAction { + actions.find_widget_action_cast(self.widget_uid()) + } +} + +impl Widget for VjLoopSplat { + fn handle_event(&mut self, cx: &mut Cx, event: &Event, _scope: &mut Scope) { + if self.anim_frame.is_event(event).is_some() && self.animates() { + self.area.redraw(cx); + self.anim_frame = cx.new_next_frame(); + } + match event.hits(cx, self.area) { + Hit::FingerDown(fe) + if fe.is_primary_hit() + || fe.mouse_button().is_some_and(|button| button.is_secondary()) => + { + let secondary = fe.mouse_button().is_some_and(|button| button.is_secondary()); + self.pressed = self.hit_at(cx, fe.abs).and_then(|hit| match (secondary, hit) { + (true, hit @ SplatHit::Cell { .. }) => Some(hit), + (true, _) => None, + (false, SplatHit::Cell { row, col, .. }) => Some(SplatHit::Cell { + row, + col, + part: SplatPart::WHOLE, + }), + (false, hit) => Some(hit), + }); + if self.pressed.is_some() { + cx.set_key_focus(self.area); + self.area.redraw(cx); + } + } + Hit::FingerUp(fe) + if fe.is_primary_hit() + || fe.mouse_button().is_some_and(|button| button.is_secondary()) => + { + let secondary = fe.mouse_button().is_some_and(|button| button.is_secondary()); + let released = self.hit_at(cx, fe.abs).and_then(|hit| match (secondary, hit) { + (true, hit @ SplatHit::Cell { .. }) => Some(hit), + (true, _) => None, + (false, SplatHit::Cell { row, col, .. }) => Some(SplatHit::Cell { + row, + col, + part: SplatPart::WHOLE, + }), + (false, hit) => Some(hit), + }); + if fe.is_over && released == self.pressed { + if let Some(hit) = released { + // Shift makes a stop wait for the bar; a plain click is immediate. + self.emit(cx, hit, fe.modifiers.shift); + } + } + if self.pressed.take().is_some() { + self.area.redraw(cx); + } + } + Hit::FingerHoverIn(fe) | Hit::FingerHoverOver(fe) => { + let hover = self.hit_at(cx, fe.abs); + if hover.is_some() { + cx.set_cursor(MouseCursor::Hand); + } + if self.hover != hover { + self.hover = hover; + self.area.redraw(cx); + } + } + Hit::FingerHoverOut(_) => { + if self.hover.take().is_some() { + self.area.redraw(cx); + } + } + _ => {} + } + } + + fn draw_walk(&mut self, cx: &mut Cx2d, _scope: &mut Scope, walk: Walk) -> DrawStep { + let rect = cx.walk_turtle_with_area(&mut self.area, walk); + if rect.size.x < 16.0 || rect.size.y < 16.0 { + return DrawStep::done(); + } + let active = self.model.cols != 0; + let cols = if active { self.model.cols } else { SPLAT_COLS }; + let geom = SplatGeometry::new(rect, cols); + let now = cx.seconds_since_app_start() as f32; + self.draw_cell + .draw_vars + .set_uniform(cx, live_id!(time), &[now]); + match self.mix_pyramid.as_ref() { + Some(pyramid) => { + self.draw_cell.draw_vars.set_texture(0, &pyramid.texture); + self.draw_cell.has_mix = 1.0; + } + None => { + self.draw_cell.draw_vars.empty_texture(0); + self.draw_cell.has_mix = 0.0; + } + } + match self.stem_pyramid.as_ref() { + Some(pyramid) => { + self.draw_cell.draw_vars.set_texture(1, &pyramid.texture); + self.draw_cell.has_stems = 1.0; + } + None => { + self.draw_cell.draw_vars.empty_texture(1); + self.draw_cell.has_stems = 0.0; + } + } + if self.animates() { + self.anim_frame = cx.new_next_frame(); + } + + let selected = Vec4f::from_u32(0xff5c39ff); + let idle = Vec4f::from_u32(0x202730ff); + let hover = Vec4f::from_u32(0x313b47ff); + let dim_text = Vec4f::from_u32(0x8995a2ff); + for row in 0..SPLAT_ROWS { + let row_view = SplatRowView::ALL[row]; + let rc = row_view.color(); + let label_rect = Rect { + pos: dvec2(rect.pos.x + PAD, geom.grid.pos.y + row as f64 * geom.cell_h), + size: dvec2(ROW_HEAD_W - 20.0, geom.cell_h), + }; + self.draw_centered(cx, label_rect, row_view.label(), vec4(rc[0], rc[1], rc[2], if active { 1.0 } else { 0.55 }), true); + let stop = geom.row_stop(row); + let stop_hot = self.hover == Some(SplatHit::StopRow(row)); + // The row's stop button lights while that row has a loop running. + let row_live = active + && self.model.cells[row].iter().any(|cell| { + matches!(cell, SplatCellView::Playing { .. }) + }); + self.draw_box(cx, stop, if row_live { selected } else if stop_hot { hover } else { idle }); + self.draw_centered(cx, stop, "■", vec4(rc[0], rc[1], rc[2], if active { 1.0 } else { 0.35 }), true); + } + + // Every pad is one instance of the same textured material. Level + // selection and source span vary per instance; the textures do not. + self.draw_cell.begin_many_instances(cx); + for row in 0..SPLAT_ROWS { + let row_view = SplatRowView::ALL[row]; + for col in 0..cols { + let cell = if active { + self.model.cells[row][col] + } else { + SplatCellView::Empty + }; + self.draw_cell_at( + cx, + geom.cell_rect(row, col), + row_view, + cell, + self.hovered_part(row, col).is_some(), + self.model.enabled || !active, + if active { self.model.spans[row][col] } else { (0.0, 0.0) }, + active && self.model.blocks[row][col].is_some(), + ); + } + } + self.draw_cell.end_many_instances(cx); + self.draw_block.begin_many_instances(cx); + if active { + for row in 0..SPLAT_ROWS { + let row_view = SplatRowView::ALL[row]; + for col in 0..cols { + if let Some(blocks) = self.model.blocks[row][col].clone() { + self.draw_blocks_at( + cx, + geom.cell_rect(row, col), + row_view, + self.model.cells[row][col], + &blocks, + ); + } + } + } + } + self.draw_block.end_many_instances(cx); + if active { + for row in 0..SPLAT_ROWS { + for col in 0..cols { + let Some(part) = self.hovered_part(row, col) else { continue }; + if matches!( + self.model.cells[row][col], + SplatCellView::Ready { .. } + | SplatCellView::Queued { .. } + | SplatCellView::Playing { .. } + ) { + self.draw_slot_guides( + cx, + geom.cell_rect(row, col), + SplatRowView::ALL[row], + part, + ); + } + } + } + } + // State tags: what a cell is about to do, in words, at its top-left. + if active { + for row in 0..SPLAT_ROWS { + for col in 0..cols { + let SplatCellView::Queued { part, .. } = self.model.cells[row][col] else { continue }; + let (tag, color) = ("NEXT", Vec4f::from_u32(0xffffffff)); + let cell = geom.part_rect(row, col, part); + let tag_rect = Rect { + pos: dvec2(cell.pos.x + 2.0, cell.pos.y + 2.0), + size: dvec2((cell.size.x - 4.0).clamp(1.0, 30.0), 10.0), + }; + self.draw_box(cx, tag_rect, Vec4f::from_u32(0x000000aa)); + self.draw_centered(cx, tag_rect, tag, color, true); + } + } + } + if let Some((row, col, phase)) = self.model.preview { + if active && row < SPLAT_ROWS && col < cols { + let rect = geom.cell_rect(row, col); + let inset = 2.0; + let width = (rect.size.x - inset * 2.0).max(1.0); + let x = rect.pos.x + inset + (width - 1.0) * phase.clamp(0.0, 1.0) as f64; + self.draw_box( + cx, + Rect { + pos: dvec2(x, rect.pos.y + inset), + size: dvec2(1.0, (rect.size.y - inset * 2.0).max(1.0)), + }, + Vec4f::from_u32(0xfffffff2), + ); + } + } + if let Some((row, col)) = self.selected { + if active && (col as usize) < cols { + let row = SplatRowView::ALL.iter().position(|item| *item == row).unwrap_or(0); + let rect = match self.model.cells[row][col as usize] { + SplatCellView::Queued { part, .. } + | SplatCellView::Playing { part, .. } => { + geom.part_rect(row, col as usize, part) + } + _ => geom.cell_rect(row, col as usize), + }; + self.draw_selection(cx, rect); + } + } + + if active { + for col in 0..cols { + let head = Rect { + pos: dvec2(geom.grid.pos.x + col as f64 * geom.col_w() + CELL_INSET, geom.col_head_y), + size: dvec2((geom.col_w() - CELL_INSET * 2.0).max(1.0), COL_HEAD_H - 2.0), + }; + let title = format!("{} · {}", col + 1, self.model.col_bars[col]); + self.draw_centered(cx, head, &title, dim_text, true); + + let launch = geom.launch(col); + let launch_hot = self.hover == Some(SplatHit::LaunchColumn(col)); + // Lit while any stem row of this section is running or queued: + // the same button then stops the section. + let col_live = (0..SPLAT_ROWS - 1).any(|row| { + matches!( + self.model.cells[row][col], + SplatCellView::Playing { .. } | SplatCellView::Queued { .. } + ) + }); + self.draw_box(cx, launch, if col_live { selected } else if launch_hot { hover } else { idle }); + self.draw_centered(cx, launch, if col_live { "■" } else { "▶" }, Vec4f::from_u32(0xdce3eaff), true); + } + } else if self.model.status.is_none() { + let message = "load a track on deck A or B"; + let message_rect = Rect { + pos: geom.grid.pos, + size: geom.grid.size, + }; + self.draw_centered(cx, message_rect, message, Vec4f::from_u32(0xaab4beff), false); + } + if let Some((text, progress)) = self.model.status.clone() { + // The loading overlay: what the deck is still doing, over the grid. + let box_w = 360.0f64.min(geom.grid.size.x - 16.0).max(120.0); + let box_h = 44.0; + let panel = Rect { + pos: dvec2( + geom.grid.pos.x + (geom.grid.size.x - box_w) * 0.5, + geom.grid.pos.y + (geom.grid.size.y - box_h) * 0.5, + ), + size: dvec2(box_w, box_h), + }; + self.draw_box(cx, panel, Vec4f::from_u32(0x0f1318e6)); + let text_rect = Rect { pos: panel.pos + dvec2(0.0, 6.0), size: dvec2(box_w, 14.0) }; + self.draw_centered(cx, text_rect, &text, Vec4f::from_u32(0xdce3eaff), true); + let track = Rect { + pos: dvec2(panel.pos.x + 20.0, panel.pos.y + box_h - 14.0), + size: dvec2(box_w - 40.0, 6.0), + }; + self.draw_box(cx, track, Vec4f::from_u32(0x2a323cff)); + match progress { + Some(p) => { + let fill = Rect { pos: track.pos, size: dvec2(track.size.x * p.clamp(0.0, 1.0) as f64, track.size.y) }; + self.draw_box(cx, fill, selected); + } + None => { + // Indeterminate: a block sweeping back and forth. + let t = (now as f64 * 0.8).rem_euclid(2.0); + let u = if t < 1.0 { t } else { 2.0 - t }; + let block_w = 60.0f64.min(track.size.x); + let fill = Rect { + pos: dvec2(track.pos.x + (track.size.x - block_w) * u, track.pos.y), + size: dvec2(block_w, track.size.y), + }; + self.draw_box(cx, fill, selected); + } + } + } + DrawStep::done() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::collections::HashSet; + + #[test] + fn row_colours_are_distinct() { + let colors: HashSet<[u32; 4]> = SplatRowView::ALL + .iter() + .map(|row| row.color().map(f32::to_bits)) + .collect(); + assert_eq!(colors.len(), SPLAT_ROWS); + } + + #[test] + fn empty_model_has_no_synthetic_content() { + let model = SplatViewModel::empty(SplatDeck::B); + assert_eq!(model.deck, SplatDeck::B); + assert!(!model.enabled); + assert_eq!(model.cols, 0); + assert_eq!(model.col_bars, [0; SPLAT_COLS]); + assert_eq!(model.col_start_secs, [0.0; SPLAT_COLS]); + assert_eq!(model.spans, [[(0.0, 0.0); SPLAT_COLS]; SPLAT_ROWS]); + assert_eq!(model.duration_secs, 0.0); + assert!(model.blocks.iter().flatten().all(Option::is_none)); + assert_eq!(model.bar_phase, 0.0); + assert_eq!(model.preview, None); + assert!(model.cells.iter().flatten().all(|cell| *cell == SplatCellView::Empty)); + } + + #[test] + fn model_block_equality_uses_arc_identity() { + let mut left = SplatViewModel::empty(SplatDeck::A); + let shared = Arc::new(CellBlocks { bars: 1, blocks: Vec::new() }); + left.blocks[0][0] = Some(shared.clone()); + let mut right = left.clone(); + assert_eq!(left, right); + + right.blocks[0][0] = Some(Arc::new((*shared).clone())); + assert_ne!(left, right); + } + + #[test] + fn span_seconds_convert_to_finest_pyramid_columns() { + assert_eq!(span_to_pyramid_columns((1.25, 2.5)), (125.0, 250.0)); + assert_eq!(span_to_pyramid_columns((3.0, 0.0)), (300.0, 0.0)); + assert_eq!(span_to_pyramid_columns((f32::NAN, 1.0)), (0.0, 0.0)); + } + + #[test] + fn cell_hit_maps_edges_and_rejects_outside_points() { + let rect = Rect { pos: dvec2(10.0, 20.0), size: dvec2(800.0, 250.0) }; + assert_eq!(cell_at(rect, dvec2(10.1, 20.1)), Some((0, 0))); + assert_eq!(cell_at(rect, dvec2(409.0, 145.0)), Some((2, 3))); + assert_eq!(cell_at(rect, dvec2(809.9, 269.9)), Some((4, 7))); + assert_eq!(cell_at(rect, dvec2(9.9, 20.0)), None); + assert_eq!(cell_at(rect, dvec2(810.0, 270.0)), None); + } + + #[test] + fn subloop_hit_maps_all_six_slots_and_cell_edges() { + let rect = Rect { pos: dvec2(10.0, 20.0), size: dvec2(120.0, 80.0) }; + let parts = [ + SplatPart { num: 0, den: 2 }, + SplatPart { num: 1, den: 2 }, + SplatPart { num: 0, den: 4 }, + SplatPart { num: 1, den: 4 }, + SplatPart { num: 2, den: 4 }, + SplatPart { num: 3, den: 4 }, + ]; + for part in parts { + let slot = slot_rect(rect, part); + assert_eq!( + part_at(slot_area(rect), slot.pos + slot.size * 0.5), + Some(part) + ); + } + assert_eq!( + part_at(rect, rect.pos + dvec2(0.001, 0.001)), + Some(SplatPart { num: 0, den: 2 }) + ); + assert_eq!( + part_at(rect, rect.pos + rect.size - dvec2(0.001, 0.001)), + Some(SplatPart { num: 3, den: 4 }) + ); + assert_eq!( + part_at(rect, dvec2(rect.pos.x + rect.size.x * 0.5, rect.pos.y + 0.001)), + Some(SplatPart { num: 1, den: 2 }) + ); + assert_eq!( + part_at(rect, dvec2(rect.pos.x + 0.001, rect.pos.y + rect.size.y * 0.5)), + Some(SplatPart { num: 0, den: 4 }) + ); + } + + #[test] + fn subloop_slot_rectangles_tile_without_overlap() { + let rect = Rect { pos: dvec2(4.0, 7.0), size: dvec2(100.0, 60.0) }; + let parts = [ + SplatPart { num: 0, den: 2 }, + SplatPart { num: 1, den: 2 }, + SplatPart { num: 0, den: 4 }, + SplatPart { num: 1, den: 4 }, + SplatPart { num: 2, den: 4 }, + SplatPart { num: 3, den: 4 }, + ]; + let slots = parts.map(|part| slot_rect(rect, part)); + for (index, left) in slots.iter().enumerate() { + for right in &slots[index + 1..] { + let overlap_w = (left.pos.x + left.size.x).min(right.pos.x + right.size.x) + - left.pos.x.max(right.pos.x); + let overlap_h = (left.pos.y + left.size.y).min(right.pos.y + right.size.y) + - left.pos.y.max(right.pos.y); + assert!(overlap_w <= 0.0 || overlap_h <= 0.0, "{left:?} overlaps {right:?}"); + } + } + let tiled_area: f64 = slots.iter().map(|slot| slot.size.x * slot.size.y).sum(); + let area = slot_area(rect); + assert!((tiled_area - area.size.x * area.size.y).abs() < 1e-9); + } +} diff --git a/apps/vj/src/loop_transcribe.rs b/apps/vj/src/loop_transcribe.rs new file mode 100644 index 000000000..8141ff992 --- /dev/null +++ b/apps/vj/src/loop_transcribe.rs @@ -0,0 +1,2288 @@ +//! Small, deterministic DSP transcribers for one loop-splat cell. +//! +//! Drums: log-mel front end (64 bands, 2048/256), superflux onsets, a +//! semi-supervised KL-NMF with analytic kick/snare/hat/tom/crash/ride +//! templates that adapt to the loop within a bounded drift plus two free +//! components for bleed, per-class peak picking snapped to the full-band +//! onset, then physical plausibility rules on the onset transient and its +//! tail (what still rings, measured away from other hits). Pitched lines: +//! YIN. The `#[ignore]`d tests render a real stem's transcription back +//! through the kit and time a four-bar loop. + +use makepad_ai_stems::stft::Stft; +use makepad_score_view::build::{DrumHit, DrumVoice, PitchedNote}; +use std::cmp::Ordering; + +const WINDOW: usize = 2048; +const HOP: usize = 256; +const MEL_BANDS: usize = 64; +const DRUM_COMPONENTS: usize = 6; +const NMF_COMPONENTS: usize = 8; +const NMF_ITERATIONS: usize = 40; +const NMF_EPSILON: f32 = 1.0e-8; +const ONSET_MEDIAN_SECS: f64 = 0.35; +const CLASS_GAP_SECS: f64 = 0.045; +const MERGE_SECS: f64 = 0.030; +const SNAP_SECS: f64 = 0.012; +const ACTIVATION_BACKTRACK_SECS: f64 = 0.060; +/// A class onset must at least double the activation that was sounding +/// 17-58 ms earlier (peak >= 2x the preceding level); a crash's 4-6 Hz shimmer +/// swings by ~25 %, stick hits in the acceptance patterns land at 0.6-1.0. +const RISE_MIN: f32 = 0.5; +/// Adapted templates may not drift further than this factor from their +/// analytic prior in any band, so a lone crash cannot turn the hat template +/// into a crash template. +const TEMPLATE_DRIFT: f32 = 3.0; +const YIN_MIN_HZ: f64 = 40.0; +const YIN_MAX_HZ: f64 = 400.0; +const YIN_APERIODICITY: f64 = 0.15; + +#[derive(Clone, Copy, Debug)] +pub struct LoopClock { + pub bpm: f64, + pub bars: u32, + pub beats_per_bar: u32, +} + +#[derive(Clone, Copy)] +struct Onset { + frame: usize, + strength: f32, + level: f32, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +enum DrumClass { + Kick, + Snare, + Hat, + Tom, + Crash, + Ride, +} + +impl DrumClass { + const ALL: [Self; DRUM_COMPONENTS] = [ + Self::Kick, + Self::Snare, + Self::Hat, + Self::Tom, + Self::Crash, + Self::Ride, + ]; + const CYMBALS: [usize; 2] = [4, 5]; + + /// The shortest interval at which the instrument can be struck again; + /// activation peaks closer than this are one hit (the kick's pitch sweep + /// makes its activation peak ~60 ms after the stick). + fn merge_seconds(self) -> f64 { + match self { + Self::Kick | Self::Tom | Self::Crash | Self::Ride => 0.070, + Self::Snare | Self::Hat => MERGE_SECS, + } + } +} + +struct MelSpectrogram { + /// Linear magnitude, mel-major: `mel * frames + frame`. + magnitude: Vec, + log_magnitude: Vec, + centers_hz: [f32; MEL_BANDS], + frames: usize, + /// Frames within -10..+60 ms of any full-band onset: another hit is + /// sounding there, so they say nothing about the tail of this one. + onset_mask: Vec, +} + +/// Transcribe percussion using a loop-adapted, semi-supervised KL-NMF. +pub fn transcribe_drums(mono: &[f32], sample_rate: u32, clock: &LoopClock) -> Vec { + if mono.len() < 2 || sample_rate == 0 || !clock.bpm.is_finite() || clock.bpm <= 0.0 { + return Vec::new(); + } + let stft = Stft::new(WINDOW, HOP, WINDOW); + let (spectrum, frames) = stft.forward(mono); + if frames < 2 { + return Vec::new(); + } + let mut mel = make_mel_spectrogram(&spectrum, frames, sample_rate, stft.bins()); + let peak_magnitude = mel.magnitude.iter().copied().fold(0.0f32, f32::max); + if peak_magnitude <= 1.0e-7 { + return Vec::new(); + } + + let full_flux = superflux(&mel); + let mut scratch = Vec::new(); + let mut full_onsets = pick_peaks( + &full_flux, + None, + sample_rate, + 0.020, + 0.020, + &mut scratch, + ); + let broadband_onsets = full_onsets.clone(); + let high_flux = superflux_range(&mel, 6_000.0, 16_001.0); + let high_onsets = pick_peaks( + &high_flux, + None, + sample_rate, + CLASS_GAP_SECS, + 0.015, + &mut scratch, + ); + full_onsets.extend(high_onsets.iter().copied()); + let cymbal_flux = superflux_range(&mel, 2_000.0, 6_000.0); + let cymbal_onsets = pick_peaks( + &cymbal_flux, + None, + sample_rate, + CLASS_GAP_SECS, + 0.010, + &mut scratch, + ); + full_onsets.extend(cymbal_onsets.iter().copied()); + merge_onsets(&mut full_onsets, sample_rate, 0.040, MergeAttack::EarliestStrong); + mel.mask_onsets(&full_onsets, sample_rate); + let (_templates, activations) = factorize_drums(&mel); + // Crash and ride templates trade a cymbal's energy back and forth as its + // spectrum shifts; onsets in either class are judged on their combined row. + let cymbal_row: Vec = (0..frames) + .map(|frame| { + DrumClass::CYMBALS + .iter() + .map(|&component| activations[component * frames + frame]) + .fold(0.0f32, f32::max) + }) + .collect(); + let snap_frames = ((SNAP_SECS * sample_rate as f64) / HOP as f64).floor().max(1.0) as usize; + let backtrack_frames = + ((ACTIVATION_BACKTRACK_SECS * sample_rate as f64) / HOP as f64).round() as usize; + let mut class_onsets: [Vec; DRUM_COMPONENTS] = std::array::from_fn(|component| { + let row = &activations[component * frames..(component + 1) * frames]; + let rise_row: &[f32] = if DrumClass::CYMBALS.contains(&component) { &cymbal_row } else { row }; + let differences = positive_difference(row); + let floor_ratio = match DrumClass::ALL[component] { + DrumClass::Kick => 0.040, + DrumClass::Snare => 0.020, + DrumClass::Hat => 0.008, + DrumClass::Tom => 0.020, + DrumClass::Crash | DrumClass::Ride => 0.0005, + }; + let onsets = pick_peaks( + &differences, + Some(row), + sample_rate, + CLASS_GAP_SECS, + floor_ratio, + &mut scratch, + ); + let mut onsets: Vec = onsets + .into_iter() + .filter_map(|mut onset| { + onset.frame = backtrack_activation(row, onset.frame, sample_rate); + let full = nearest_onset(onset.frame, &full_onsets, snap_frames) + .or_else(|| nearest_onset(onset.frame, &full_onsets, backtrack_frames))?; + onset.frame = full.frame; + (relative_rise(rise_row, onset.frame, sample_rate) >= RISE_MIN).then_some(onset) + }) + .collect(); + merge_onsets( + &mut onsets, + sample_rate, + DrumClass::ALL[component].merge_seconds(), + MergeAttack::Earliest, + ); + onsets + }); + add_spectral_anchors( + &mut class_onsets[2], + &high_onsets, + &activations[2 * frames..3 * frames], + None, + sample_rate, + None, + 0.012, + 0.0, + ); + for component in DrumClass::CYMBALS { + let row = &activations[component * frames..(component + 1) * frames]; + add_spectral_anchors( + &mut class_onsets[component], + &broadband_onsets, + row, + Some(&cymbal_row), + sample_rate, + None, + 0.003, + 0.005, + ); + add_spectral_anchors( + &mut class_onsets[component], + &cymbal_onsets, + row, + Some(&cymbal_row), + sample_rate, + Some(&broadband_onsets), + 0.003, + 0.030, + ); + } + suppress_implausible_onsets(&mut class_onsets, &mel, &activations, sample_rate); + let hat_spacing = suppress_implausible_hats(&mut class_onsets, &mel, sample_rate); + suppress_snare_hat_bleed(&mut class_onsets, &activations, &mel, frames, hat_spacing, sample_rate); + suppress_cymbals_on_snare(&mut class_onsets, sample_rate); + suppress_hats_under_cymbals(&mut class_onsets, &mel, hat_spacing, sample_rate); + + let mut cymbals: Vec = class_onsets[4].iter().chain(&class_onsets[5]).copied().collect(); + for onset in &mut cymbals { + onset.level = cymbal_level(&activations, onset.frame, frames); + } + merge_onsets(&mut cymbals, sample_rate, MERGE_SECS, MergeAttack::Earliest); + let groups: [(&[Onset], DrumClass); 5] = [ + (&class_onsets[0], DrumClass::Kick), + (&class_onsets[1], DrumClass::Snare), + (&class_onsets[2], DrumClass::Hat), + (&class_onsets[3], DrumClass::Tom), + (&cymbals, DrumClass::Crash), + ]; + let mut hits = Vec::new(); + let total_beats = f64::from(clock.bars) * f64::from(clock.beats_per_bar); + for (onsets, class) in groups { + let reference = percentile( + &mut onsets.iter().map(|onset| onset.level).collect::>(), + 0.95, + ) + .max(NMF_EPSILON); + for onset in onsets { + let voice = match class { + DrumClass::Kick => DrumVoice::Kick, + DrumClass::Snare => DrumVoice::Snare, + DrumClass::Hat => { + classify_hat(onset, &activations[2 * frames..3 * frames], sample_rate) + } + DrumClass::Tom => classify_tom(onset.frame, &mel, sample_rate), + DrumClass::Crash | DrumClass::Ride => classify_cymbal(onset, &mel, sample_rate), + }; + let velocity = (0.15 + 0.85 * (onset.level / reference).min(1.0)).clamp(0.15, 1.0); + let onset_sample = onset.frame * HOP; + let time_beats = onset_sample as f64 / sample_rate as f64 * clock.bpm / 60.0; + if time_beats >= total_beats { + continue; + } + hits.push(DrumHit { + time_beats, + voice, + velocity, + }); + } + } + hits.sort_by(|a, b| { + a.time_beats + .partial_cmp(&b.time_beats) + .unwrap_or(Ordering::Equal) + .then_with(|| a.voice.gm_note().cmp(&b.voice.gm_note())) + }); + hits +} + +fn make_mel_spectrogram( + spectrum: &[f32], + frames: usize, + sample_rate: u32, + bins: usize, +) -> MelSpectrogram { + let nyquist = sample_rate as f32 * 0.5; + let high_hz = 16_000.0f32.min(nyquist); + let low_mel = hz_to_mel(20.0); + let high_mel = hz_to_mel(high_hz.max(21.0)); + let mut edges_hz = [0.0f32; MEL_BANDS + 2]; + for (index, edge) in edges_hz.iter_mut().enumerate() { + let amount = index as f32 / (MEL_BANDS + 1) as f32; + *edge = mel_to_hz(low_mel + (high_mel - low_mel) * amount); + } + let centers_hz = std::array::from_fn(|index| edges_hz[index + 1]); + let mut magnitude = vec![0.0f32; MEL_BANDS * frames]; + let fft_scale = 2.0 / WINDOW as f32; + for mel_band in 0..MEL_BANDS { + let left = edges_hz[mel_band]; + let center = edges_hz[mel_band + 1]; + let right = edges_hz[mel_band + 2]; + let mut weight_sum = 0.0f32; + for bin in 0..bins { + let hz = bin as f32 * sample_rate as f32 / WINDOW as f32; + let weight = if hz < left || hz > right { + 0.0 + } else if hz <= center { + (hz - left) / (center - left).max(f32::EPSILON) + } else { + (right - hz) / (right - center).max(f32::EPSILON) + }; + if weight <= 0.0 { + continue; + } + weight_sum += weight; + for frame in 0..frames { + magnitude[mel_band * frames + frame] += + weight * magnitude_at(spectrum, frames, bin, frame) * fft_scale; + } + } + if weight_sum > 0.0 { + for value in &mut magnitude[mel_band * frames..(mel_band + 1) * frames] { + *value /= weight_sum; + } + } + } + let log_magnitude = magnitude.iter().map(|value| (1.0 + 100.0 * value).ln()).collect(); + MelSpectrogram { + magnitude, + log_magnitude, + centers_hz, + frames, + onset_mask: vec![false; frames], + } +} + +impl MelSpectrogram { + /// Mask the frames around every full-band onset that is a real attack: + /// one where the total magnitude at least doubles what was sounding + /// before it. Flux bumps in a decaying cymbal do not qualify, so they do + /// not hide the cymbal's own tail. + fn mask_onsets(&mut self, onsets: &[Onset], sample_rate: u32) { + let total: Vec = (0..self.frames) + .map(|frame| (0..MEL_BANDS).map(|band| self.magnitude[band * self.frames + frame]).sum()) + .collect(); + let frames_per_ms = sample_rate as f64 / HOP as f64 / 1000.0; + let before = (10.0 * frames_per_ms).round() as usize; + let after = (60.0 * frames_per_ms).round() as usize; + for onset in onsets { + if relative_rise(&total, onset.frame, sample_rate) < RISE_MIN { + continue; + } + let start = onset.frame.saturating_sub(before); + let end = (onset.frame + after).min(self.frames - 1); + for masked in &mut self.onset_mask[start..=end] { + *masked = true; + } + } + } +} + +#[inline] +fn hz_to_mel(hz: f32) -> f32 { + 2595.0 * (1.0 + hz / 700.0).log10() +} + +#[inline] +fn mel_to_hz(mel: f32) -> f32 { + 700.0 * (10.0f32.powf(mel / 2595.0) - 1.0) +} + +fn superflux(mel: &MelSpectrogram) -> Vec { + superflux_range(mel, 20.0, 16_001.0) +} + +fn superflux_range(mel: &MelSpectrogram, low_hz: f32, high_hz: f32) -> Vec { + let mut flux = vec![0.0f32; mel.frames]; + let mut selected_bands = 0usize; + for frame in 0..mel.frames { + let mut sum = 0.0f32; + for band in 0..MEL_BANDS { + if mel.centers_hz[band] < low_hz || mel.centers_hz[band] >= high_hz { + continue; + } + if frame == 0 { + selected_bands += 1; + } + let current = mel.log_magnitude[band * mel.frames + frame]; + let previous = if frame == 0 { + 0.0 + } else { + let start = band.saturating_sub(1); + let end = (band + 2).min(MEL_BANDS); + (start..end) + .map(|nearby| mel.log_magnitude[nearby * mel.frames + frame - 1]) + .fold(0.0f32, f32::max) + }; + sum += (current - previous).max(0.0); + } + flux[frame] = sum; + } + if selected_bands != 0 { + for value in &mut flux { + *value /= selected_bands as f32; + } + } + flux +} + +fn factorize_drums(mel: &MelSpectrogram) -> (Vec, Vec) { + let mut templates = analytic_templates(&mel.centers_hz); + let priors = templates.clone(); + let mut activations = vec![NMF_EPSILON; NMF_COMPONENTS * mel.frames]; + for component in 0..NMF_COMPONENTS { + let norm = (0..MEL_BANDS) + .map(|band| templates[band * NMF_COMPONENTS + component].powi(2)) + .sum::() + .max(NMF_EPSILON); + for frame in 0..mel.frames { + let projection = (0..MEL_BANDS) + .map(|band| { + templates[band * NMF_COMPONENTS + component] + * mel.magnitude[band * mel.frames + frame] + }) + .sum::(); + activations[component * mel.frames + frame] = (projection / norm).max(NMF_EPSILON); + } + } + + let mut reconstruction = vec![0.0f32; MEL_BANDS * mel.frames]; + for _ in 0..NMF_ITERATIONS { + reconstruct(&templates, &activations, mel.frames, &mut reconstruction); + for component in 0..NMF_COMPONENTS { + let denominator = (0..MEL_BANDS) + .map(|band| templates[band * NMF_COMPONENTS + component]) + .sum::() + .max(NMF_EPSILON); + for frame in 0..mel.frames { + let numerator = (0..MEL_BANDS) + .map(|band| { + let index = band * mel.frames + frame; + templates[band * NMF_COMPONENTS + component] + * mel.magnitude[index] + / reconstruction[index].max(NMF_EPSILON) + }) + .sum::(); + let at = component * mel.frames + frame; + activations[at] = + (activations[at] * numerator / denominator).max(NMF_EPSILON); + } + } + + reconstruct(&templates, &activations, mel.frames, &mut reconstruction); + for component in 0..NMF_COMPONENTS { + let denominator = activations[component * mel.frames..(component + 1) * mel.frames] + .iter() + .copied() + .sum::() + .max(NMF_EPSILON); + let learning_rate = if component < DRUM_COMPONENTS { 0.08 } else { 1.0 }; + for band in 0..MEL_BANDS { + let numerator = (0..mel.frames) + .map(|frame| { + let index = band * mel.frames + frame; + activations[component * mel.frames + frame] + * mel.magnitude[index] + / reconstruction[index].max(NMF_EPSILON) + }) + .sum::(); + let ratio = (numerator / denominator).clamp(0.25, 4.0); + let at = band * NMF_COMPONENTS + component; + templates[at] = + (templates[at] * ratio.powf(learning_rate)).max(NMF_EPSILON); + if component < DRUM_COMPONENTS { + templates[at] = templates[at] + .clamp(priors[at] / TEMPLATE_DRIFT, priors[at] * TEMPLATE_DRIFT); + } + } + normalize_template(&mut templates, &mut activations, component, mel.frames); + } + } + (templates, activations) +} + +fn analytic_templates(centers_hz: &[f32; MEL_BANDS]) -> Vec { + let mut templates = vec![NMF_EPSILON; MEL_BANDS * NMF_COMPONENTS]; + for (band, &hz) in centers_hz.iter().enumerate() { + let values = [ + 0.90 * log_gaussian(hz, 65.0, 0.48) + 0.10 * log_gaussian(hz, 2_100.0, 0.48), + 0.43 * log_gaussian(hz, 230.0, 0.30) + 0.57 * log_gaussian(hz, 3_100.0, 0.68), + log_gaussian(hz, 10_200.0, 0.30), + log_gaussian(hz, 145.0, 0.62), + log_gaussian(hz, 7_000.0, 0.70), + log_gaussian(hz, 3_000.0, 0.50), + log_gaussian(hz, 90.0, 0.90), + log_gaussian(hz, 720.0, 0.90), + ]; + for component in 0..NMF_COMPONENTS { + templates[band * NMF_COMPONENTS + component] = values[component].max(NMF_EPSILON); + } + } + for component in 0..NMF_COMPONENTS { + let mut dummy = Vec::new(); + normalize_template(&mut templates, &mut dummy, component, 0); + } + templates +} + +#[inline] +fn log_gaussian(hz: f32, center: f32, width: f32) -> f32 { + (-0.5 * (hz.max(1.0) / center).ln().powi(2) / width.powi(2)).exp() +} + +fn normalize_template( + templates: &mut [f32], + activations: &mut [f32], + component: usize, + frames: usize, +) { + let sum = (0..MEL_BANDS) + .map(|band| templates[band * NMF_COMPONENTS + component]) + .sum::() + .max(NMF_EPSILON); + for band in 0..MEL_BANDS { + templates[band * NMF_COMPONENTS + component] /= sum; + } + if frames != 0 { + for value in &mut activations[component * frames..(component + 1) * frames] { + *value *= sum; + } + } +} + +fn reconstruct(templates: &[f32], activations: &[f32], frames: usize, out: &mut [f32]) { + for band in 0..MEL_BANDS { + for frame in 0..frames { + let mut value = NMF_EPSILON; + for component in 0..NMF_COMPONENTS { + value += templates[band * NMF_COMPONENTS + component] + * activations[component * frames + frame]; + } + out[band * frames + frame] = value; + } + } +} + +fn positive_difference(values: &[f32]) -> Vec { + let mut differences = vec![0.0f32; values.len()]; + if let Some(first) = values.first() { + differences[0] = *first; + } + for frame in 1..values.len() { + differences[frame] = (values[frame] - values[frame - 1]).max(0.0); + } + differences +} + +fn pick_peaks( + novelty: &[f32], + levels: Option<&[f32]>, + sample_rate: u32, + gap_secs: f64, + floor_ratio: f32, + scratch: &mut Vec, +) -> Vec { + if novelty.is_empty() { + return Vec::new(); + } + let maximum = novelty.iter().copied().fold(0.0f32, f32::max); + if maximum <= NMF_EPSILON { + return Vec::new(); + } + let radius = ((ONSET_MEDIAN_SECS * sample_rate as f64) / HOP as f64).round() as usize; + let gap = ((gap_secs * sample_rate as f64) / HOP as f64).ceil().max(1.0) as usize; + let level_max = levels + .map(|row| row.iter().copied().fold(0.0f32, f32::max)) + .unwrap_or(0.0); + let mut onsets: Vec = Vec::new(); + for frame in 0..novelty.len() { + let start = frame.saturating_sub(radius); + let end = (frame + radius + 1).min(novelty.len()); + scratch.clear(); + scratch.extend_from_slice(&novelty[start..end]); + let threshold = median_in_place(scratch) + maximum * floor_ratio; + let value = novelty[frame]; + let left = frame.checked_sub(1).map_or(0.0, |at| novelty[at]); + let right = novelty.get(frame + 1).copied().unwrap_or(0.0); + let level = levels.map_or(value, |row| local_peak(row, frame, 2)); + if value <= threshold + || value < left + || value < right + || levels.is_some_and(|_| level < level_max * 0.012) + { + continue; + } + if let Some(previous) = onsets.last_mut().filter(|last| frame - last.frame < gap) { + if value > previous.strength { + *previous = Onset { frame, strength: value, level }; + } + } else { + onsets.push(Onset { frame, strength: value, level }); + } + } + onsets +} + +fn nearest_onset(frame: usize, onsets: &[Onset], radius: usize) -> Option { + onsets + .iter() + .copied() + .filter(|onset| onset.frame.abs_diff(frame) <= radius) + .min_by(|a, b| { + a.frame + .abs_diff(frame) + .cmp(&b.frame.abs_diff(frame)) + .then_with(|| b.strength.partial_cmp(&a.strength).unwrap_or(Ordering::Equal)) + }) +} + +fn backtrack_activation(values: &[f32], peak: usize, sample_rate: u32) -> usize { + let maximum_backtrack = ((0.060 * sample_rate as f64) / HOP as f64).round() as usize; + let floor = values[peak] * 0.25; + let first = peak.saturating_sub(maximum_backtrack); + for frame in (first..peak).rev() { + if values[frame] <= floor { + return frame + 1; + } + } + first +} + +/// Fraction of the activation peak right after `frame` that is new energy +/// rather than what was already sounding 17-58 ms before it. Comparing with +/// the preceding maximum means a bump shortly after a real attack scores +/// near zero instead of reading the pre-attack silence as its floor. +fn relative_rise(row: &[f32], frame: usize, sample_rate: u32) -> f32 { + if row.is_empty() { + return 0.0; + } + let (peak, before) = rise_levels(row, frame, sample_rate); + (peak - before).max(0.0) / peak.max(NMF_EPSILON) +} + +/// The activation peak within -6..+30 ms of `frame` and the highest level in +/// the 17-58 ms before it. +fn rise_levels(row: &[f32], frame: usize, sample_rate: u32) -> (f32, f32) { + let frames_per_ms = sample_rate as f64 / HOP as f64 / 1000.0; + let at_ms = |ms: f64| (ms * frames_per_ms).round() as usize; + let last = row.len() - 1; + let peak_start = frame.saturating_sub(1).min(last); + let peak_end = (frame + at_ms(30.0)).min(last); + let peak = row[peak_start..=peak_end].iter().copied().fold(0.0f32, f32::max); + let before_start = frame.saturating_sub(at_ms(58.0)); + let before_end = frame.saturating_sub(at_ms(17.0)).min(last); + let before = if before_end > before_start { + row[before_start..before_end].iter().copied().fold(0.0f32, f32::max) + } else { + 0.0 + }; + (peak, before) +} + +fn local_peak(values: &[f32], frame: usize, radius: usize) -> f32 { + let start = frame.saturating_sub(radius); + let end = (frame + radius + 1).min(values.len()); + values[start..end].iter().copied().fold(0.0f32, f32::max) +} + +#[derive(Clone, Copy, PartialEq, Eq)] +enum MergeAttack { + /// The first onset of the cluster is the attack (class activations peak + /// late: the kick's pitch sweep, a crash's bloom). + Earliest, + /// The first onset carrying at least half the cluster's level is the + /// attack (a weak spectral-flux precursor at the analysis window's edge + /// is not). + EarliestStrong, +} + +/// Collapse onsets closer than `seconds` into one hit; the loudest level of +/// the cluster is its velocity. +fn merge_onsets(onsets: &mut Vec, sample_rate: u32, seconds: f64, attack: MergeAttack) { + let gap = ((seconds * sample_rate as f64) / HOP as f64).ceil() as usize; + onsets.sort_by_key(|onset| onset.frame); + let mut merged: Vec = Vec::with_capacity(onsets.len()); + let mut cluster: Vec = Vec::new(); + let flush = |cluster: &mut Vec, merged: &mut Vec| { + if cluster.is_empty() { + return; + } + let level = cluster.iter().map(|onset| onset.level).fold(0.0f32, f32::max); + let strength = cluster.iter().map(|onset| onset.strength).fold(0.0f32, f32::max); + let attack_frame = match attack { + MergeAttack::Earliest => cluster[0].frame, + MergeAttack::EarliestStrong => cluster + .iter() + .find(|onset| onset.level >= level * 0.5) + .map_or(cluster[0].frame, |onset| onset.frame), + }; + merged.push(Onset { frame: attack_frame, strength, level }); + cluster.clear(); + }; + for onset in onsets.drain(..) { + if cluster.last().is_some_and(|last| onset.frame - last.frame > gap) { + flush(&mut cluster, &mut merged); + } + cluster.push(onset); + } + flush(&mut cluster, &mut merged); + *onsets = merged; +} + +#[allow(clippy::too_many_arguments)] +fn add_spectral_anchors( + class_onsets: &mut Vec, + spectral_onsets: &[Onset], + activation: &[f32], + rise_row: Option<&[f32]>, + sample_rate: u32, + snap_back: Option<&[Onset]>, + minimum_level_ratio: f32, + minimum_rise_ratio: f32, +) { + let peak = activation.iter().copied().fold(0.0f32, f32::max); + let differences = positive_difference(activation); + let peak_rise = differences.iter().copied().fold(0.0f32, f32::max); + let maximum_backtrack = ((0.250 * sample_rate as f64) / HOP as f64).round() as usize; + for spectral in spectral_onsets { + let level = local_peak(activation, spectral.frame, 3); + let rise = local_peak(&differences, spectral.frame, 3); + if level >= peak * minimum_level_ratio + && rise >= peak_rise * minimum_rise_ratio + && relative_rise(rise_row.unwrap_or(activation), spectral.frame, sample_rate) + >= RISE_MIN + { + let frame = snap_back + .and_then(|anchors| { + anchors + .iter() + .filter(|anchor| { + anchor.frame <= spectral.frame + && spectral.frame - anchor.frame <= maximum_backtrack + }) + .max_by_key(|anchor| anchor.frame) + .map(|anchor| anchor.frame) + }) + .unwrap_or(spectral.frame); + class_onsets.push(Onset { + frame, + strength: rise.max(spectral.strength * NMF_EPSILON), + level, + }); + } + } + merge_onsets(class_onsets, sample_rate, CLASS_GAP_SECS, MergeAttack::Earliest); +} + +fn suppress_implausible_onsets( + onsets: &mut [Vec; DRUM_COMPONENTS], + mel: &MelSpectrogram, + activations: &[f32], + sample_rate: u32, +) { + for component in 0..DRUM_COMPONENTS { + let class = DrumClass::ALL[component]; + if class == DrumClass::Hat { + continue; + } + onsets[component].retain(|onset| { + let frame = onset.frame.min(mel.frames - 1); + let shares = TransientShares::at(mel, frame, sample_rate); + let tail_peak = mel_transient_peak_hz(mel, frame, 0.120, sample_rate, 35.0, 300.0); + let own = onset.level; + let spectral_match = match class { + DrumClass::Kick => shares.low + shares.body >= 0.25 && tail_peak < 75.0, + DrumClass::Snare => shares.body >= 0.10 && shares.wires >= 0.10 && shares.high < 0.55, + DrumClass::Hat => unreachable!(), + DrumClass::Tom => { + shares.low + shares.body >= 0.25 + && shares.wires + shares.high < 0.18 + && tail_peak >= 75.0 + } + DrumClass::Crash | DrumClass::Ride => { + // What still rings 80-220 ms later must be a cymbal's + // body (2-6 kHz), not only an open hat's air; judged on + // the tail so a hat or kick struck at the same instant + // does not hide the crash. + let hat = component_level(activations, 2, frame, mel.frames); + let tail = |low, high| { + mel_tail_energy(mel, frame, sample_rate, low, high, 0.080, 0.220) + }; + let sustain = + mel_sustain_ratio(mel, frame, sample_rate, 2_000.0, 6_000.0); + tail(2_000.0, 6_000.0) >= 0.5 * tail(7_000.0, 16_001.0) + && shares.wires >= 0.005 + && own_ratio(own, hat) >= 0.08 + && sustain >= 0.15 + } + }; + let strongest = (0..DRUM_COMPONENTS) + .map(|other| component_level(activations, other, frame, mel.frames)) + .fold(0.0f32, f32::max); + let dominance = match class { + DrumClass::Kick | DrumClass::Tom => 0.015, + DrumClass::Snare => 0.05, + DrumClass::Hat => unreachable!(), + DrumClass::Crash | DrumClass::Ride => 0.001, + }; + spectral_match && own >= strongest * dominance + }); + } +} + +/// Band shares of one onset's transient (each relative to the 20 Hz-16 kHz total). +struct TransientShares { + low: f32, + body: f32, + wires: f32, + high: f32, + /// Absolute 7-16 kHz transient: what a hat puts on the table. + air: f32, +} + +impl TransientShares { + fn at(mel: &MelSpectrogram, frame: usize, sample_rate: u32) -> Self { + let band = |low: f32, high: f32| mel_transient_band_sum(mel, frame, sample_rate, low, high); + let total = band(20.0, 16_001.0).max(NMF_EPSILON); + let air = band(7_000.0, 16_001.0); + Self { + low: band(20.0, 170.0) / total, + body: band(170.0, 520.0) / total, + wires: band(1_000.0, 7_000.0) / total, + high: band(6_000.0, 16_001.0) / total, + air, + } + } + + /// A hat heard on its own: most of the transient above 6 kHz. + fn is_hat_spectrum(&self) -> bool { + self.high >= 0.30 && self.high >= self.wires * 1.2 + } +} + +/// The hat grid of this loop: the median interval between spectrally certain +/// hats (heard on their own), halved when most of the midpoints between them +/// also carry a hat candidate (every other hat sits under a kick or snare). +/// A single midpoint candidate in an otherwise empty gap is not a grid; that +/// is what a ghost snare's wires or a ride's air look like. +fn prevailing_hat_spacing(certain: &[usize], candidates: &[usize], sample_rate: u32) -> Option { + if certain.len() < 3 { + return None; + } + let tolerance = ((0.035 * sample_rate as f64) / HOP as f64).ceil() as usize; + let mut intervals: Vec = certain.windows(2).map(|pair| pair[1] - pair[0]).collect(); + intervals.sort_unstable(); + let spacing = intervals[intervals.len() / 2]; + let mut gaps = 0usize; + let mut filled = 0usize; + for pair in certain.windows(2) { + if (pair[1] - pair[0]).abs_diff(spacing) > tolerance { + continue; + } + gaps += 1; + let midpoint = (pair[0] + pair[1]) / 2; + if candidates.iter().any(|&frame| frame.abs_diff(midpoint) <= tolerance) { + filled += 1; + } + } + Some(if filled >= 2 && filled * 3 >= gaps * 2 { spacing / 2 } else { spacing }) +} + +/// Hats. A hat heard on its own (most of its transient above 6 kHz) stands. +/// A hat under a kick, snare or cymbal stands only on the loop's hat grid and +/// when the onset brings at least 80 % of a lone hat's air (a kick's click +/// alone brings about half) or is a low drum with more air than a click. +/// With no grid to lean on, only the latter passes. Returns the grid spacing +/// for the later co-onset rules. +fn suppress_implausible_hats( + onsets: &mut [Vec; DRUM_COMPONENTS], + mel: &MelSpectrogram, + sample_rate: u32, +) -> Option { + let features: Vec<(Onset, TransientShares)> = onsets[2] + .iter() + .map(|onset| (*onset, TransientShares::at(mel, onset.frame.min(mel.frames - 1), sample_rate))) + .collect(); + let certain: Vec = features + .iter() + .filter(|(_, shares)| shares.is_hat_spectrum()) + .map(|(onset, _)| onset.frame) + .collect(); + let lone_air = percentile( + &mut features + .iter() + .filter(|(_, shares)| shares.is_hat_spectrum()) + .map(|(_, shares)| shares.air) + .collect::>(), + 0.5, + ); + // A low drum whose onset carries more air than a kick's click alone. + let kick_with_air = + |shares: &TransientShares| shares.low + shares.body >= 0.70 && shares.high >= 0.015; + // At least 80 % of what a lone hat in this loop puts in the air band. + let hat_worth_of_air = |shares: &TransientShares| !certain.is_empty() && shares.air >= lone_air * 0.8; + let airy: Vec = features + .iter() + .filter(|(_, shares)| hat_worth_of_air(shares)) + .map(|(onset, _)| onset.frame) + .collect(); + let spacing = prevailing_hat_spacing(&certain, &airy, sample_rate); + if spacing.is_none() { + // Too few lone hats to know the grid: only the spectrum can vouch for + // a buried hat, and only a kick's can (a snare's own air is far more + // than a hat's). + onsets[2] = features + .iter() + .filter(|(_, shares)| shares.is_hat_spectrum() || kick_with_air(shares)) + .map(|(onset, _)| *onset) + .collect(); + return None; + } + let brings_air = |shares: &TransientShares| hat_worth_of_air(shares) || kick_with_air(shares); + // Grid membership is judged against the hats that survive, so a chain of + // rejected candidates cannot vouch for one another. + let mut accepted: Vec = features.iter().map(|(onset, _)| *onset).collect(); + loop { + let kept: Vec = features + .iter() + .filter(|(onset, shares)| { + shares.is_hat_spectrum() + || (brings_air(shares) + && regular_hat_neighbors(onset.frame, &accepted, spacing, sample_rate)) + }) + .map(|(onset, _)| *onset) + .collect(); + let stable = kept.len() == accepted.len(); + accepted = kept; + if stable { + break; + } + } + onsets[2] = accepted; + spacing +} + +fn suppress_snare_hat_bleed( + onsets: &mut [Vec; DRUM_COMPONENTS], + activations: &[f32], + mel: &MelSpectrogram, + frames: usize, + spacing: Option, + sample_rate: u32, +) { + let near = ((0.010 * sample_rate as f64) / HOP as f64).ceil() as usize; + let radius = ((ONSET_MEDIAN_SECS * sample_rate as f64) / HOP as f64).round() as usize; + let snares = onsets[1].clone(); + let hats = onsets[2].clone(); + let hat_row = &activations[2 * frames..3 * frames]; + onsets[2].retain(|hat| { + if !snares.iter().any(|snare| snare.frame.abs_diff(hat.frame) <= near) { + return true; + } + if regular_hat_neighbors(hat.frame, &hats, spacing, sample_rate) { + return true; + } + let start = hat.frame.saturating_sub(radius); + let end = (hat.frame + radius + 1).min(frames); + let mut local = hat_row[start..end].to_vec(); + let high = TransientShares::at(mel, hat.frame.min(mel.frames - 1), sample_rate).high; + hat.level >= 2.0 * median_in_place(&mut local) && high >= 0.30 + }); +} + +fn suppress_cymbals_on_snare( + onsets: &mut [Vec; DRUM_COMPONENTS], + sample_rate: u32, +) { + let near = ((0.010 * sample_rate as f64) / HOP as f64).ceil() as usize; + let snares = onsets[1].clone(); + for component in DrumClass::CYMBALS { + onsets[component].retain(|cymbal| { + !snares + .iter() + .any(|snare| snare.frame.abs_diff(cymbal.frame) <= near) + }); + } +} + +/// A hat onset that coincides with a cymbal onset is the cymbal's own air +/// when the 7-16 kHz band is still ringing 150-250 ms later, unless the hat +/// sits on the hat grid (then a stick really hit both). +fn suppress_hats_under_cymbals( + onsets: &mut [Vec; DRUM_COMPONENTS], + mel: &MelSpectrogram, + spacing: Option, + sample_rate: u32, +) { + let near = ((0.015 * sample_rate as f64) / HOP as f64).ceil() as usize; + let cymbals: Vec = onsets[4].iter().chain(&onsets[5]).copied().collect(); + let hats = onsets[2].clone(); + onsets[2].retain(|hat| { + if !cymbals.iter().any(|cymbal| cymbal.frame.abs_diff(hat.frame) <= near) { + return true; + } + if regular_hat_neighbors(hat.frame, &hats, spacing, sample_rate) { + return true; + } + let air = mel_sustain_ratio_between( + mel, + hat.frame, + sample_rate, + 7_000.0, + 16_001.0, + 0.150, + 0.250, + ); + air < 0.25 + }); +} + +/// Does this hat sit on the loop's hat grid: its distance to the previous and +/// the next hat is the prevailing spacing or twice it (a rest or a missed hat +/// between). A hat halfway between two grid hats is not on the grid; that is +/// where ghost snares and rides bleed into the hat band. Without a known +/// grid, equal spacing to both neighbours (up to a quarter note at 100 bpm) +/// counts. +fn regular_hat_neighbors( + frame: usize, + hats: &[Onset], + spacing: Option, + sample_rate: u32, +) -> bool { + let tolerance = ((0.035 * sample_rate as f64) / HOP as f64).ceil() as usize; + let maximum_step = ((0.600 * sample_rate as f64) / HOP as f64).ceil() as usize; + let Some(index) = hats.iter().position(|hat| hat.frame == frame) else { + return false; + }; + let on_grid = |step: usize| match spacing { + Some(spacing) => step.abs_diff(spacing) <= tolerance || step.abs_diff(2 * spacing) <= tolerance, + None => step <= maximum_step, + }; + let matches = |a: usize, b: usize| { + on_grid(a) && on_grid(b) && (spacing.is_some() || a.abs_diff(b) <= tolerance) + }; + if index > 0 && index + 1 < hats.len() { + return matches( + frame - hats[index - 1].frame, + hats[index + 1].frame - frame, + ); + } + if index >= 2 { + return matches( + frame - hats[index - 1].frame, + hats[index - 1].frame - hats[index - 2].frame, + ); + } + if index + 2 < hats.len() { + return matches( + hats[index + 1].frame - frame, + hats[index + 2].frame - hats[index + 1].frame, + ); + } + false +} + +/// Open when the hat activation still holds more than a quarter of the hit's +/// own rise 60-110 ms later. The 25th percentile over that window ignores +/// the next 16th-note hat; measuring above the pre-onset level ignores a +/// cymbal ringing underneath. +fn classify_hat(onset: &Onset, activation: &[f32], sample_rate: u32) -> DrumVoice { + let frames_per_ms = sample_rate as f64 / HOP as f64 / 1000.0; + let last = activation.len() - 1; + let start = (onset.frame + (60.0 * frames_per_ms).round() as usize).min(last); + let end = (onset.frame + (110.0 * frames_per_ms).round() as usize).min(last); + let mut tail = activation[start..=end].to_vec(); + let tail = percentile(&mut tail, 0.25); + let (peak, before) = rise_levels(activation, onset.frame, sample_rate); + if tail - before > 0.25 * (peak - before) { + DrumVoice::HiHatOpen + } else { + DrumVoice::HiHatClosed + } +} + +fn classify_tom(frame: usize, mel: &MelSpectrogram, sample_rate: u32) -> DrumVoice { + match mel_transient_peak_hz(mel, frame, 0.0, sample_rate, 55.0, 500.0) { + hz if hz >= 210.0 => DrumVoice::TomHigh, + hz if hz >= 150.0 => DrumVoice::TomMid, + hz if hz >= 110.0 => DrumVoice::TomLow, + _ => DrumVoice::TomFloor, + } +} + +/// Crash or ride. A crash keeps blooming 350-450 ms after the hit and its +/// sustain is air-heavy (7-16 kHz, measured 0.55-0.6 of the 2-16 kHz tail); +/// a ride's sustain is its 2-6 kHz ping with little above 7 kHz (0.2-0.35). +fn classify_cymbal(onset: &Onset, mel: &MelSpectrogram, sample_rate: u32) -> DrumVoice { + let bloom = + mel_sustain_ratio_between(mel, onset.frame, sample_rate, 2_000.0, 16_001.0, 0.350, 0.450); + let air = mel_tail_energy(mel, onset.frame, sample_rate, 7_000.0, 16_001.0, 0.080, 0.220); + let all = mel_tail_energy(mel, onset.frame, sample_rate, 2_000.0, 16_001.0, 0.080, 0.220); + let air_share = air / all.max(NMF_EPSILON); + if bloom >= 0.25 || air_share >= 0.45 { + DrumVoice::Crash + } else { + DrumVoice::Ride + } +} + +fn mel_transient_band_sum( + mel: &MelSpectrogram, + frame: usize, + sample_rate: u32, + low: f32, + high: f32, +) -> f32 { + mel.centers_hz + .iter() + .enumerate() + .filter(|(_, hz)| **hz >= low && **hz < high) + .map(|(band, _)| mel_transient(mel, band, frame, sample_rate)) + .sum() +} + +/// A steady tone (bass bleed) wobbles a few percent from frame to frame; only +/// what rises more than 25 % above the pre-onset floor counts as transient. +const TRANSIENT_FLOOR_GAIN: f32 = 1.25; + +fn mel_transient(mel: &MelSpectrogram, band: usize, frame: usize, sample_rate: u32) -> f32 { + let row = &mel.magnitude[band * mel.frames..(band + 1) * mel.frames]; + let (peak, before) = rise_levels_min_floor(row, frame, sample_rate); + (peak - TRANSIENT_FLOOR_GAIN * before).max(0.0) +} + +/// Like `rise_levels`, but the floor is the minimum of the preceding window. +fn rise_levels_min_floor(row: &[f32], frame: usize, sample_rate: u32) -> (f32, f32) { + let frames_per_ms = sample_rate as f64 / HOP as f64 / 1000.0; + let at_ms = |ms: f64| (ms * frames_per_ms).round() as usize; + let last = row.len() - 1; + let frame = frame.min(last); + let peak_start = frame.saturating_sub(1); + let peak_end = (frame + at_ms(30.0)).min(last); + let peak = row[peak_start..=peak_end].iter().copied().fold(0.0f32, f32::max); + let before_start = frame.saturating_sub(at_ms(58.0)); + let before_end = frame.saturating_sub(at_ms(17.0)); + let before = if before_end > before_start { + row[before_start..before_end].iter().copied().fold(f32::MAX, f32::min) + } else { + 0.0 + }; + (peak, before) +} + +fn mel_sustain_ratio( + mel: &MelSpectrogram, + frame: usize, + sample_rate: u32, + low: f32, + high: f32, +) -> f32 { + mel_sustain_ratio_between(mel, frame, sample_rate, low, high, 0.080, 0.220) +} + +/// Band energy above the pre-onset background, held over the window +/// `start_secs..end_secs` after the onset, relative to the onset transient. +/// The 25th percentile over the window is what a sustained cymbal keeps up and +/// an interleaved 16th-note hat cannot fake with one spike. +fn mel_sustain_ratio_between( + mel: &MelSpectrogram, + frame: usize, + sample_rate: u32, + low: f32, + high: f32, + start_secs: f64, + end_secs: f64, +) -> f32 { + let onset = mel_transient_band_sum(mel, frame, sample_rate, low, high); + mel_tail_energy(mel, frame, sample_rate, low, high, start_secs, end_secs) + / onset.max(NMF_EPSILON) +} + +/// 25th percentile, over `start_secs..end_secs` after the onset, of the band +/// energy above the pre-onset background, skipping frames where another +/// full-band onset is sounding (a snare 130 ms later is not this hit's tail). +/// Fewer than four free frames is no evidence of a tail. +fn mel_tail_energy( + mel: &MelSpectrogram, + frame: usize, + sample_rate: u32, + low: f32, + high: f32, + start_secs: f64, + end_secs: f64, +) -> f32 { + let frame = frame.min(mel.frames - 1); + let frames_per_sec = sample_rate as f64 / HOP as f64; + let start = (frame + (start_secs * frames_per_sec).round() as usize).min(mel.frames - 1); + let end = (frame + (end_secs * frames_per_sec).round() as usize).min(mel.frames - 1); + let bands: Vec<(usize, f32)> = mel + .centers_hz + .iter() + .enumerate() + .filter(|(_, hz)| **hz >= low && **hz < high) + .map(|(band, _)| { + let row = &mel.magnitude[band * mel.frames..(band + 1) * mel.frames]; + (band, rise_levels_min_floor(row, frame, sample_rate).1) + }) + .collect(); + let mut tail: Vec = (start..=end) + .filter(|&later| !mel.onset_mask[later]) + .map(|later| { + bands + .iter() + .map(|&(band, background)| { + (mel.magnitude[band * mel.frames + later] - TRANSIENT_FLOOR_GAIN * background) + .max(0.0) + }) + .sum() + }) + .collect(); + if tail.len() < 4 { + return 0.0; + } + percentile(&mut tail, 0.25) +} + +/// The mel band with the strongest energy above the pre-onset floor, measured +/// `tail_secs` after the onset (0 = at the onset itself). +fn mel_transient_peak_hz( + mel: &MelSpectrogram, + frame: usize, + tail_secs: f64, + sample_rate: u32, + low: f32, + high: f32, +) -> f32 { + let later = (frame + (tail_secs * sample_rate as f64 / HOP as f64).round() as usize) + .min(mel.frames - 1); + let tail_level = |band: usize| { + let row = &mel.magnitude[band * mel.frames..(band + 1) * mel.frames]; + let (_, before) = rise_levels_min_floor(row, frame, sample_rate); + (local_peak(row, later, 2) - TRANSIENT_FLOOR_GAIN * before).max(0.0) + }; + mel.centers_hz + .iter() + .enumerate() + .filter(|(_, hz)| **hz >= low && **hz < high) + .max_by(|(a, _), (b, _)| tail_level(*a).partial_cmp(&tail_level(*b)).unwrap_or(Ordering::Equal)) + .map_or(0.0, |(_, hz)| *hz) +} + +fn own_ratio(own: f32, other: f32) -> f32 { + own / other.max(NMF_EPSILON) +} + +fn cymbal_level(activations: &[f32], frame: usize, frames: usize) -> f32 { + DrumClass::CYMBALS + .iter() + .map(|&component| component_level(activations, component, frame, frames)) + .fold(0.0f32, f32::max) +} + +fn component_level(activations: &[f32], component: usize, frame: usize, frames: usize) -> f32 { + local_peak( + &activations[component * frames..(component + 1) * frames], + frame, + 8, + ) +} + +fn percentile(values: &mut [f32], quantile: f32) -> f32 { + if values.is_empty() { + return 0.0; + } + values.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)); + let index = ((values.len() - 1) as f32 * quantile).round() as usize; + values[index] +} + +/// Track one bass/melody line with a YIN-style difference function. +pub fn transcribe_monophonic( + mono: &[f32], + sample_rate: u32, + clock: &LoopClock, +) -> Vec { + if mono.is_empty() || sample_rate == 0 || !clock.bpm.is_finite() || clock.bpm <= 0.0 { + return Vec::new(); + } + let frame_count = mono.len().div_ceil(HOP).max(1); + let mut energies = vec![0.0f32; frame_count]; + let mut pitches = vec![None; frame_count]; + let mut frame = vec![0.0f32; WINDOW]; + let decimation = (sample_rate / 8_000).max(1) as usize; + let effective_rate = sample_rate as f64 / decimation as f64; + let mut downsampled = Vec::with_capacity(WINDOW.div_ceil(decimation)); + let mut difference = Vec::new(); + let mut cmnd = Vec::new(); + + for index in 0..frame_count { + let center = index * HOP; + copy_centered(mono, center, &mut frame); + let mean = frame.iter().copied().sum::() / WINDOW as f32; + let mut square = 0.0f64; + for value in &mut frame { + *value -= mean; + square += f64::from(*value) * f64::from(*value); + } + energies[index] = (square / WINDOW as f64).sqrt() as f32; + downsampled.clear(); + for samples in frame.chunks(decimation) { + downsampled.push(samples.iter().copied().sum::() / samples.len() as f32); + } + pitches[index] = yin_pitch( + &downsampled, + effective_rate, + &mut difference, + &mut cmnd, + ); + } + + let peak_energy = energies.iter().copied().fold(0.0f32, f32::max); + if peak_energy <= 1e-7 { + return Vec::new(); + } + let silence = peak_energy * 10.0f32.powf(-30.0 / 20.0); + for (pitch, energy) in pitches.iter_mut().zip(&energies) { + if *energy < silence { + *pitch = None; + } + } + let pitches = median_smooth(&pitches); + segment_notes(&pitches, &energies, peak_energy, mono.len(), sample_rate, clock) +} + +fn magnitude_at(spectrum: &[f32], frames: usize, bin: usize, frame: usize) -> f32 { + let at = (bin * frames + frame) * 2; + spectrum[at].hypot(spectrum[at + 1]) +} + +fn median_in_place(values: &mut [f32]) -> f32 { + if values.is_empty() { + return 0.0; + } + let middle = values.len() / 2; + let (_, value, _) = values.select_nth_unstable_by(middle, |a, b| { + a.partial_cmp(b).unwrap_or(Ordering::Equal) + }); + *value +} + +fn copy_centered(source: &[f32], center: usize, target: &mut [f32]) { + target.fill(0.0); + let left = center as isize - target.len() as isize / 2; + for (offset, value) in target.iter_mut().enumerate() { + let source_index = left + offset as isize; + if source_index >= 0 { + if let Some(source) = source.get(source_index as usize) { + *value = *source; + } + } + } +} + +fn yin_pitch( + samples: &[f32], + sample_rate: f64, + difference: &mut Vec, + cmnd: &mut Vec, +) -> Option { + let min_lag = (sample_rate / YIN_MAX_HZ).floor().max(2.0) as usize; + let max_lag = (sample_rate / YIN_MIN_HZ).ceil() as usize; + if samples.len() <= max_lag + 4 || min_lag >= max_lag { + return None; + } + let compared = samples.len() - max_lag; + difference.clear(); + difference.resize(max_lag + 1, 0.0); + cmnd.clear(); + cmnd.resize(max_lag + 1, 1.0); + for lag in 1..=max_lag { + let mut sum = 0.0f64; + for index in 0..compared { + let delta = f64::from(samples[index] - samples[index + lag]); + sum += delta * delta; + } + difference[lag] = sum; + } + let mut cumulative = 0.0; + for lag in 1..=max_lag { + cumulative += difference[lag]; + cmnd[lag] = if cumulative > 1e-15 { + difference[lag] * lag as f64 / cumulative + } else { + 1.0 + }; + } + let mut lag = min_lag; + while lag <= max_lag { + if cmnd[lag] < YIN_APERIODICITY { + while lag < max_lag && cmnd[lag + 1] < cmnd[lag] { + lag += 1; + } + let refined = parabolic_minimum(cmnd, lag); + let pitch = sample_rate / refined; + return (YIN_MIN_HZ..=YIN_MAX_HZ).contains(&pitch).then_some(pitch); + } + lag += 1; + } + None +} + +fn parabolic_minimum(values: &[f64], index: usize) -> f64 { + if index == 0 || index + 1 >= values.len() { + return index as f64; + } + let left = values[index - 1]; + let center = values[index]; + let right = values[index + 1]; + let denominator = left - 2.0 * center + right; + if denominator.abs() < 1e-12 { + index as f64 + } else { + index as f64 + (0.5 * (left - right) / denominator).clamp(-0.5, 0.5) + } +} + +fn median_smooth(pitches: &[Option]) -> Vec> { + let mut smoothed = vec![None; pitches.len()]; + let mut scratch = Vec::with_capacity(5); + for (index, pitch) in pitches.iter().enumerate() { + if pitch.is_none() { + continue; + } + scratch.clear(); + let start = index.saturating_sub(2); + let end = (index + 3).min(pitches.len()); + scratch.extend(pitches[start..end].iter().flatten().copied()); + scratch.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)); + smoothed[index] = scratch.get(scratch.len() / 2).copied(); + } + smoothed +} + +fn segment_notes( + pitches: &[Option], + energies: &[f32], + peak_energy: f32, + sample_count: usize, + sample_rate: u32, + clock: &LoopClock, +) -> Vec { + let mut notes = Vec::new(); + let mut start = None; + for index in 0..=pitches.len() { + let pitch = pitches.get(index).copied().flatten(); + let boundary = match (start, pitch) { + (Some(segment_start), Some(current)) if index > segment_start => { + let energy_rise = energies[index] + > energies[index.saturating_sub(1)].max(1e-9) * 10.0f32.powf(6.0 / 20.0); + let prior = recent_median_pitch(pitches, segment_start, index).unwrap_or(current); + let jump = semitone_distance(prior, current) > 1.0 + && pitch_is_held(pitches, index, current); + energy_rise || jump + } + (Some(_), None) => true, + _ => false, + }; + if boundary { + if let Some(segment_start) = start.take() { + push_note( + &mut notes, + pitches, + energies, + segment_start, + index, + peak_energy, + sample_count, + sample_rate, + clock, + ); + } + } + if pitch.is_some() && start.is_none() { + start = Some(index); + } + } + notes +} + +fn pitch_is_held(pitches: &[Option], start: usize, pitch: f64) -> bool { + (start..start.saturating_add(3)).all(|index| { + pitches + .get(index) + .copied() + .flatten() + .is_some_and(|value| semitone_distance(value, pitch) < 0.75) + }) +} + +fn median_pitch(pitches: &[Option]) -> Option { + let mut values: Vec = pitches.iter().flatten().copied().collect(); + if values.is_empty() { + return None; + } + values.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)); + values.get(values.len() / 2).copied() +} + +fn recent_median_pitch(pitches: &[Option], start: usize, end: usize) -> Option { + let mut values = [0.0f64; 5]; + let mut count = 0; + for pitch in pitches[start.max(end.saturating_sub(values.len()))..end] + .iter() + .flatten() + { + values[count] = *pitch; + count += 1; + } + if count == 0 { + return None; + } + values[..count].sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)); + Some(values[count / 2]) +} + +#[allow(clippy::too_many_arguments)] +fn push_note( + notes: &mut Vec, + pitches: &[Option], + energies: &[f32], + start: usize, + end: usize, + peak_energy: f32, + sample_count: usize, + sample_rate: u32, + clock: &LoopClock, +) { + let Some(pitch) = median_pitch(&pitches[start..end]) else { return }; + let start_sample = (start * HOP).min(sample_count); + let end_sample = (end * HOP).min(sample_count).max((start_sample + HOP).min(sample_count)); + if end_sample <= start_sample { + return; + } + let midi = (69.0 + 12.0 * (pitch / 440.0).log2()).round().clamp(0.0, 127.0) as u8; + let segment_peak = energies[start..end].iter().copied().fold(0.0f32, f32::max); + let beats_per_second = clock.bpm / 60.0; + let total_beats = f64::from(clock.bars) * f64::from(clock.beats_per_bar); + let onset_beats = start_sample as f64 / sample_rate as f64 * beats_per_second; + if onset_beats >= total_beats { + return; + } + notes.push(PitchedNote { + onset_beats, + duration_beats: ((end_sample - start_sample) as f64 / sample_rate as f64 + * beats_per_second) + .min(total_beats - onset_beats), + midi, + velocity: (segment_peak / peak_energy).clamp(0.0, 1.0), + }); +} + +fn semitone_distance(a: f64, b: f64) -> f64 { + (12.0 * (a / b).log2()).abs() +} + +#[cfg(test)] +mod tests { + use super::*; + use makepad_drumkit::{DrumKit, DrumVoice as KitVoice, SampleBank}; + use std::f32::consts::TAU; + use std::sync::{Arc, OnceLock}; + + const RATE: u32 = 44_100; + + fn clock() -> LoopClock { + LoopClock { bpm: 120.0, bars: 1, beats_per_bar: 4 } + } + + fn local_sample_bank() -> Option> { + static BANK: OnceLock, String>> = OnceLock::new(); + let dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")) + .join("../../local/score-corpus/drums/OH"); + if !dir.is_dir() { + eprintln!("skipping drum transcription kit test: {} is absent", dir.display()); + return None; + } + match BANK.get_or_init(|| SampleBank::load(&dir).map(Arc::new)) { + Ok(bank) => Some(bank.clone()), + Err(error) => panic!("load local Salamander corpus: {error}"), + } + } + + fn render_kit(events: &[(f64, KitVoice, f32)], bars: u32) -> Option> { + let sample_count = bars as usize * 4 * RATE as usize / 2; + let mut out = vec![0.0f32; sample_count]; + let mut kit = DrumKit::new(RATE as f32); + kit.set_bank(local_sample_bank()?); + let mut event_index = 0; + for (sample_index, sample) in out.iter_mut().enumerate() { + while let Some(&(beat, voice, velocity)) = events.get(event_index) { + let event_sample = (beat * RATE as f64 * 0.5).round() as usize; + if event_sample > sample_index { + break; + } + kit.trigger(voice, velocity); + event_index += 1; + } + let mut frame = [[0.0f32; 2]]; + kit.process(&mut frame); + *sample = (frame[0][0] + frame[0][1]) * 0.5; + } + Some(out) + } + + fn has_hit(hits: &[DrumHit], voice: DrumVoice, beat: f64) -> bool { + hits.iter().any(|hit| { + hit.voice == voice && (hit.time_beats - beat).abs() <= 1.0 / 32.0 + }) + } + + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + enum HitClass { + Kick, + Snare, + Hat, + Tom, + Cymbal, + } + + impl HitClass { + const ALL: [Self; 5] = [Self::Kick, Self::Snare, Self::Hat, Self::Tom, Self::Cymbal]; + + fn index(self) -> usize { + match self { + Self::Kick => 0, + Self::Snare => 1, + Self::Hat => 2, + Self::Tom => 3, + Self::Cymbal => 4, + } + } + } + + #[derive(Clone, Copy, Default)] + struct Counts { + true_positive: usize, + false_positive: usize, + false_negative: usize, + } + + impl Counts { + fn f_measure(self) -> f32 { + let denominator = 2 * self.true_positive + self.false_positive + self.false_negative; + if denominator == 0 { + 1.0 + } else { + 2.0 * self.true_positive as f32 / denominator as f32 + } + } + + fn add(&mut self, other: Self) { + self.true_positive += other.true_positive; + self.false_positive += other.false_positive; + self.false_negative += other.false_negative; + } + } + + fn kit_class(voice: KitVoice) -> HitClass { + match voice { + KitVoice::Kick => HitClass::Kick, + KitVoice::Snare | KitVoice::SideStick | KitVoice::Clap => HitClass::Snare, + KitVoice::HiHatClosed | KitVoice::HiHatOpen | KitVoice::HiHatPedal => HitClass::Hat, + KitVoice::TomHigh | KitVoice::TomMid | KitVoice::TomLow | KitVoice::TomFloor => { + HitClass::Tom + } + KitVoice::Ride | KitVoice::RideBell | KitVoice::Crash => HitClass::Cymbal, + // The kit's clap has no score voice of its own; it sits where + // a snare sits in the harness. + KitVoice::Clap => HitClass::Snare, + } + } + + fn score_class(voice: DrumVoice) -> HitClass { + match voice { + DrumVoice::Kick => HitClass::Kick, + DrumVoice::Snare | DrumVoice::SideStick => HitClass::Snare, + DrumVoice::HiHatClosed | DrumVoice::HiHatOpen | DrumVoice::HiHatPedal => HitClass::Hat, + DrumVoice::TomHigh | DrumVoice::TomMid | DrumVoice::TomLow | DrumVoice::TomFloor => { + HitClass::Tom + } + DrumVoice::Ride | DrumVoice::RideBell | DrumVoice::Crash => HitClass::Cymbal, + } + } + + fn onset_counts( + truth: &[(f64, KitVoice, f32)], + detected: &[DrumHit], + class: HitClass, + ) -> Counts { + let truth: Vec = truth + .iter() + .filter(|event| kit_class(event.1) == class) + .map(|event| event.0) + .collect(); + let detected: Vec = detected + .iter() + .filter(|hit| score_class(hit.voice) == class) + .map(|hit| hit.time_beats) + .collect(); + let mut used = vec![false; detected.len()]; + let mut true_positive = 0; + for expected in &truth { + let nearest = detected + .iter() + .enumerate() + .filter(|(index, at)| !used[*index] && (*at - expected).abs() <= 0.05) + .min_by(|(_, a), (_, b)| { + (*a - expected) + .abs() + .partial_cmp(&(*b - expected).abs()) + .unwrap_or(Ordering::Equal) + }) + .map(|(index, _)| index); + if let Some(index) = nearest { + used[index] = true; + true_positive += 1; + } + } + Counts { + true_positive, + false_positive: detected.len() - true_positive, + false_negative: truth.len() - true_positive, + } + } + + fn synthetic_patterns() -> Vec> { + let mut patterns = Vec::new(); + + let mut rock = Vec::new(); + for step in 1..16 { + rock.push((step as f64 * 0.5, KitVoice::HiHatClosed, 0.48 + 0.16 * (step % 2) as f32)); + } + for beat in [0.5, 2.5, 4.5, 6.5] { + rock.push((beat, KitVoice::Kick, 0.78)); + } + for beat in [1.5, 3.5, 5.5, 7.5] { + rock.push((beat, KitVoice::Snare, 0.84)); + } + rock.push((0.5, KitVoice::Crash, 0.88)); + rock.push((2.25, KitVoice::Ride, 0.62)); + rock.push((6.25, KitVoice::Ride, 0.68)); + patterns.push(rock); + + let mut disco = Vec::new(); + for step in 1..16 { + let beat = 0.25 + step as f64 * 0.5; + disco.push(( + beat, + if step == 7 || step == 15 { + KitVoice::HiHatOpen + } else { + KitVoice::HiHatClosed + }, + if step % 2 == 0 { 0.50 } else { 0.72 }, + )); + } + for beat in [0.75, 1.75, 2.75, 3.75, 4.75, 5.75, 6.75, 7.75] { + disco.push((beat, KitVoice::Kick, 0.82)); + } + for beat in [1.75, 3.75, 5.75, 7.75] { + disco.push((beat, KitVoice::Snare, 0.79)); + } + patterns.push(disco); + + let mut hip_hop = Vec::new(); + for beat in [0.5, 1.25, 2.75, 4.5, 5.0, 6.75] { + hip_hop.push((beat, KitVoice::Kick, 0.52 + 0.05 * beat as f32)); + } + for beat in [1.5, 3.5, 5.5, 7.5] { + hip_hop.push((beat, KitVoice::Snare, 0.72)); + } + for step in 2..32 { + hip_hop.push((step as f64 * 0.25, KitVoice::HiHatClosed, 0.32 + 0.08 * (step % 4) as f32)); + } + patterns.push(hip_hop); + + let mut breakbeat = Vec::new(); + for beat in [0.5, 1.25, 2.5, 3.25, 4.5, 5.75, 6.5] { + breakbeat.push((beat, KitVoice::Kick, 0.74)); + } + for (beat, velocity) in [ + (1.5, 0.86), + (2.25, 0.27), + (3.5, 0.82), + (4.25, 0.24), + (5.5, 0.88), + (6.25, 0.30), + (7.5, 0.84), + ] { + breakbeat.push((beat, KitVoice::Snare, velocity)); + } + for beat in [0.75, 1.75, 2.75, 3.75, 4.75, 5.75, 6.75, 7.75] { + breakbeat.push((beat, KitVoice::HiHatClosed, 0.56)); + } + patterns.push(breakbeat); + + let mut tom_fill = vec![ + (0.5, KitVoice::Kick, 0.82), + (1.5, KitVoice::Snare, 0.78), + (2.5, KitVoice::Kick, 0.74), + (3.5, KitVoice::Snare, 0.84), + (4.0, KitVoice::TomHigh, 0.55), + (4.5, KitVoice::TomHigh, 0.70), + (5.0, KitVoice::TomMid, 0.62), + (5.5, KitVoice::TomMid, 0.78), + (6.0, KitVoice::TomLow, 0.68), + (6.5, KitVoice::TomLow, 0.82), + (7.0, KitVoice::TomFloor, 0.76), + (7.5, KitVoice::TomFloor, 0.92), + (7.5, KitVoice::Crash, 0.88), + ]; + for step in 1..8 { + tom_fill.push((step as f64 * 0.5, KitVoice::HiHatClosed, 0.52)); + } + patterns.push(tom_fill); + + let mut hats = Vec::new(); + for step in 2..32 { + hats.push(( + step as f64 * 0.25, + if step == 8 || step == 20 || step == 28 { + KitVoice::HiHatOpen + } else { + KitVoice::HiHatClosed + }, + 0.38 + 0.12 * (step % 4) as f32, + )); + } + patterns.push(hats); + + for pattern in &mut patterns { + pattern.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal)); + } + patterns + } + + fn add_bleed_and_smear(clean: &[f32]) -> Vec { + let peak = clean.iter().copied().map(f32::abs).fold(0.0f32, f32::max); + let bass_level = peak * 10.0f32.powf(-18.0 / 20.0); + let delay = (RATE as f32 * 0.030).round() as usize; + let mut degraded = clean.to_vec(); + for index in 0..degraded.len() { + let fade = (index as f32 / (RATE as f32 * 0.020)).min(1.0); + degraded[index] += + (TAU * 55.0 * index as f32 / RATE as f32).sin() * bass_level * fade; + if index >= delay { + degraded[index] += clean[index - delay] * 0.28; + } + } + degraded + } + + #[test] + fn synthetic_drum_hits_land_on_their_beats() { + let Some(samples) = render_kit( + &[ + (0.5, KitVoice::Kick, 0.85), + (1.5, KitVoice::Snare, 0.8), + (2.5, KitVoice::HiHatClosed, 0.7), + (3.25, KitVoice::Kick, 0.6), + (3.5, KitVoice::Snare, 0.9), + ], + 1, + ) else { return }; + let hits = transcribe_drums(&samples, RATE, &clock()); + for beat in [0.5, 1.5, 2.5, 3.25, 3.5] { + assert!( + hits.iter().any(|hit| (hit.time_beats - beat).abs() <= 1.0 / 32.0), + "missing sample-kit onset at beat {beat}: {hits:?}" + ); + } + } + + #[test] + fn drum_transcribe_single_kit_hits_have_the_right_class() { + let mut failures = Vec::new(); + for kit_voice in [ + KitVoice::Kick, + KitVoice::Snare, + KitVoice::HiHatClosed, + KitVoice::HiHatOpen, + KitVoice::TomHigh, + KitVoice::TomMid, + KitVoice::TomLow, + KitVoice::TomFloor, + KitVoice::Ride, + KitVoice::Crash, + ] { + let Some(samples) = render_kit(&[(1.0, kit_voice, 0.8)], 1) else { return }; + let hits = transcribe_drums(&samples, RATE, &clock()); + if !hits.iter().any(|hit| (hit.time_beats - 1.0).abs() <= 1.0 / 32.0) { + failures.push(format!("missing onset for {kit_voice:?}: {hits:?}")); + } + } + assert!(failures.is_empty(), "{}", failures.join("\n")); + } + + #[test] + fn drum_transcribe_keeps_kick_hat_co_onset_and_rejects_snare_hat_bleed() { + let Some(co_onset) = render_kit( + &[(1.0, KitVoice::Kick, 0.9), (1.0, KitVoice::HiHatClosed, 0.7)], + 1, + ) else { return }; + let hits = transcribe_drums(&co_onset, RATE, &clock()); + assert!(has_hit(&hits, DrumVoice::Kick, 1.0), "missing kick: {hits:?}"); + assert!( + hits.iter().filter(|hit| (hit.time_beats - 1.0).abs() <= 1.0 / 32.0).count() >= 2, + "co-onset collapsed to one event: {hits:?}" + ); + + let Some(snare) = render_kit(&[(1.0, KitVoice::Snare, 0.9)], 1) else { return }; + let hits = transcribe_drums(&snare, RATE, &clock()); + assert!(has_hit(&hits, DrumVoice::Snare, 1.0), "missing snare: {hits:?}"); + assert!( + !hits.iter().any(|hit| matches!( + hit.voice, + DrumVoice::HiHatClosed | DrumVoice::HiHatOpen | DrumVoice::HiHatPedal + )), + "snare produced a false hat: {hits:?}" + ); + } + + #[test] + fn drum_transcribe_is_deterministic() { + let Some(samples) = render_kit( + &[ + (0.5, KitVoice::Kick, 0.75), + (1.0, KitVoice::Snare, 0.55), + (1.5, KitVoice::HiHatOpen, 0.9), + ], + 1, + ) else { return }; + let first = transcribe_drums(&samples, RATE, &clock()); + let second = transcribe_drums(&samples, RATE, &clock()); + assert_eq!(first.len(), second.len()); + for (a, b) in first.iter().zip(&second) { + assert_eq!(a.time_beats.to_bits(), b.time_beats.to_bits()); + assert_eq!(a.voice, b.voice); + assert_eq!(a.velocity.to_bits(), b.velocity.to_bits()); + } + } + + #[test] + fn drum_transcribe_synthetic_acceptance() { + let mut clean = [Counts::default(); 5]; + let mut degraded = [Counts::default(); 5]; + let mut snare_without_hat = 0usize; + let mut false_hats_on_snare = 0usize; + let mut truth_events = 0usize; + let mut clean_timed = 0usize; + let mut degraded_timed = 0usize; + let clock = LoopClock { + bpm: 120.0, + bars: 2, + beats_per_bar: 4, + }; + for (pattern_index, truth) in synthetic_patterns().into_iter().enumerate() { + let Some(samples) = render_kit(&truth, 2) else { return }; + let clean_hits = transcribe_drums(&samples, RATE, &clock); + let degraded_hits = transcribe_drums(&add_bleed_and_smear(&samples), RATE, &clock); + eprintln!( + "pattern {pattern_index} truth={} clean={:?} degraded={:?}", + truth.len(), + clean_hits + .iter() + .map(|hit| (hit.time_beats, score_class(hit.voice))) + .collect::>(), + degraded_hits + .iter() + .map(|hit| (hit.time_beats, score_class(hit.voice))) + .collect::>() + ); + for class in HitClass::ALL { + clean[class.index()].add(onset_counts(&truth, &clean_hits, class)); + degraded[class.index()].add(onset_counts(&truth, °raded_hits, class)); + } + for &(beat, voice, _) in &truth { + truth_events += 1; + clean_timed += usize::from( + clean_hits.iter().any(|hit| (hit.time_beats - beat).abs() <= 0.05), + ); + degraded_timed += usize::from( + degraded_hits.iter().any(|hit| (hit.time_beats - beat).abs() <= 0.05), + ); + if kit_class(voice) != HitClass::Snare + || truth.iter().any(|event| { + kit_class(event.1) == HitClass::Hat && (event.0 - beat).abs() <= 0.05 + }) + { + continue; + } + snare_without_hat += 1; + if clean_hits.iter().any(|hit| { + score_class(hit.voice) == HitClass::Hat + && (hit.time_beats - beat).abs() <= 0.05 + }) { + false_hats_on_snare += 1; + } + } + } + let clean_f: [f32; 5] = std::array::from_fn(|index| clean[index].f_measure()); + let degraded_f: [f32; 5] = std::array::from_fn(|index| degraded[index].f_measure()); + let clean_timing_recall = clean_timed as f32 / truth_events as f32; + let degraded_timing_recall = degraded_timed as f32 / truth_events as f32; + eprintln!( + "drum synthetic F clean={clean_f:?} bleed+smear={degraded_f:?}; onset recall={clean_timing_recall:.3}/{degraded_timing_recall:.3}; false hats={false_hats_on_snare}/{snare_without_hat}" + ); + assert!(clean_timing_recall >= 0.70, "clean onset recall {clean_timing_recall:.3}"); + assert!( + degraded_timing_recall >= 0.50, + "bleed+smear onset recall {degraded_timing_recall:.3}" + ); + assert!( + false_hats_on_snare * 20 <= snare_without_hat, + "false hats on snare: {false_hats_on_snare}/{snare_without_hat}" + ); + } + + #[test] + fn synthetic_bass_line_has_four_midi_notes() { + let midi = [28u8, 33, 38, 43]; + let note_samples = RATE as usize / 2; + let gap = RATE as usize / 100; + let mut samples = vec![0.0; note_samples * midi.len()]; + for (note, midi) in midi.into_iter().enumerate() { + let hz = 440.0 * 2.0f32.powf((midi as f32 - 69.0) / 12.0); + let start = note * note_samples; + let end = (start + note_samples - gap).min(samples.len()); + for (offset, sample) in samples[start..end].iter_mut().enumerate() { + let edge = (offset.min(end - start - 1 - offset) as f32 / 128.0).min(1.0); + *sample = (TAU * hz * offset as f32 / RATE as f32).sin() * 0.7 * edge; + } + } + let notes = transcribe_monophonic(&samples, RATE, &clock()); + assert_eq!(notes.iter().map(|note| note.midi).collect::>(), midi); + } + + #[test] + fn silence_is_empty() { + assert!(transcribe_drums(&vec![0.0; WINDOW * 2], RATE, &clock()).is_empty()); + assert!(transcribe_monophonic(&vec![0.0; WINDOW * 2], RATE, &clock()).is_empty()); + } + + #[test] + fn one_frame_inputs_do_not_panic() { + assert!(transcribe_drums(&[0.0], RATE, &clock()).is_empty()); + assert!(transcribe_monophonic(&[0.0], RATE, &clock()).is_empty()); + } + + fn read_wav_pcm16_mono(path: &std::path::Path) -> Option<(Vec, u32)> { + let bytes = std::fs::read(path).ok()?; + if bytes.len() < 12 || &bytes[0..4] != b"RIFF" || &bytes[8..12] != b"WAVE" { + return None; + } + let u16_at = |at: usize| u16::from_le_bytes([bytes[at], bytes[at + 1]]); + let u32_at = |at: usize| u32::from_le_bytes(bytes[at..at + 4].try_into().unwrap()); + let mut channels = 0usize; + let mut rate = 0u32; + let mut bits = 0u16; + let mut cursor = 12; + while cursor + 8 <= bytes.len() { + let id = &bytes[cursor..cursor + 4]; + let size = u32_at(cursor + 4) as usize; + let body = cursor + 8; + if id == b"fmt " && body + 16 <= bytes.len() { + channels = u16_at(body + 2) as usize; + rate = u32_at(body + 4); + bits = u16_at(body + 14); + } else if id == b"data" { + if bits != 16 || channels == 0 || rate == 0 { + return None; + } + let end = (body + size).min(bytes.len()); + let frame_bytes = 2 * channels; + let frames = (end - body) / frame_bytes; + let mut mono = Vec::with_capacity(frames); + for frame in 0..frames { + let at = body + frame * frame_bytes; + let sum: f32 = (0..channels) + .map(|channel| i16::from_le_bytes([bytes[at + 2 * channel], bytes[at + 2 * channel + 1]]) as f32 / 32768.0) + .sum(); + mono.push(sum / channels as f32); + } + return Some((mono, rate)); + } + cursor = body + size + (size & 1); + } + None + } + + fn write_wav_mono16(path: &std::path::Path, samples: &[f32], rate: u32) -> std::io::Result<()> { + let data_len = samples.len() * 2; + let mut out = Vec::with_capacity(44 + data_len); + out.extend_from_slice(b"RIFF"); + out.extend_from_slice(&(36 + data_len as u32).to_le_bytes()); + out.extend_from_slice(b"WAVEfmt "); + out.extend_from_slice(&16u32.to_le_bytes()); + out.extend_from_slice(&1u16.to_le_bytes()); + out.extend_from_slice(&1u16.to_le_bytes()); + out.extend_from_slice(&rate.to_le_bytes()); + out.extend_from_slice(&(rate * 2).to_le_bytes()); + out.extend_from_slice(&2u16.to_le_bytes()); + out.extend_from_slice(&16u16.to_le_bytes()); + out.extend_from_slice(b"data"); + out.extend_from_slice(&(data_len as u32).to_le_bytes()); + for sample in samples { + out.extend_from_slice(&((sample.clamp(-1.0, 1.0) * 32767.0).round() as i16).to_le_bytes()); + } + std::fs::write(path, out) + } + + /// Render a transcription through the kit at the clock's tempo. + fn render_hits(hits: &[DrumHit], clock: &LoopClock, rate: u32, length: usize) -> Option> { + let mut events: Vec<(f64, KitVoice, f32)> = hits + .iter() + .filter_map(|hit| { + KitVoice::try_from(hit.voice.gm_note()) + .ok() + .map(|voice| (hit.time_beats * 60.0 / clock.bpm, voice, hit.velocity)) + }) + .collect(); + events.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal)); + let mut out = vec![0.0f32; length]; + let mut kit = DrumKit::new(rate as f32); + kit.set_bank(local_sample_bank()?); + let mut next = 0; + for (index, sample) in out.iter_mut().enumerate() { + while let Some(&(secs, voice, velocity)) = events.get(next) { + if (secs * rate as f64).round() as usize > index { + break; + } + kit.trigger(voice, velocity); + next += 1; + } + let mut frame = [[0.0f32; 2]]; + kit.process(&mut frame); + *sample = (frame[0][0] + frame[0][1]) * 0.5; + } + Some(out) + } + + /// Second-order Butterworth low-pass (RBJ cookbook), run twice for a 4th-order slope. + fn low_pass(samples: &[f32], rate: u32, cutoff_hz: f32) -> Vec { + let w0 = TAU * cutoff_hz / rate as f32; + let alpha = w0.sin() / (2.0 * std::f32::consts::FRAC_1_SQRT_2); + let cos = w0.cos(); + let a0 = 1.0 + alpha; + let b0 = (1.0 - cos) / 2.0 / a0; + let b1 = (1.0 - cos) / a0; + let b2 = b0; + let a1 = -2.0 * cos / a0; + let a2 = (1.0 - alpha) / a0; + let mut out = samples.to_vec(); + for _ in 0..2 { + let (mut x1, mut x2, mut y1, mut y2) = (0.0f32, 0.0f32, 0.0f32, 0.0f32); + for value in &mut out { + let x0 = *value; + let y0 = b0 * x0 + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2; + x2 = x1; + x1 = x0; + y2 = y1; + y1 = y0; + *value = y0; + } + } + out + } + + /// 10 ms RMS envelopes of the <200 Hz, 200 Hz-3 kHz and >5 kHz bands. + fn band_envelopes(samples: &[f32], rate: u32) -> [Vec; 3] { + let low = low_pass(samples, rate, 200.0); + let below_3k = low_pass(samples, rate, 3_000.0); + let below_5k = low_pass(samples, rate, 5_000.0); + let mid: Vec = below_3k.iter().zip(&low).map(|(a, b)| a - b).collect(); + let high: Vec = samples.iter().zip(&below_5k).map(|(a, b)| a - b).collect(); + let block = (rate as usize) / 100; + let envelope = |band: &[f32]| -> Vec { + band.chunks(block) + .map(|chunk| (chunk.iter().map(|v| v * v).sum::() / chunk.len() as f32).sqrt()) + .collect() + }; + [envelope(&low), envelope(&mid), envelope(&high)] + } + + fn pearson(a: &[f32], b: &[f32]) -> f64 { + let n = a.len().min(b.len()); + if n < 2 { + return 0.0; + } + let mean = |values: &[f32]| values[..n].iter().map(|v| f64::from(*v)).sum::() / n as f64; + let (mean_a, mean_b) = (mean(a), mean(b)); + let (mut cov, mut var_a, mut var_b) = (0.0f64, 0.0f64, 0.0f64); + for index in 0..n { + let da = f64::from(a[index]) - mean_a; + let db = f64::from(b[index]) - mean_b; + cov += da * db; + var_a += da * da; + var_b += db * db; + } + cov / (var_a * var_b).sqrt().max(1e-12) + } + + fn sounds_like(original: &[Vec; 3], rendered: &[f32], rate: u32) -> [f64; 3] { + let envelopes = band_envelopes(rendered, rate); + std::array::from_fn(|band| pearson(&original[band], &envelopes[band])) + } + + + /// Real separated drums stem (gitignored): transcribe, render through the kit and + /// report how much the render's 10 ms band envelopes follow the original's + /// (Pearson per band: <200 Hz, 200 Hz-3 kHz, >5 kHz). Writes + /// `target/drum_ab/{original,after}.wav` for listening. The band grid is only + /// a beats<->seconds mapping here, so a nominal 120 bpm clock covers the file. + #[test] + #[ignore] + fn drum_ab_real_stem_sounds_like() { + let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../.."); + let stem = root.join("local/stems_demo/seg_drums.wav"); + let Some((mono, rate)) = read_wav_pcm16_mono(&stem) else { + eprintln!("no real stem at {}; skipping", stem.display()); + return; + }; + let seconds = mono.len() as f64 / rate as f64; + let clock = LoopClock { bpm: 120.0, bars: (seconds / 2.0).ceil() as u32, beats_per_bar: 4 }; + let original = band_envelopes(&mono, rate); + let out_dir = root.join("target/drum_ab"); + std::fs::create_dir_all(&out_dir).unwrap(); + let started = std::time::Instant::now(); + let hits = transcribe_drums(&mono, rate, &clock); + let elapsed = started.elapsed(); + let Some(rendered) = render_hits(&hits, &clock, rate, mono.len()) else { return }; + let bands = sounds_like(&original, &rendered, rate); + let paths = [("original", &mono), ("after", &rendered)]; + for (label, samples) in paths { + let path = out_dir.join(format!("{label}.wav")); + write_wav_mono16(&path, samples, rate).unwrap(); + eprintln!("wrote {}", path.canonicalize().unwrap().display()); + } + eprintln!( + "sounds-like: low={:.3} mid={:.3} high={:.3} mean={:.3} ({} hits)", + bands[0], + bands[1], + bands[2], + (bands[0] + bands[1] + bands[2]) / 3.0, + hits.len() + ); + eprintln!("transcribe_drums on {seconds:.1} s of stem: {elapsed:?}"); + } + + /// Four bars at 120 bpm through the kit, timed (run in release: < 200 ms on one core). + #[test] + #[ignore] + fn drum_transcribe_four_bars_timing() { + let mut pattern = Vec::new(); + for bar in 0..4 { + for event in &synthetic_patterns()[bar % 2] { + pattern.push((event.0 + bar as f64 * 4.0, event.1, event.2)); + } + } + pattern.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal)); + let Some(samples) = render_kit(&pattern, 4) else { return }; + let clock = LoopClock { bpm: 120.0, bars: 4, beats_per_bar: 4 }; + let started = std::time::Instant::now(); + let hits = transcribe_drums(&samples, RATE, &clock); + let elapsed = started.elapsed(); + eprintln!("transcribe_drums 4 bars @120: {elapsed:?} ({} hits)", hits.len()); + assert!(!hits.is_empty()); + } + +} diff --git a/apps/vj/src/main.rs b/apps/vj/src/main.rs index 593f95253..6220b0dce 100644 --- a/apps/vj/src/main.rs +++ b/apps/vj/src/main.rs @@ -72,7 +72,12 @@ mod lanes; // a coding agent polls after saving one. See apps/vj/LIVECODING.md. mod livecode; mod loop_detect; +mod loop_blocks; mod loop_scan; +mod loop_splat; +mod loop_splat_model; +mod loop_transcribe; +mod loop_splat_view; // Karaoke: whisper over the separated vocals stem, cached beside the stems. mod lyrics; // Word-level karaoke timing: cross-attention DTW + teacher forcing + onset @@ -86,10 +91,12 @@ mod midi_learn; mod mix; mod mixer; mod models; +mod notes_map; // Two-deck music mode: deck DSP, off-thread track analysis, deck surface. mod music_dsp; mod music_import_ui; mod music_view; +mod score_preview; mod stems; mod wave_analysis; mod pads; @@ -103,8 +110,8 @@ mod side_channels; mod views; use crate::apc40::{ - palette_velocity, thumb_color, Apc40State, ApcAction, ApcSurface, LedDiff, LedFrame, PadLed, - PAD_COUNT, + palette_velocity, splat_led_frame, thumb_color, Apc40State, ApcAction, ApcSurface, LedDiff, + LedFrame, PadLed, PAD_COUNT, }; use crate::beat_sync::{ BeatClock, BeatFit, BeatLockState, BeatSnapshot, BeatSyncAnalyzer, @@ -115,6 +122,12 @@ use crate::cue::{CueCmd, CueEngine, CueGen, CueItem, CueScheduleId, SlotId}; use crate::loop_detect::{ analyze_video_loop, FrameSignature, LoopDetection, LoopKind, MotionSummary, }; +use crate::loop_splat::{build_splat, SplatPart, StemLevels}; +use crate::loop_splat_model::{splat_deck, splat_row, splat_view_model, SplatCoverage}; +use crate::loop_splat_view::{ + LoopSplatAction, SplatCellView, SplatRowView, SplatViewModel, VjLoopSplatWidgetRefExt, + SPLAT_ROWS, +}; use crate::autopilot::{AutoCmd, AutoDeckObs, AutoLoad, AutoObs, AutoPilot, AutoStyle}; use crate::blend::MixBrain; use crate::decks::{ @@ -153,7 +166,7 @@ use crate::lanes::{LatestWins, AUDIO_LANE}; use crate::media::{DecodeDone, DecodeJob, DecodePool, SlotPlayer}; use crate::mixer::{ TrackStems, - CueMode, CueReadState, Mixer, TrackPcm, VideoTransitionError, VideoTransitionId, + CueMode, CueReadState, MixCmd, Mixer, TrackPcm, VideoTransitionError, VideoTransitionId, VideoTransitionPhase, }; use crate::pads::{PadCmd, PadEngine, PadItem}; @@ -2844,6 +2857,409 @@ impl SungWorker { } } +struct SplatRefineDone { + deck: DeckId, + gen: u64, + grid: Option>, +} + +struct SplatRefineWorker { + tx: std::sync::mpsc::Sender, + rx: std::sync::mpsc::Receiver, +} + +impl SplatRefineWorker { + fn new() -> Self { + let (tx, rx) = std::sync::mpsc::channel(); + Self { tx, rx } + } + + fn submit( + &self, + deck: DeckId, + gen: u64, + stems: Arc, + pcm: Arc, + analysis: Arc, + ) -> bool { + let tx = self.tx.clone(); + std::thread::Builder::new() + .name("loop-splat-refine".to_string()) + .spawn(move || { + let levels = Arc::new(splat_stem_levels(&stems, &pcm, &analysis)); + let grid = build_splat(&analysis, Some(&levels)).map(Arc::new); + let _ = tx.send(SplatRefineDone { deck, gen, grid }); + }) + .is_ok() + } + + fn poll(&self) -> Vec { + self.rx.try_iter().collect() + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +struct LoopScoreKey { + deck: DeckId, + row: SplatRowView, + col: u8, + load_gen: u64, + start_frame: usize, + end_frame: usize, + sample_rate: u32, + bars: u8, + bpm_bits: u64, + basic_pitch: bool, +} + +impl std::hash::Hash for LoopScoreKey { + fn hash(&self, state: &mut H) { + self.deck.index().hash(state); + self.row.hash(state); + self.col.hash(state); + self.load_gen.hash(state); + self.start_frame.hash(state); + self.end_frame.hash(state); + self.sample_rate.hash(state); + self.bars.hash(state); + self.bpm_bits.hash(state); + self.basic_pitch.hash(state); + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +enum LoopScoreSignature { + Empty, + Selected { key: LoopScoreKey, source_ready: bool, lyrics_ready: bool }, +} + +#[derive(Clone, Debug)] +enum LoopScoreTranscription { + Drums(Vec), + Pitched { + notes: Vec, + engine: LoopScorePitchEngine, + }, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +enum LoopScorePitchEngine { + BasicPitch, + PitchTracker, +} + +impl LoopScoreTranscription { + fn blocks(&self, bars: u8) -> crate::loop_blocks::CellBlocks { + match self { + Self::Drums(hits) => crate::loop_blocks::drum_blocks(hits, bars), + Self::Pitched { notes, .. } => crate::loop_blocks::pitched_blocks(notes, bars), + } + } + + fn pitch_engine(&self) -> Option { + match self { + Self::Drums(_) => None, + Self::Pitched { engine, .. } => Some(*engine), + } + } +} + +struct LoopScoreDone { + key: LoopScoreKey, + transcription: Arc, + blocks: Arc, +} + +struct LoopScoreJob { + key: LoopScoreKey, + pcm: Arc, + stems: Option<(Arc, usize)>, + clock: crate::loop_transcribe::LoopClock, + lyrics: Vec, + notes_model: Option, +} + +fn loop_score_lyric_words( + lyrics: Option<&TrackLyrics>, + start_secs: f64, + end_secs: f64, + bpm: f64, +) -> Vec { + let Some(lyrics) = lyrics else { return Vec::new() }; + if !start_secs.is_finite() + || !end_secs.is_finite() + || end_secs < start_secs + || !bpm.is_finite() + || bpm <= 0.0 + { + return Vec::new(); + } + let beats_per_second = bpm / 60.0; + let mut output = Vec::new(); + for line in &lyrics.lines { + for (index, text) in line.text.split_whitespace().enumerate() { + let Some(&onset) = line.words.get(index) else { break }; + if !onset.is_finite() || onset < start_secs || onset > end_secs { + continue; + } + let end = line + .words + .get(index + 1) + .copied() + .filter(|end| end.is_finite()) + .unwrap_or(line.end_secs) + .max(onset) + .min(end_secs); + output.push(makepad_score_view::build::LyricWord { + onset_beats: (onset - start_secs) * beats_per_second, + end_beats: (end - start_secs) * beats_per_second, + text: text.to_string(), + }); + } + } + output.sort_by(|left, right| left.onset_beats.total_cmp(&right.onset_beats)); + output +} + +#[cfg(test)] +mod loop_score_lyric_tests { + use super::*; + + #[test] + fn loop_score_words_are_clipped_and_converted_to_beats() { + let lyrics = TrackLyrics { + backend: "test".into(), + model: "test".into(), + language: "en".into(), + duration_secs: 20.0, + onset: Default::default(), + lines: vec![crate::lyrics::LyricLine { + start_secs: 9.8, + end_secs: 12.5, + text: "before sing it after".into(), + words: vec![9.8, 10.25, 10.75, 12.1], + confident: true, + }], + }; + let words = loop_score_lyric_words(Some(&lyrics), 10.0, 12.0, 120.0); + assert_eq!(words.len(), 2); + assert_eq!(words[0].text, "sing"); + assert!((words[0].onset_beats - 0.5).abs() < 1e-9); + assert!((words[0].end_beats - 1.5).abs() < 1e-9); + assert_eq!(words[1].text, "it"); + assert!((words[1].onset_beats - 1.5).abs() < 1e-9); + assert!((words[1].end_beats - 4.0).abs() < 1e-9); + } +} + +struct LoopScoreWorker { + tx: std::sync::mpsc::Sender, + rx: std::sync::mpsc::Receiver, + pending: VecDeque, + active: Vec, + next_thread: u64, + notes_model: Arc< + std::sync::Mutex>, + >, +} + +impl LoopScoreWorker { + const MAX_ACTIVE: usize = 2; + + fn new() -> Self { + let (tx, rx) = std::sync::mpsc::channel(); + Self { + tx, + rx, + pending: VecDeque::new(), + active: Vec::new(), + next_thread: 0, + notes_model: Arc::new(std::sync::Mutex::new(None)), + } + } + + fn submit(&mut self, job: LoopScoreJob) -> bool { + if self.active.contains(&job.key) || self.pending.iter().any(|pending| pending.key == job.key) { + return true; + } + self.pending.push_back(job); + self.fill(); + true + } + + fn fill(&mut self) { + while self.active.len() < Self::MAX_ACTIVE { + let Some(job) = self.pending.pop_front() else { break }; + let key = job.key; + let tx = self.tx.clone(); + let notes_model = self.notes_model.clone(); + let thread = self.next_thread; + self.next_thread = self.next_thread.wrapping_add(1); + let spawned = std::thread::Builder::new() + .name(format!("loop-score-{thread}")) + .spawn(move || { + let mono = copy_loop_mono( + &job.pcm, + job.stems.as_ref().map(|(stems, stem)| (stems.as_ref(), *stem)), + key.start_frame, + key.end_frame, + ); + let transcription = Arc::new(match key.row { + SplatRowView::Drums | SplatRowView::Mix => LoopScoreTranscription::Drums( + crate::loop_transcribe::transcribe_drums(&mono, key.sample_rate, &job.clock), + ), + SplatRowView::Bass | SplatRowView::Vocals | SplatRowView::Other => { + let basic_pitch = job.notes_model.as_ref().map(|path| { + let mono_22k = crate::notes_map::resample_to_basic_pitch( + &mono, + key.sample_rate, + ); + let mut cached = notes_model + .lock() + .map_err(|_| "Basic Pitch model lock poisoned".to_string())?; + if cached.as_ref().is_none_or(|(loaded_path, _)| loaded_path != path) { + *cached = Some(( + path.clone(), + makepad_ai_notes::NotesModel::load(path)?, + )); + } + let transcription = cached + .as_mut() + .expect("Basic Pitch cache loaded") + .1 + .transcribe(&mono_22k)?; + let lane = match key.row { + SplatRowView::Bass => crate::notes_map::PitchLane::Bass, + SplatRowView::Vocals => crate::notes_map::PitchLane::Melody, + SplatRowView::Other => crate::notes_map::PitchLane::Other, + _ => unreachable!(), + }; + Ok::<_, String>(crate::notes_map::map_notes( + &transcription.notes, + job.clock.bpm, + lane, + )) + }); + match basic_pitch.transpose() { + Ok(Some(notes)) => LoopScoreTranscription::Pitched { + notes, + engine: LoopScorePitchEngine::BasicPitch, + }, + Ok(None) => LoopScoreTranscription::Pitched { + notes: crate::loop_transcribe::transcribe_monophonic( + &mono, + key.sample_rate, + &job.clock, + ), + engine: LoopScorePitchEngine::PitchTracker, + }, + Err(error) => { + log!("Basic Pitch loop transcription failed: {error}"); + LoopScoreTranscription::Pitched { + notes: crate::loop_transcribe::transcribe_monophonic( + &mono, + key.sample_rate, + &job.clock, + ), + engine: LoopScorePitchEngine::PitchTracker, + } + } + } + } + }); + let blocks = Arc::new(transcription.blocks(key.bars)); + let _ = tx.send(LoopScoreDone { key, transcription, blocks }); + }); + if spawned.is_ok() { + self.active.push(key); + } + } + } + + fn poll(&mut self) -> Vec { + let completed: Vec<_> = self.rx.try_iter().collect(); + for done in &completed { + self.active.retain(|key| *key != done.key); + } + self.fill(); + completed + } + + fn discard_stale(&mut self, load_gens: [u64; 2]) { + self.pending.retain(|job| load_gens[job.key.deck.index()] == job.key.load_gen); + } +} + +fn splat_stem_levels( + stems: &TrackStems, + pcm: &TrackPcm, + analysis: &TrackAnalysis, +) -> StemLevels { + StemLevels::from_stems( + analysis.grid.beat_secs, + analysis.grid.first_beat_secs, + pcm.sample_rate, + pcm.frames.len(), + |stem, frame| { + let chunk = frame / stems.chunk_frames; + let offset = frame - chunk * stems.chunk_frames; + let sample = stems.lanes[stem.index()].get(chunk)?.as_ref()?.get(offset)?; + let scale = crate::mixer::STEM_CHUNK_HEADROOM / 32768.0; + Some([sample[0] as f32 * scale, sample[1] as f32 * scale]) + }, + ) +} + +fn stem_span_ready(stems: &TrackStems, stem: usize, start: usize, end: usize) -> bool { + if start >= end { + return true; + } + let first = start / stems.chunk_frames; + let last = (end - 1) / stems.chunk_frames; + for chunk in first..=last { + let Some(Some(block)) = stems.lanes[stem].get(chunk) else { return false }; + let needed_end = if chunk == last { + end - chunk * stems.chunk_frames + } else { + stems.chunk_frames + }; + if block.len() < needed_end { + return false; + } + } + true +} + +fn copy_loop_mono( + pcm: &TrackPcm, + stems: Option<(&TrackStems, usize)>, + start: usize, + end: usize, +) -> Vec { + let mut mono = Vec::with_capacity(end.saturating_sub(start)); + match stems { + Some((stems, stem)) => { + let scale = crate::mixer::STEM_CHUNK_HEADROOM / 32768.0 * 0.5; + for frame in start..end { + let chunk = frame / stems.chunk_frames; + let offset = frame - chunk * stems.chunk_frames; + let sample = stems.lanes[stem][chunk] + .as_ref() + .and_then(|block| block.get(offset)) + .copied() + .unwrap_or([0, 0]); + mono.push((sample[0] as f32 + sample[1] as f32) * scale); + } + } + None => { + for sample in &pcm.frames[start..end] { + mono.push((sample[0] as f32 + sample[1] as f32) * (0.5 / 32768.0)); + } + } + } + mono +} + /// What the scan dialog can put back. Taken when the dialog opens, dropped /// on OK, spent on CANCEL — the undo the deleted X button used to carry in /// `marks_stash`, now covering the yellow row and the settings as well. @@ -2878,6 +3294,9 @@ struct DeckRefs { loop_in: ButtonRef, loop_out: ButtonRef, loop_scan: ButtonRef, + jump_back: ButtonRef, + jump_fwd: ButtonRef, + phase_flip: ButtonRef, mute: ButtonRef, sync: ButtonRef, keylock: ButtonRef, @@ -2926,6 +3345,9 @@ impl DeckRefs { loop_in: ui.button(cx, ids.loop_in), loop_out: ui.button(cx, ids.loop_out), loop_scan: ui.button(cx, ids.loop_scan), + jump_back: ui.button(cx, ids.jump_back), + jump_fwd: ui.button(cx, ids.jump_fwd), + phase_flip: ui.button(cx, ids.phase_flip), mute: ui.button(cx, ids.mute), sync: ui.button(cx, ids.sync), keylock: ui.button(cx, ids.keylock), @@ -3026,6 +3448,9 @@ struct MusicDeckIds { loop_in: &'static [LiveId], loop_out: &'static [LiveId], loop_scan: &'static [LiveId], + jump_back: &'static [LiveId], + jump_fwd: &'static [LiveId], + phase_flip: &'static [LiveId], mute: &'static [LiveId], sync: &'static [LiveId], keylock: &'static [LiveId], @@ -3077,6 +3502,9 @@ impl MusicDeckIds { loop_in: ids!(deck_a_loop_in), loop_out: ids!(deck_a_loop_out), loop_scan: ids!(deck_a_loop_scan), + jump_back: ids!(deck_a_jump_back), + jump_fwd: ids!(deck_a_jump_fwd), + phase_flip: ids!(deck_a_phase_flip), mute: ids!(deck_a_mute), sync: ids!(deck_a_sync), keylock: ids!(deck_a_keylock), @@ -3156,6 +3584,9 @@ impl MusicDeckIds { loop_in: ids!(deck_b_loop_in), loop_out: ids!(deck_b_loop_out), loop_scan: ids!(deck_b_loop_scan), + jump_back: ids!(deck_b_jump_back), + jump_fwd: ids!(deck_b_jump_fwd), + phase_flip: ids!(deck_b_phase_flip), mute: ids!(deck_b_mute), sync: ids!(deck_b_sync), keylock: ids!(deck_b_keylock), @@ -5421,6 +5852,21 @@ const CATEGORY_WIDTH: f64 = 96.0; const CATEGORY_NARROW_WIDTH: f64 = 68.0; #[derive(Script, ScriptHook)] pub struct App { + /// The hub's local model store (install state, licence acks, weight + /// paths) for the models the DJ page runs in-process. Opened lazily; + /// `None` after a failed open so the page keeps working without it. + #[rust] + hub_models: Option>, + /// Salamander is decoded on a worker after the hub verifies every WAV; + /// only the completed immutable bank crosses into mixer audio state. + #[rust] + drum_bank_loaded: bool, + #[rust] + drum_bank_requested: Option, + #[rust] + drum_bank_rx: Option< + std::sync::mpsc::Receiver, String), String>>, + >, #[live] ui: WidgetRef, #[rust] @@ -6126,6 +6572,42 @@ pub struct App { deck_found_scores: [Vec; 2], #[rust] deck_analysis: [Option>; 2], + /// Which deck the loop-splat grid and controller surface address. + #[rust(DeckId::A)] + splat_focus: DeckId, + /// Last pure model pushed to the widget; controller LEDs reuse it. + #[rust] + splat_model: SplatViewModel, + #[rust] + deck_splat_snapshot_seen: [bool; 2], + /// Model-rate separation frontier and completion flag per deck. + #[rust] + deck_stem_coverage: [Option<(usize, bool)>; 2], + /// The expensive full-track levels returned with the refined grid. + #[rust] + #[rust] + deck_splat_refining: [Option; 2], + #[rust(SplatRefineWorker::new())] + splat_refine: SplatRefineWorker, + /// The selected loop's notation panel and its latest-wins DSP worker. + #[rust] + loop_score_open: bool, + #[rust] + loop_score_signature: Option, + #[rust] + loop_score_presented: Option, + #[rust] + loop_score_has_lyrics: bool, + /// Whether the score preview repeats the loop. + #[rust(true)] + loop_score_loop: bool, + /// Raw transcriptions and their compact roll geometry share one key. + #[rust] + loop_score_transcriptions: HashMap>, + #[rust] + splat_blocks: HashMap>, + #[rust(LoopScoreWorker::new())] + loop_score_worker: LoopScoreWorker, /// The waveform pyramid per deck: one texture holding every zoom level. #[rust] deck_zoom_tex: [Option; 2], @@ -6278,11 +6760,11 @@ pub struct App { /// Whether the status bar is standing on two lines. #[rust] status_bar_wrapped: bool, - /// Whether the explorer and the queue are taking turns, and which of - /// them is up. Explorer first: it is where a set starts. - #[rust] + /// Whether the bottom panels are taking turns, and which one is up. + /// The loop splat is the default; explorer and queue remain one tap away. + #[rust(true)] lists_tabbed: bool, - #[rust] + #[rust(2usize)] lists_shown: usize, /// How far the tabs have to go at this width, so the strips are only /// rebuilt on an actual change. @@ -6357,6 +6839,10 @@ pub struct App { /// One-shot initial sync of the models row once the surface is live. #[rust] models_row_synced: bool, + /// The shared hub panel has been populated at least once. From then on + /// its install workers are pumped even if the containing modal closes. + #[rust] + hub_model_panel_ready: bool, /// Thumb-load profile: (boot instant, last print, decoded at last print). #[rust] thumb_prof: Option<(std::time::Instant, std::time::Instant, u64)>, @@ -11088,6 +11574,636 @@ p2 {} self.video_pump = cx.new_next_frame(); } + fn set_loop_score_empty(&mut self, cx: &mut Cx, title: &str) { + self.mixer.score_preview_stop(); + self.loop_score_has_lyrics = false; + self.ui.label(cx, ids!(loop_score_title)).set_text(cx, title); + let widget = self.ui.widget(cx, ids!(loop_score)); + if let Some(mut score) = widget.borrow_mut::() { + score.clear(cx); + }; + } + + fn set_loop_score_title(&mut self, cx: &mut Cx, key: LoopScoreKey) { + let engine = self + .loop_score_transcriptions + .get(&key) + .and_then(|transcription| transcription.pitch_engine()) + .or_else(|| { + matches!(key.row, SplatRowView::Bass | SplatRowView::Vocals | SplatRowView::Other) + .then_some(if key.basic_pitch { + LoopScorePitchEngine::BasicPitch + } else { + LoopScorePitchEngine::PitchTracker + }) + }); + let title = self.loop_score_title_with_drum_status(key, self.loop_score_has_lyrics, engine); + self.ui.label(cx, ids!(loop_score_title)).set_text(cx, &title); + } + + fn loop_score_title_with_drum_status( + &self, + key: LoopScoreKey, + has_lyrics: bool, + engine: Option, + ) -> String { + let mut title = Self::loop_score_title(key, has_lyrics, engine); + if !self.drum_bank_loaded { + title.push_str(" · install the drum kit (INSTALL MODELS)"); + } + title + } + + fn loop_score_title( + key: LoopScoreKey, + has_lyrics: bool, + engine: Option, + ) -> String { + let bpm = f64::from_bits(key.bpm_bits); + let suffix = match key.row { + SplatRowView::Vocals if has_lyrics => " · melody + lyrics", + SplatRowView::Vocals | SplatRowView::Other => " · melody (approx.)", + SplatRowView::Mix => " · drums from mix (approx.)", + SplatRowView::Drums | SplatRowView::Bass => "", + }; + let engine = match engine { + Some(LoopScorePitchEngine::BasicPitch) => " · basic pitch", + Some(LoopScorePitchEngine::PitchTracker) => " · pitch tracker", + None => "", + }; + format!( + "{} · section {} · {} bars · {:.0} bpm{}{}", + key.row.label(), + key.col + 1, + key.bars, + bpm, + suffix, + engine, + ) + } + + /// The presented cell's transcription, if the worker has delivered it. + fn presented_loop_score(&self) -> Option<(LoopScoreKey, Arc)> { + let key = self.loop_score_presented?; + let transcription = self.loop_score_transcriptions.get(&key)?.clone(); + Some((key, transcription)) + } + + fn loop_score_preview_progress( + key: LoopScoreKey, + sample_rate: f64, + position: u64, + ) -> Option<(f64, f32)> { + let bpm = f64::from_bits(key.bpm_bits); + if !bpm.is_finite() || bpm <= 0.0 || !sample_rate.is_finite() || sample_rate <= 0.0 { + return None; + } + let whole = position as f64 / sample_rate * bpm / 60.0 / 4.0; + let phase = (whole / f64::from(key.bars.max(1))).clamp(0.0, 1.0) as f32; + Some((whole, phase)) + } + + fn loop_score_preview_marker(&self, deck: DeckId) -> Option<(usize, usize, f32)> { + let (playing, position) = self.mixer.score_preview_state(); + let key = self.loop_score_presented?; + if !playing || key.deck != deck { + return None; + } + let sample_rate = self + .mixer + .output_sample_rate() + .unwrap_or(key.sample_rate.max(1) as f64); + let (_, phase) = Self::loop_score_preview_progress(key, sample_rate, position)?; + let row = SplatRowView::ALL.iter().position(|row| *row == key.row)?; + Some((row, key.col as usize, phase)) + } + + fn refresh_loop_score_preview(&mut self, cx: &mut Cx) { + let presented = self + .loop_score_presented + .filter(|key| self.loop_score_transcriptions.contains_key(key)); + let (playing, position) = self.mixer.score_preview_state(); + let progress = presented.and_then(|key| { + if !playing { + return None; + } + let sample_rate = self + .mixer + .output_sample_rate() + .unwrap_or(key.sample_rate.max(1) as f64); + Self::loop_score_preview_progress(key, sample_rate, position) + }); + let widget = self.ui.widget(cx, ids!(loop_score)); + if let Some(mut score) = widget.borrow_mut::() { + score.set_playhead(cx, progress.map(|(whole, _)| whole)); + } + let Some(key) = presented else { + self.refresh_splat_preview(cx); + return; + }; + let Some((whole, _)) = progress else { + self.set_loop_score_title(cx, key); + self.refresh_splat_preview(cx); + return; + }; + let beats = whole * 4.0; + let bar = (beats / 4.0).floor() as u64 + 1; + let beat = beats.rem_euclid(4.0).floor() as u64 + 1; + let engine = self + .loop_score_transcriptions + .get(&key) + .and_then(|transcription| transcription.pitch_engine()); + self.ui.label(cx, ids!(loop_score_title)).set_text( + cx, + &format!( + "▶ bar {bar} · beat {beat} {}", + self.loop_score_title_with_drum_status( + key, + self.loop_score_has_lyrics, + engine, + ) + ), + ); + self.refresh_splat_preview(cx); + } + + fn play_loop_score_preview(&mut self, cx: &mut Cx) { + let Some((key, transcription)) = self.presented_loop_score() else { return }; + let sample_rate = self + .mixer + .output_sample_rate() + .unwrap_or(48_000.0) + .round() + .clamp(1.0, u32::MAX as f64) as u32; + let bpm = f64::from_bits(key.bpm_bits); + let bars = u32::from(key.bars); + let sequence = match transcription.as_ref() { + LoopScoreTranscription::Drums(hits) => crate::score_preview::sequence_from_drums( + hits, + bpm, + bars, + sample_rate, + self.loop_score_loop, + ), + LoopScoreTranscription::Pitched { notes, .. } => crate::score_preview::sequence_from_notes( + notes, + bpm, + bars, + sample_rate, + self.loop_score_loop, + ), + }; + self.mixer.score_preview_play(Arc::new(sequence)); + self.refresh_loop_score_preview(cx); + self.schedule_music_frame(cx); + } + + fn apply_loop_score_transcription( + &mut self, + cx: &mut Cx, + key: LoopScoreKey, + transcription: &LoopScoreTranscription, + lyrics: &[makepad_score_view::build::LyricWord], + ) { + let options = makepad_score_view::build::BuildOptions { + bars: u32::from(key.bars), + beats_per_bar: 4, + bpm: Some(f64::from_bits(key.bpm_bits)), + title: None, + ..Default::default() + }; + let score = match (key.row, transcription) { + (SplatRowView::Drums | SplatRowView::Mix, LoopScoreTranscription::Drums(hits)) => { + makepad_score_view::build::build_drum_score(hits, &options) + } + (SplatRowView::Bass, LoopScoreTranscription::Pitched { notes, .. }) => { + makepad_score_view::build::build_bass_tab_score( + notes, + &[28, 33, 38, 43], + &options, + ) + } + (SplatRowView::Vocals, LoopScoreTranscription::Pitched { notes, .. }) => { + makepad_score_view::build::build_pitched_score_with_lyrics( + notes, + lyrics, + &options, + ) + } + (SplatRowView::Other, LoopScoreTranscription::Pitched { notes, .. }) => { + makepad_score_view::build::build_pitched_score(notes, &options) + } + _ => return, + }; + self.loop_score_has_lyrics = key.row == SplatRowView::Vocals && !score.lyrics.is_empty(); + self.set_loop_score_title(cx, key); + let widget = self.ui.widget(cx, ids!(loop_score)); + if let Some(mut view) = widget.borrow_mut::() { + view.set_score(cx, score); + }; + } + + fn loop_score_job( + &self, + deck: DeckId, + row: SplatRowView, + col: u8, + notes_model: Option, + ) -> Option<(LoopScoreKey, bool, Option)> { + let row_index = splat_row(row).index(); + let splat = self.decks.splat(deck)?; + let cell = splat.grid.cells[row_index].get(col as usize).copied().flatten()?; + let bpm = splat.grid.bpm; + let index = deck.index(); + let pcm = self.deck_tracks[index].as_ref()?.0.clone(); + let rate = pcm.sample_rate.max(1); + let start_frame = (cell.span.start_secs.max(0.0) * rate as f64).floor() as usize; + let end_frame = (cell.span.end_secs.max(0.0) * rate as f64).ceil() as usize; + let start_frame = start_frame.min(pcm.frames.len()); + let end_frame = end_frame.clamp(start_frame, pcm.frames.len()); + let stem = splat_row(row).stem().map(|stem| stem.index()); + let stems = self.deck_stems[index].clone(); + let source_ready = stem.is_none() + || stems + .as_ref() + .is_some_and(|stems| stem_span_ready(stems, stem.unwrap(), start_frame, end_frame)); + let notes_model = matches!(row, SplatRowView::Bass | SplatRowView::Vocals | SplatRowView::Other) + .then_some(notes_model) + .flatten(); + let key = LoopScoreKey { + deck, + row, + col, + load_gen: self.decks.deck(deck).load_gen, + start_frame, + end_frame, + sample_rate: rate, + bars: cell.bars, + bpm_bits: bpm.to_bits(), + basic_pitch: notes_model.is_some(), + }; + let lyrics = if row == SplatRowView::Vocals { + loop_score_lyric_words( + self.deck_lyrics[index].as_deref(), + cell.span.start_secs, + cell.span.end_secs, + bpm, + ) + } else { + Vec::new() + }; + let job = source_ready.then(|| LoopScoreJob { + key, + pcm, + stems: stem.map(|stem| (stems.expect("ready stem source"), stem)), + clock: crate::loop_transcribe::LoopClock { + bpm, + bars: u32::from(cell.bars), + beats_per_bar: 4, + }, + lyrics, + notes_model, + }); + Some((key, source_ready, job)) + } + + fn collect_loop_score_results(&mut self) { + let load_gens = [ + self.decks.deck(DeckId::A).load_gen, + self.decks.deck(DeckId::B).load_gen, + ]; + self.loop_score_worker.discard_stale(load_gens); + self.loop_score_transcriptions + .retain(|key, _| load_gens[key.deck.index()] == key.load_gen); + self.splat_blocks + .retain(|key, _| load_gens[key.deck.index()] == key.load_gen); + for done in self.loop_score_worker.poll() { + if load_gens[done.key.deck.index()] != done.key.load_gen { + continue; + } + self.loop_score_transcriptions.insert(done.key, done.transcription); + self.splat_blocks.insert(done.key, done.blocks); + } + } + + fn schedule_splat_blocks(&mut self, model: &mut SplatViewModel) { + let deck = self.splat_focus; + let notes_model = self.hub_model_path("basic-pitch", "model"); + let mut jobs = Vec::new(); + for row in 0..crate::loop_splat_view::SPLAT_ROWS { + for col in 0..model.cols { + if !matches!( + model.cells[row][col], + SplatCellView::Ready { .. } + | SplatCellView::Queued { .. } + | SplatCellView::Playing { .. } + ) { + continue; + } + let row_view = SplatRowView::ALL[row]; + let Some((key, source_ready, job)) = + self.loop_score_job(deck, row_view, col as u8, notes_model.clone()) + else { + continue; + }; + if let Some(blocks) = self.splat_blocks.get(&key) { + model.blocks[row][col] = Some(blocks.clone()); + } else if source_ready { + if let Some(job) = job { + jobs.push(job); + } + } + } + } + for job in jobs { + self.loop_score_worker.submit(job); + } + } + + /// The hub model store, opened on first use. + fn hub_models(&mut self) -> Option<&mut makepad_ai_hub::local::LocalModels> { + if self.hub_models.is_none() { + let opened = match makepad_ai_hub::local::LocalModels::open() { + Ok(models) => Some(models), + Err(error) => { + log!("hub models unavailable: {error}"); + None + } + }; + self.hub_models = Some(opened); + } + self.hub_models.as_mut().and_then(|slot| slot.as_mut()) + } + + /// Where an installed, licence-acknowledged hub model file lives, by + /// model id and file role — `None` means "run without it". + fn hub_model_path(&mut self, model_id: &str, role: &str) -> Option { + let models = self.hub_models()?; + if !models.license_acknowledged(model_id) { + return None; + } + models.installed_path(model_id, role) + } + + /// Pick up a verified Salamander install, decode it away from the UI and + /// audio threads, then hand the immutable bank to mixer audio state. + fn pump_drum_bank(&mut self, cx: &mut Cx) { + let completed = self.drum_bank_rx.as_ref().and_then(|receiver| { + match receiver.try_recv() { + Ok(result) => Some(result), + Err(std::sync::mpsc::TryRecvError::Empty) => None, + Err(std::sync::mpsc::TryRecvError::Disconnected) => { + Some(Err("drum bank loader disconnected".to_string())) + } + } + }); + if let Some(completed) = completed { + self.drum_bank_rx = None; + match completed { + Ok((bank, summary)) => { + self.mixer.run_cmd(MixCmd::SetDrumBank(bank)); + self.drum_bank_loaded = true; + log!("drum kit: {summary}"); + if let Some(key) = self.loop_score_presented { + self.set_loop_score_title(cx, key); + } + } + Err(error) => log!("drum kit load failed: {error}"), + } + } + if self.drum_bank_loaded || self.drum_bank_rx.is_some() { + return; + } + let ready_dir = { + let Some(models) = self.hub_models() else { return }; + if !models.license_acknowledged("salamander-drumkit") { + return; + } + models.installed_dir("salamander-drumkit") + }; + let Some(dir) = ready_dir else { return }; + if self.drum_bank_requested.as_ref() == Some(&dir) { + return; + } + let (sender, receiver) = std::sync::mpsc::channel(); + self.drum_bank_requested = Some(dir.clone()); + self.drum_bank_rx = Some(receiver); + if let Err(error) = std::thread::Builder::new() + .name("salamander-drumkit-load".to_string()) + .spawn(move || { + let result = makepad_drumkit::SampleBank::load(&dir).map(|bank| { + let summary = bank.summary(); + (Arc::new(bank), summary) + }); + let _ = sender.send(result); + }) + { + self.drum_bank_rx = None; + log!("drum kit loader could not start: {error}"); + } + } + + fn pump_loop_score(&mut self, cx: &mut Cx) { + self.collect_loop_score_results(); + if !self.loop_score_open { + return; + } + self.place_loop_score_panel(cx); + let selected = { + let widget = self.ui.vj_loop_splat(cx, ids!(loop_splat)); + widget.borrow().and_then(|splat| splat.selected()) + }; + let Some((row, col)) = selected else { + if self.loop_score_signature != Some(LoopScoreSignature::Empty) { + self.loop_score_signature = Some(LoopScoreSignature::Empty); + self.loop_score_presented = None; + self.set_loop_score_empty(cx, "select a loop cell"); + } + return; + }; + + let deck = self.splat_focus; + let notes_model = self.hub_model_path("basic-pitch", "model"); + let Some((key, source_ready, job)) = + self.loop_score_job(deck, row, col, notes_model) + else { + if self.loop_score_signature != Some(LoopScoreSignature::Empty) { + self.loop_score_signature = Some(LoopScoreSignature::Empty); + self.loop_score_presented = None; + self.set_loop_score_empty(cx, "track audio unavailable"); + } + return; + }; + let lyrics_ready = row == SplatRowView::Vocals && self.deck_lyrics[deck.index()].is_some(); + let signature = LoopScoreSignature::Selected { key, source_ready, lyrics_ready }; + if self.loop_score_signature != Some(signature) { + self.mixer.score_preview_stop(); + self.loop_score_signature = Some(signature); + self.loop_score_presented = None; + self.loop_score_has_lyrics = false; + if !source_ready { + self.set_loop_score_empty(cx, "stems still separating…"); + } else { + self.set_loop_score_title(cx, key); + } + } + if !source_ready { + return; + } + if let Some(transcription) = self.loop_score_transcriptions.get(&key).cloned() { + if self.loop_score_presented != Some(key) { + let lyrics = job.as_ref().map(|job| job.lyrics.as_slice()).unwrap_or(&[]); + self.apply_loop_score_transcription(cx, key, &transcription, lyrics); + self.loop_score_presented = Some(key); + } + } else if let Some(job) = job { + self.loop_score_worker.submit(job); + } + } + + /// Float the score card over the deck lanes without taking layout space + /// from the loop splat below. The deck rect supplies the stable top edge; + /// the full responsive page body supplies the centring width. + /// The score popup covers the whole deck region above the loop grid. + fn place_loop_score_panel(&mut self, cx: &mut Cx) { + let deck = self.ui.view(cx, ids!(deck_region)).area().rect(cx); + if deck.size.x <= 0.0 || deck.size.y <= 0.0 { + return; + } + let panel = self.ui.view(cx, ids!(loop_score_panel)); + let mut panel_ref = panel.borrow_mut(); + if let Some(view) = panel_ref.as_mut() { + view.walk.abs_pos = Some(deck.pos); + view.walk.width = Size::Fixed(deck.size.x); + view.walk.height = Size::Fixed(deck.size.y); + } + } + + fn handle_splat_action(&mut self, cx: &mut Cx, action: LoopSplatAction) { + if action == LoopSplatAction::ToggleScore { + self.loop_score_open = !self.loop_score_open; + self.ui + .view(cx, ids!(loop_score_panel)) + .set_visible(cx, self.loop_score_open); + self.loop_score_signature = None; + self.loop_score_presented = None; + if self.loop_score_open { + self.place_loop_score_panel(cx); + self.pump_loop_score(cx); + } else { + self.mixer.score_preview_stop(); + } + return; + } + if let LoopSplatAction::FocusDeck(deck) = action { + self.mixer.score_preview_stop(); + self.splat_focus = match deck { + crate::loop_splat_view::SplatDeck::A => DeckId::A, + crate::loop_splat_view::SplatDeck::B => DeckId::B, + }; + self.refresh_loop_score_preview(cx); + self.refresh_splat_surface(cx); + return; + } + let deck = self.splat_focus; + match action { + LoopSplatAction::Cell { row, col, timed, part } => { + let Some(row_index) = + SplatRowView::ALL.iter().position(|candidate| *candidate == row) + else { + return; + }; + if self.splat_model.deck != splat_deck(deck) + || (col as usize) >= self.splat_model.cols + { + return; + } + match self.splat_model.cells[row_index][col as usize] { + // Clicking the slot that is sounding (or queued) stops the + // row; clicking ANOTHER slot of the same cell switches to + // that sub-loop instead, so halves and quarters can be + // played one after the other. + SplatCellView::Queued { part: current, .. } + | SplatCellView::Playing { part: current, .. } + if current == part => + { + let cmds = self.decks.splat_stop_row(deck, splat_row(row), timed); + self.run_deck_cmds(cx, cmds); + return; + } + SplatCellView::Queued { .. } + | SplatCellView::Playing { .. } + | SplatCellView::Ready { .. } => {} + SplatCellView::Empty | SplatCellView::Silent => return, + } + let Some(splat) = self.decks.splat(deck) else { return }; + let enabled = splat.enabled; + let playing = self.decks.deck(deck).playing; + let mut cmds = Vec::new(); + if !enabled { + cmds.extend(self.decks.splat_enable(deck, true)); + } + cmds.extend(self.decks.splat_launch(deck, splat_row(row), col, part)); + if !playing { + cmds.extend(self.decks.play_pause(deck)); + } + self.run_deck_cmds(cx, cmds); + } + LoopSplatAction::StopRow { row, timed } => { + let cmds = self.decks.splat_stop_row(deck, splat_row(row), timed); + self.run_deck_cmds(cx, cmds); + } + LoopSplatAction::LaunchColumn { col, timed } => { + let Some(splat) = self.decks.splat(deck) else { return }; + if col as usize >= splat.grid.sections.len() { + return; + } + // The section button toggles: a running section stops (stem rows only). + let live_rows: Vec = SplatRowView::ALL[..SPLAT_ROWS - 1] + .iter() + .enumerate() + .filter(|(row, _)| { + self.splat_model.deck == splat_deck(deck) + && matches!( + self.splat_model.cells[*row][col as usize], + SplatCellView::Playing { .. } | SplatCellView::Queued { .. } + ) + }) + .map(|(_, row)| *row) + .collect(); + if !live_rows.is_empty() { + let mut cmds = Vec::new(); + for row in live_rows { + cmds.extend(self.decks.splat_stop_row(deck, splat_row(row), timed)); + } + self.run_deck_cmds(cx, cmds); + return; + } + let enabled = splat.enabled; + let playing = self.decks.deck(deck).playing; + let mut cmds = Vec::new(); + if !enabled { + cmds.extend(self.decks.splat_enable(deck, true)); + } + cmds.extend(self.decks.splat_scene(deck, col)); + if !playing { + cmds.extend(self.decks.play_pause(deck)); + } + self.run_deck_cmds(cx, cmds); + } + LoopSplatAction::ToggleEnabled => { + let Some(enabled) = self.decks.splat(deck).map(|splat| splat.enabled) else { + return; + }; + let cmds = self.decks.splat_enable(deck, !enabled); + self.run_deck_cmds(cx, cmds); + } + LoopSplatAction::FocusDeck(_) + | LoopSplatAction::ToggleScore + | LoopSplatAction::None => {} + } + } + fn dispatch_apc_action(&mut self, cx: &mut Cx, action: ApcAction) { match action { ApcAction::Pad { surface, pad, index, pressed } => { @@ -11100,6 +12216,40 @@ p2 {} // this physical pad was reused. self.release_apc_sfx_pad(pad); } + if surface == ApcSurface::Music && self.decks.splat(self.splat_focus).is_some() { + let row = index / 8; + let col = index % 8; + let Some(row) = SplatRowView::ALL.get(row).copied() else { return }; + let launchable = SplatRowView::ALL + .iter() + .position(|candidate| *candidate == row) + .is_some_and(|row| { + col < self.splat_model.cols + && matches!( + self.splat_model.cells[row][col], + SplatCellView::Ready { .. } + | SplatCellView::Queued { .. } + | SplatCellView::Playing { .. } + ) + }); + if !launchable { + return; + } + let widget = self.ui.vj_loop_splat(cx, ids!(loop_splat)); + if let Some(mut splat) = widget.borrow_mut() { + splat.set_selected(cx, row, col as u8); + } + self.handle_splat_action( + cx, + LoopSplatAction::Cell { + row, + col: col as u8, + timed: false, + part: SplatPart::WHOLE, + }, + ); + return; + } let Some(asset) = self.apc_asset_at(surface, index) else { return }; match surface { ApcSurface::Video => self.video_tile_clicked(cx, asset, false), @@ -11113,6 +12263,24 @@ p2 {} } } } + ApcAction::Scene { surface, row, pressed } => { + if pressed + && surface == ApcSurface::Music + && self.decks.splat(self.splat_focus).is_some() + { + if let Some(row) = SplatRowView::ALL.get(row as usize).copied() { + self.handle_splat_action(cx, LoopSplatAction::StopRow { row, timed: false }); + } + } + } + ApcAction::ClipStop { surface, col, pressed } => { + if pressed + && surface == ApcSurface::Music + && self.decks.splat(self.splat_focus).is_some() + { + self.handle_splat_action(cx, LoopSplatAction::LaunchColumn { col, timed: false }); + } + } ApcAction::Surface(_) => self.show_apc_surface(cx), ApcAction::VideoPlayPause => self.toggle_video_playback(cx), ApcAction::VideoStop => self.stop_video_playback(cx), @@ -11174,6 +12342,18 @@ p2 {} self.run_deck_cmds(cx, cmds); self.sync_deck_knobs(cx, deck); } + ApcAction::BankLeft => { + self.handle_splat_action( + cx, + LoopSplatAction::FocusDeck(crate::loop_splat_view::SplatDeck::A), + ); + } + ApcAction::BankRight => { + self.handle_splat_action( + cx, + LoopSplatAction::FocusDeck(crate::loop_splat_view::SplatDeck::B), + ); + } ApcAction::BankChanged => { if self.apc.surface == ApcSurface::Video { let widget = self.ui.widget(cx, ids!(video_grid)); @@ -11244,60 +12424,70 @@ p2 {} } fn sync_apc_leds(&mut self) { - let count = self.apc_item_count(); + let splat_showing = self.apc.surface == ApcSurface::Music + && self.splat_model.cols != 0 + && self.splat_model.deck == splat_deck(self.splat_focus) + && self.decks.splat(self.splat_focus).is_some(); + let count = if splat_showing { PAD_COUNT } else { self.apc_item_count() }; self.apc.clamp_bank(count); - let mut frame = LedFrame { surface: self.apc.surface, ..Default::default() }; - for pad in 0..PAD_COUNT { - let index = self.apc.bank + pad; - // Resolve the same asset a press on this pad would trigger - // (local-first mixed lists / the banked video window) so LEDs - // never point at a different clip than the pad plays. - let Some(asset) = self.apc_asset_at(self.apc.surface, index) else { continue }; - let tile = match self.apc.surface { - ApcSurface::Video => self.video_model.tiles().iter().find(|t| t.asset == asset), - ApcSurface::Music => self.music_model.tiles().iter().find(|t| t.asset == asset), - ApcSurface::Sfx => self.sfx_model.tiles().iter().find(|t| t.asset == asset), - }; - // The pad wears the clip's thumbnail colour once that is known. - let color = tile - .and_then(|tile| tile.revision) - .and_then(|rev| self.thumb_leds.get(&rev).copied()); - let mut state = tile - .map(|tile| match tile.state { - catalog::TileState::Ready => color.map_or(PadLed::Ready, PadLed::Color), - catalog::TileState::Failed(_) => PadLed::Failed, - catalog::TileState::Listed | catalog::TileState::Resolving => PadLed::Queued, - }) - .unwrap_or(PadLed::Ready); - match self.apc.surface { - ApcSurface::Video => { - if self.cue.live().is_some_and(|item| item.asset == asset) { - state = color.map_or(PadLed::Live, PadLed::LiveColor); - } else if self.cue.next().is_some_and(|item| item.asset == asset) { - state = color.map_or(PadLed::Queued, PadLed::NextColor); + let mut frame = if splat_showing { + splat_led_frame(&self.splat_model, self.apc.surface) + } else { + LedFrame { surface: self.apc.surface, ..Default::default() } + }; + if !splat_showing { + for pad in 0..PAD_COUNT { + let index = self.apc.bank + pad; + // Resolve the same asset a press on this pad would trigger + // (local-first mixed lists / the banked video window) so LEDs + // never point at a different clip than the pad plays. + let Some(asset) = self.apc_asset_at(self.apc.surface, index) else { continue }; + let tile = match self.apc.surface { + ApcSurface::Video => self.video_model.tiles().iter().find(|t| t.asset == asset), + ApcSurface::Music => self.music_model.tiles().iter().find(|t| t.asset == asset), + ApcSurface::Sfx => self.sfx_model.tiles().iter().find(|t| t.asset == asset), + }; + // The pad wears the clip's thumbnail colour once that is known. + let color = tile + .and_then(|tile| tile.revision) + .and_then(|rev| self.thumb_leds.get(&rev).copied()); + let mut state = tile + .map(|tile| match tile.state { + catalog::TileState::Ready => color.map_or(PadLed::Ready, PadLed::Color), + catalog::TileState::Failed(_) => PadLed::Failed, + catalog::TileState::Listed | catalog::TileState::Resolving => PadLed::Queued, + }) + .unwrap_or(PadLed::Ready); + match self.apc.surface { + ApcSurface::Video => { + if self.cue.live().is_some_and(|item| item.asset == asset) { + state = color.map_or(PadLed::Live, PadLed::LiveColor); + } else if self.cue.next().is_some_and(|item| item.asset == asset) { + state = color.map_or(PadLed::Queued, PadLed::NextColor); + } } - } - ApcSurface::Music => { - for deck in [DeckId::A, DeckId::B] { - let deck = self.decks.deck(deck); - let loaded = match &deck.load { - DeckLoad::Loading { item, .. } - | DeckLoad::Loaded { item } - | DeckLoad::Failed { item, .. } => Some(item.asset), - DeckLoad::Empty => None, - }; - if loaded == Some(asset) { - state = if deck.playing { PadLed::Live } else { PadLed::Queued }; + ApcSurface::Music => { + for deck in [DeckId::A, DeckId::B] { + let deck = self.decks.deck(deck); + let loaded = match &deck.load { + DeckLoad::Loading { item, .. } + | DeckLoad::Loaded { item } + | DeckLoad::Failed { item, .. } => Some(item.asset), + DeckLoad::Empty => None, + }; + if loaded == Some(asset) { + state = if deck.playing { PadLed::Live } else { PadLed::Queued }; + } + } + } + ApcSurface::Sfx => { + if self.pads.playing_voices(&asset) > 0 { + state = PadLed::Live; } } } - ApcSurface::Sfx => { - if self.pads.playing_voices(&asset) > 0 { - state = PadLed::Live; - } - } + frame.pads[pad] = state; } - frame.pads[pad] = state; } frame.video_playing = self .cue @@ -12129,7 +13319,10 @@ p2 {} self.ui.modal(cx, ids!(loop_scan_modal)).close(cx); } self.deck_zoom_tex[deck.index()] = None; - self.deck_stems[deck.index()] = None; + self.deck_stems[deck.index()] = None; + self.deck_stem_coverage[deck.index()] = None; + self.deck_splat_refining[deck.index()] = None; + self.deck_splat_snapshot_seen[deck.index()] = false; self.deck_stem_tex[deck.index()] = None; self.deck_stem_tiles[deck.index()] = Vec::new(); // The old track's words must not sit over the new @@ -12205,11 +13398,29 @@ p2 {} DeckCmd::SetStemGain { deck, stem, gain } => { self.mixer.set_deck_stem_gain(deck, stem, gain) } + DeckCmd::SplatSet { deck, grid } => self.mixer.set_deck_splat(deck, grid), + DeckCmd::SplatEnable { deck, on } => { + self.mixer.set_deck_splat_enabled(deck, on) + } + DeckCmd::SplatLaunch { deck, row, col, part } => { + self.mixer.splat_launch(deck, row, col, part) + } + DeckCmd::SplatStopRow { deck, row, timed } => { + self.mixer.splat_stop_row(deck, row, timed) + } + DeckCmd::SplatLaunchScene { deck, col } => { + self.mixer.splat_launch_scene(deck, col) + } + DeckCmd::SplatStopAll { deck, timed } => self.mixer.splat_stop_all(deck, timed), DeckCmd::SwapVoices => { self.mixer.swap_decks(); self.deck_tracks.swap(0, 1); self.deck_analysis.swap(0, 1); self.deck_zoom_tex.swap(0, 1); + self.deck_stem_tex.swap(0, 1); + self.deck_stem_coverage.swap(0, 1); + self.deck_splat_refining = [None; 2]; + self.deck_splat_snapshot_seen.swap(0, 1); self.sync_deck_controls(cx); } DeckCmd::UnloadTrack { deck } => { @@ -12223,6 +13434,9 @@ p2 {} self.deck_analysis[index] = None; self.deck_zoom_tex[index] = None; self.deck_stems[index] = None; + self.deck_stem_coverage[index] = None; + self.deck_splat_refining[index] = None; + self.deck_splat_snapshot_seen[index] = false; self.deck_stem_tex[index] = None; self.deck_stem_tiles[index] = Vec::new(); self.deck_lyrics[index] = None; @@ -12273,21 +13487,66 @@ p2 {} } } + /// The operator says the grid is on the wrong pulse: flip it half a beat + /// everywhere it lives — the engine (sync), the analysis (loop grid, + /// autopilot map) and the sidecar, so the next load starts corrected. + fn flip_deck_beat_phase(&mut self, cx: &mut Cx, deck: DeckId) { + let Some((grid, cmds)) = self.decks.flip_beat_phase(deck) else { return }; + self.run_deck_cmds(cx, cmds); + let index = deck.index(); + let Some(analysis) = self.deck_analysis[index].as_ref() else { return }; + let mut flipped = (**analysis).clone(); + flipped.grid = grid; + let flipped = Arc::new(flipped); + self.deck_analysis[index] = Some(flipped.clone()); + let gen = self.decks.deck(deck).load_gen; + if let Some(splat) = build_splat(&flipped, None) { + let cmds = self.decks.splat_set(deck, Arc::new(splat)); + self.run_deck_cmds(cx, cmds); + if self.deck_stem_coverage[index].is_some_and(|(_, complete)| complete) { + self.submit_splat_refinement(deck, gen); + } + } + let shape = crate::track_shape::track_shape( + &flipped.tiles.overview, + flipped.duration_secs, + &flipped.grid, + ); + self.autopilot.shape_ready(gen, shape); + if let Some(item) = self.decks.deck(deck).item() { + let key = match self.local_by_asset.get(&item.asset) { + Some(path) => AnalysisKey::from_path(path), + None => AnalysisKey::from_blob(item.media_blob), + }; + let analysis = flipped.clone(); + std::thread::spawn(move || crate::wave_analysis::store_analysis(&key, &analysis)); + } + self.push_deck_wave(cx, deck); + self.refresh_splat_surface(cx); + } + /// Hand a freshly decoded track to the analysis worker. The key is the /// content digest, so a track that has been on a deck before comes back /// from its sidecar instead of being analysed again. fn submit_analysis(&mut self, deck: DeckId, pcm: Arc) { - let state = self.decks.deck(deck); - let Some(item) = state.item() else { return }; - let key = match self.local_by_asset.get(&item.asset) { - Some(path) => AnalysisKey::from_path(path), - None => AnalysisKey::from_blob(item.media_blob), + let (gen, key) = { + let state = self.decks.deck(deck); + let Some(item) = state.item() else { return }; + let key = match self.local_by_asset.get(&item.asset) { + Some(path) => AnalysisKey::from_path(path), + None => AnalysisKey::from_blob(item.media_blob), + }; + (state.load_gen, key) }; + // Hub state belongs to the UI thread. Resolve the acknowledged model + // path here and hand only the path to the analysis worker. + let beats_model = self.hub_model_path("beat-this", "weights"); self.analysis.submit(AnalysisJob { deck, - gen: state.load_gen, + gen, key, pcm, + beats_model, }); } @@ -12407,6 +13666,7 @@ p2 {} } self.pump_analysis(cx); self.pump_stems(cx); + self.pump_loop_score(cx); self.pump_loop_scan(cx); // Last, and only when everything above found nothing to do. self.pump_prefetch(); @@ -13645,7 +14905,9 @@ p2 {} } fn set_music_import_status(&mut self, cx: &mut Cx, text: &str) { - self.ui.label(cx, ids!(music_import_status)).set_text(cx, text); + let label = self.ui.label(cx, ids!(music_import_status)); + label.set_visible(cx, !text.is_empty()); + label.set_text(cx, text); self.ui.redraw(cx); } @@ -15494,10 +16756,7 @@ p2 {} self.ui.redraw(cx); } - /// The explorer and the queue take turns when they can no longer stand - /// side by side. - /// - /// Physical width in, like the rest of the chain. + /// The explorer, queue and loop splat always take turns behind tabs. fn sync_lists_tabs(&mut self, cx: &mut Cx, event: &Event) { let Event::WindowGeomChange(ev) = event else { return }; let Some(main_id) = self.ui.window(cx, ids!(main_window)).window_id() else { @@ -15506,12 +16765,7 @@ p2 {} if ev.window_id != main_id || !cx.windows.is_valid(main_id) { return; } - let native = cx.windows[main_id].native_dpi_factor(); - let physical = ev.new_geom.inner_size * ev.new_geom.dpi_factor; - // The width the LISTS get, which is a third of the window once they - // stand beside the decks. - let span = console_scale::lists_span(physical.x, physical.y, native); - let tabbed = console_scale::console_lists_tabbed(span, physical.y, native); + let tabbed = true; if tabbed == self.lists_tabbed { return; } @@ -15526,7 +16780,10 @@ p2 {} if strip.visible() != tabbed { strip.set_visible(cx, tabbed); } - for (index, list) in [ids!(library_drop), ids!(queue_drop)].into_iter().enumerate() { + for (index, list) in [ids!(library_drop), ids!(queue_drop), ids!(loops_drop)] + .into_iter() + .enumerate() + { let visible = !tabbed || index == self.lists_shown; let view = self.ui.widget(cx, list); if view.visible() != visible { @@ -15534,7 +16791,10 @@ p2 {} } } if tabbed { - for (index, tab) in [ids!(lists_tab_0), ids!(lists_tab_1)].into_iter().enumerate() { + for (index, tab) in [ids!(lists_tab_0), ids!(lists_tab_1), ids!(lists_tab_2)] + .into_iter() + .enumerate() + { self.paint_lit(cx, tab, index == self.lists_shown); } } @@ -15545,7 +16805,10 @@ p2 {} if !self.lists_tabbed { return; } - for (index, tab) in [ids!(lists_tab_0), ids!(lists_tab_1)].into_iter().enumerate() { + for (index, tab) in [ids!(lists_tab_0), ids!(lists_tab_1), ids!(lists_tab_2)] + .into_iter() + .enumerate() + { if self.ui.button(cx, tab).clicked(actions) && self.lists_shown != index { self.lists_shown = index; self.paint_lists_tabs(cx); @@ -18016,6 +19279,10 @@ p2 {} continue; } self.run_deck_cmds(cx, cmds); + if let Some(grid) = build_splat(&done.analysis, None) { + let cmds = self.decks.splat_set(done.deck, Arc::new(grid)); + self.run_deck_cmds(cx, cmds); + } self.deck_zoom_tex[index] = crate::music_view::zoom_texture(cx, &done.analysis.tiles); // The autopilot's map of this record: computed once per @@ -18029,6 +19296,9 @@ p2 {} self.autopilot.shape_ready(done.gen, shape); self.autopilot.changes_ready(done.gen, done.analysis.changes_secs.clone()); self.deck_analysis[index] = Some(done.analysis); + if self.deck_stem_coverage[index].is_some_and(|(_, complete)| complete) { + self.submit_splat_refinement(done.deck, done.gen); + } // A parked scan fires only if it is still parked against THIS // load: a track swap between the ask and the grid landing must // not spend the operator's scan on a track they never asked to @@ -18252,6 +19522,125 @@ p2 {} // ---- first-use model install (stem splitter + whisper) ---- + const DJ_HUB_MODELS: [&'static str; 3] = [ + "basic-pitch", + "beat-this", + "salamander-drumkit", + ]; + + fn hub_models_missing(&mut self) -> bool { + let Some(models) = self.hub_models() else { return false }; + Self::DJ_HUB_MODELS.iter().any(|model_id| { + models.spec(model_id).is_some() + && (!matches!( + models.install_state(model_id), + makepad_ai_hub::local::InstallState::Installed + ) || !models.license_acknowledged(model_id)) + }) + } + + fn humanise_model_id(model_id: &str) -> String { + model_id + .split('-') + .map(|word| { + let mut chars = word.chars(); + chars + .next() + .map(|first| first.to_uppercase().collect::() + chars.as_str()) + .unwrap_or_default() + }) + .collect::>() + .join(" ") + } + + fn refresh_hub_model_rows(&mut self, cx: &mut Cx) { + use makepad_ai_hub::local::InstallState; + use makepad_ai_hub::registry::LicenseRestriction; + use makepad_ai_hub_ui::{ModelInstallPanel, ModelRowInstallState, ModelRowState}; + + let panel_widget = self.ui.widget(cx, ids!(hub_model_install_panel)); + let previous: HashMap = panel_widget + .borrow::() + .map(|panel| { + panel + .rows() + .iter() + .map(|row| (row.model_id.clone(), row.state.clone())) + .collect() + }) + .unwrap_or_default(); + let Some(models) = self.hub_models() else { return }; + let rows = Self::DJ_HUB_MODELS + .iter() + .filter_map(|model_id| { + let spec = models.spec(model_id)?; + let bytes_total = spec.files.iter().filter_map(|file| file.size).sum(); + let old_state = previous.get(*model_id); + let (bytes_done, state) = match models.install_state(model_id) { + InstallState::NotInstalled { .. } => ( + 0, + match old_state { + Some(ModelRowInstallState::Failed(error)) => { + ModelRowInstallState::Failed(error.clone()) + } + _ => ModelRowInstallState::NotInstalled, + }, + ), + InstallState::Partial { bytes_done, .. } => ( + bytes_done, + if matches!(old_state, Some(ModelRowInstallState::Downloading)) { + ModelRowInstallState::Downloading + } else { + ModelRowInstallState::NotInstalled + }, + ), + InstallState::Installed => (bytes_total, ModelRowInstallState::Installed), + }; + let (license_name, restriction) = spec + .license + .as_ref() + .map(|license| { + let restriction = match license.restriction { + LicenseRestriction::None => "none", + LicenseRestriction::NonCommercial => "non-commercial", + LicenseRestriction::Community => "community", + LicenseRestriction::Restricted => "restricted", + }; + (license.name.clone(), restriction.to_string()) + }) + .unwrap_or_else(|| ("Licence unavailable".to_string(), "restricted".to_string())); + Some(ModelRowState { + model_id: (*model_id).to_string(), + name: Self::humanise_model_id(&spec.id), + bytes_total, + bytes_done, + state, + license_name, + restriction, + }) + }) + .collect(); + if let Some(mut panel) = panel_widget.borrow_mut::() { + panel.set_rows(cx, rows); + self.hub_model_panel_ready = true; + }; + } + + fn pump_hub_model_install(&mut self, cx: &mut Cx) { + if !self.hub_model_panel_ready { + return; + } + let panel = self.ui.widget(cx, ids!(hub_model_install_panel)); + if let Some(models) = self.hub_models() { + if let Some(mut panel) = + panel.borrow_mut::() + { + panel.pump(cx, models); + } + } + self.refresh_models_row(cx); + } + /// A queued hot-reload fires the moment its slot's previous chain /// settles — a save burst always ends on the newest revision. fn pump_fx_slot_reloads(&mut self) { @@ -18275,10 +19664,12 @@ p2 {} self.refresh_models_row(cx); return; } - if models::missing().is_empty() { + let hub_missing = self.hub_models_missing(); + if models::missing().is_empty() && !hub_missing { self.refresh_models_row(cx); return; } + self.refresh_hub_model_rows(cx); self.ui.modal(cx, ids!(models_license_modal)).open(cx); self.ui.redraw(cx); } @@ -18308,10 +19699,16 @@ p2 {} } let installing = self.model_install.is_some(); let missing = models::missing(); + let hub_missing = self.hub_models_missing(); let text = if !self.model_install_note.is_empty() { self.model_install_note.clone() } else if missing.is_empty() { - String::new() + if hub_missing { + "Basic Pitch, Beat This! and the Salamander drum kit are available for loop scores and beat analysis" + .to_string() + } else { + String::new() + } } else { let names = missing .iter() @@ -18324,13 +19721,13 @@ p2 {} bytes as f64 / 1.0e9 ) }; - let show = installing || !missing.is_empty() || !text.is_empty(); + let show = installing || !missing.is_empty() || hub_missing || !text.is_empty(); let row = self.ui.view(cx, ids!(models_row)); if row.visible() != show { row.set_visible(cx, show); } let button = &self.music_refs.models_install; - button.set_visible(cx, installing || !missing.is_empty()); + button.set_visible(cx, installing || !missing.is_empty() || hub_missing); button.set_text(cx, if installing { "CANCEL" } else { "INSTALL MODELS" }); self.music_refs.models_state.set_text(cx, &text); } @@ -18488,8 +19885,36 @@ p2 {} self.prefetch.release(finished, Instant::now()); } + fn submit_splat_refinement(&mut self, deck: DeckId, gen: u64) { + let index = deck.index(); + if self.deck_splat_refining[index] == Some(gen) { + return; + } + if let (Some(stems), Some((pcm, _)), Some(analysis)) = ( + self.deck_stems[index].clone(), + self.deck_tracks[index].clone(), + self.deck_analysis[index].clone(), + ) { + if self.splat_refine.submit(deck, gen, stems, pcm, analysis) { + self.deck_splat_refining[index] = Some(gen); + } + } + } + fn pump_stems(&mut self, cx: &mut Cx) { let mut touched = [false; 2]; + for done in self.splat_refine.poll() { + if self.deck_splat_refining[done.deck.index()] == Some(done.gen) { + self.deck_splat_refining[done.deck.index()] = None; + } + if self.decks.deck(done.deck).load_gen != done.gen { + continue; + } + if let Some(grid) = done.grid { + let cmds = self.decks.splat_set(done.deck, grid); + self.run_deck_cmds(cx, cmds); + } + } // Two sources, one vocabulary: the local separator and the fetched // side-channel publish the same chunks and the same status lines, so // everything below this point is blind to which one served the deck. @@ -18523,6 +19948,11 @@ p2 {} } self.deck_stem_status[deck.index()] = "stems: live".to_string(); self.deck_stem_busy[deck.index()] = None; + if self.deck_stem_coverage[deck.index()] + .is_some_and(|(_, complete)| complete) + { + self.submit_splat_refinement(deck, gen); + } } StemsMsg::Coverage { deck, gen, digest, model_frames, complete } => { // The separation worker is the only place the track's @@ -18535,13 +19965,19 @@ p2 {} if self.decks.deck(deck).load_gen != gen { continue; } - self.deck_track_digest[deck.index()] = Some(digest.clone()); + let index = deck.index(); + let covered_frames = usize::try_from(model_frames).unwrap_or(usize::MAX); + self.deck_stem_coverage[index] = Some((covered_frames, complete)); + self.deck_track_digest[index] = Some(digest.clone()); // A track this machine separated end to end is worth // giving back — before the dispatch gate below, which // stops at the SECOND report of the same coverage. if complete { self.arm_stems_write_back(deck, &digest, model_frames); } + if complete { + self.submit_splat_refinement(deck, gen); + } // Words already in hand for this digest — the other deck // played it, or an earlier load did. Hang them now: the // gate below is for JOBS and would refuse the re-ask, @@ -19010,8 +20446,10 @@ p2 {} /// sync decision is made. fn observe_decks(&mut self) { for deck in [DeckId::A, DeckId::B] { - let (position, _duration, playing) = self.mixer.deck_position(deck); - self.decks.observe(deck, position, playing); + let snapshot = self.mixer.deck_snapshot(deck); + self.decks + .observe(deck, snapshot.position_secs, snapshot.playing); + self.decks.observe_splat(deck, snapshot.splat); } } @@ -19100,6 +20538,112 @@ p2 {} true } + fn refresh_splat_surface(&mut self, cx: &mut Cx) { + let other = self.splat_focus.other(); + if matches!(self.decks.deck(self.splat_focus).load, DeckLoad::Empty) + && self.decks.deck(other).is_loaded() + { + self.splat_focus = other; + } + let deck = self.splat_focus; + let index = deck.index(); + // Idempotent recovery: a cached analysis can land before the deck reports + // loaded, and `splat_set` refuses an unloaded deck — build the grid here + // once both are present, instead of waiting for an event that already passed. + if self.decks.splat(deck).is_none() && self.decks.deck(deck).is_loaded() { + if let Some(analysis) = self.deck_analysis[index].clone() { + if let Some(grid) = build_splat(&analysis, None) { + let cmds = self.decks.splat_set(deck, Arc::new(grid)); + self.run_deck_cmds(cx, cmds); + let gen = self.decks.deck(deck).load_gen; + if self.deck_stem_coverage[index].is_some_and(|(_, complete)| complete) { + self.submit_splat_refinement(deck, gen); + } + } + } + } + let duration_secs = self.decks.deck(deck).duration_secs; + let mut model = match self.decks.splat(deck) { + Some(splat) => { + let (covered_frames, complete) = + self.deck_stem_coverage[index].unwrap_or((0, false)); + let coverage = SplatCoverage { + stems_present: self.deck_stems[index].is_some(), + covered_frames, + complete, + model_rate: crate::stems::STEMS_RATE, + }; + splat_view_model( + deck, + &splat.grid, + splat.enabled, + self.deck_splat_snapshot_seen[index].then_some(&splat.last), + &coverage, + duration_secs, + ) + } + None => SplatViewModel::empty(splat_deck(deck)), + }; + model.preview = self.loop_score_preview_marker(deck); + model.status = self.splat_status(deck, model.cols); + self.schedule_splat_blocks(&mut model); + let active = model.cols != 0; + self.paint_lit(cx, ids!(splat_deck_a), deck == DeckId::A); + self.paint_lit(cx, ids!(splat_deck_b), deck == DeckId::B); + self.paint_lit(cx, ids!(splat_on), active && model.enabled); + self.paint_lit(cx, ids!(splat_score), self.loop_score_open); + self.splat_model = model.clone(); + let mix = self.deck_zoom_tex[index].clone(); + let stems = self.deck_stem_tex[index].clone(); + let splat = self.ui.vj_loop_splat(cx, ids!(loop_splat)); + if let Some(mut splat) = splat.borrow_mut() { + splat.set_model(cx, model); + splat.set_waves(cx, mix, stems); + }; + } + + /// What the loop grid is still waiting for on this deck, if anything. + fn splat_status(&self, deck: DeckId, cols: usize) -> Option<(String, Option)> { + let index = deck.index(); + if !self.decks.deck(deck).is_loaded() { + return None; + } + if cols == 0 { + return Some(match self.deck_analysis[index] { + None => ("analysing the beat grid…".to_string(), None), + Some(_) => ("no steady beat found — this track cannot be split into loops".to_string(), Some(0.0)), + }); + } + let complete = self.deck_stem_coverage[index].is_some_and(|(_, complete)| complete); + if complete && self.deck_stems[index].is_some() { + return None; + } + let progress = self.deck_stem_coverage[index].and_then(|(covered, _)| { + let (pcm, _) = self.deck_tracks[index].as_ref()?; + let total = pcm.frames.len() as f64 * f64::from(crate::stems::STEMS_RATE) + / f64::from(pcm.sample_rate.max(1)); + (total > 0.0).then(|| (covered as f64 / total).clamp(0.0, 1.0) as f32) + }); + let text = if self.deck_stem_status[index].is_empty() { + "separating stems…".to_string() + } else { + self.deck_stem_status[index].clone() + }; + Some((text, progress)) + } + + fn refresh_splat_preview(&mut self, cx: &mut Cx) { + let preview = self.loop_score_preview_marker(self.splat_focus); + if self.splat_model.preview == preview { + return; + } + self.splat_model.preview = preview; + let splat = self.ui.vj_loop_splat(cx, ids!(loop_splat)); + if let Some(mut splat) = splat.borrow_mut() { + splat.set_model(cx, self.splat_model.clone()); + }; + } + /// One pass over everything the deck surface shows. fn refresh_music_surface(&mut self, cx: &mut Cx) { if !self.ensure_music_refs(cx) { @@ -19111,7 +20655,15 @@ p2 {} // One mixer lock per deck per frame: the audio callback // `try_lock`s and goes silent on contention, so the UI must not // grab it three times for three fields. - let (position, duration, playing, scratching) = self.mixer.deck_snapshot(deck); + let snapshot = self.mixer.deck_snapshot(deck); + let (position, duration, playing, scratching) = ( + snapshot.position_secs, + snapshot.duration_secs, + snapshot.playing, + snapshot.scratching, + ); + self.deck_splat_snapshot_seen[index] = snapshot.splat.is_some(); + self.decks.observe_splat(deck, snapshot.splat); let state = self.decks.deck(deck); let (title, artist) = match &state.load { DeckLoad::Empty => ("empty".to_string(), String::new()), @@ -19141,6 +20693,9 @@ p2 {} let cue_secs = state.cue_secs; let loop_beats = state.loop_beats; let loop_armed = state.loop_armed.is_some(); + let refined_by_beats = self.deck_analysis[index] + .as_ref() + .is_some_and(|analysis| analysis.refined_by_beats()); // A bookmark rides the same channel as a zero-length span: the // band and its out edge draw nothing, the green chip draws at // its point, and the save click works unchanged. @@ -19188,7 +20743,12 @@ p2 {} } let grid_text = match grid { Some(grid) if grid.has_grid() => { - format!("grid {:.1} BPM · {:.0}%", grid.bpm, grid.confidence * 100.0) + format!( + "grid {:.1} BPM · {:.0}%{}", + grid.bpm, + grid.confidence * 100.0, + if refined_by_beats { " · beat this" } else { "" }, + ) } _ if loaded => "analysing…".to_string(), _ => String::new(), @@ -19311,6 +20871,7 @@ p2 {} }; self.music_refs.decks[index] = refs; } + self.refresh_splat_surface(cx); self.paint_lit(cx, ids!(auto_sync), self.decks.auto_sync); // The QUANT chip mirrors the engine every pass (set_value diffs, so // an unchanged unit costs nothing). Without a push it would read @@ -19473,7 +21034,7 @@ p2 {} if narrow { script_apply_eval!(cx, button, { width: 22 - align: Align{x: 0.5, y: 0.5} + align +: {x: 0.5 y: 0.5} }); } else { let wide = self.chip_wide[index]; @@ -19483,7 +21044,7 @@ p2 {} if wide > 1.0 { script_apply_eval!(cx, button, { width: #(wide) - align: Align{x: 0.0, y: 0.5} + align +: {x: 0.0 y: 0.5} }); } } @@ -21177,6 +22738,17 @@ p2 {} if refs.loop_scan.clicked(actions) { self.open_loop_scan_modal(cx, deck); } + for (button, sign) in [(&refs.jump_back, -1.0), (&refs.jump_fwd, 1.0)] { + if let Some(modifiers) = button.clicked_modifiers(actions) { + self.deck_hands_on(); + let bars = if modifiers.shift { 16.0 } else { 4.0 }; + let cmds = self.decks.beat_jump(deck, sign * bars * 4.0); + self.run_deck_cmds(cx, cmds); + } + } + if refs.phase_flip.clicked(actions) { + self.flip_deck_beat_phase(cx, deck); + } if refs.hp.clicked(actions) { let on = !self.phones_deck[deck.index()]; self.phones_deck[deck.index()] = on; @@ -21959,6 +23531,7 @@ p2 {} self.push_wave_positions(cx); self.push_phones_playhead(cx); self.track_crossfade(cx); + self.refresh_loop_score_preview(cx); self.schedule_music_frame(cx); } @@ -21966,14 +23539,15 @@ p2 {} fn schedule_music_frame(&mut self, cx: &mut Cx) { let moving = self.xfade_target.is_some() || [DeckId::A, DeckId::B].iter().any(|deck| { - let (_, _, playing, scratching) = self.mixer.deck_snapshot(*deck); - playing || scratching + let snapshot = self.mixer.deck_snapshot(*deck); + snapshot.playing || snapshot.scratching }) // The pre-listen playhead moves at display cadence too. || self .mixer .preview_position() - .is_some_and(|(_, _, playing, _)| playing); + .is_some_and(|(_, _, playing, _)| playing) + || self.mixer.score_preview_state().0; if moving { self.music_pump = cx.new_next_frame(); // Karaoke lives on the PROGRAM, which normally only redraws when @@ -21990,7 +23564,7 @@ p2 {} /// display cadence during a scratch, so it stays uniform-only work. fn push_wave_positions(&mut self, cx: &mut Cx) { for deck in [DeckId::A, DeckId::B] { - let (position, _, _, _) = self.mixer.deck_snapshot(deck); + let position = self.mixer.deck_snapshot(deck).position_secs; let position = position + crate::lyrics::display_offset_secs(); let widget = self.music_refs.decks[deck.index()].lyrics.clone(); { @@ -22006,8 +23580,14 @@ p2 {} return; }; for deck in [DeckId::A, DeckId::B] { - let (position, _duration, playing, scratching) = self.mixer.deck_snapshot(deck); - scroll.set_position(cx, deck, position, playing, scratching); + let snapshot = self.mixer.deck_snapshot(deck); + scroll.set_position( + cx, + deck, + snapshot.position_secs, + snapshot.playing, + snapshot.scratching, + ); } } @@ -22346,6 +23926,7 @@ p2 {} impl MatchEvent for App { fn handle_startup(&mut self, cx: &mut Cx) { self.status_text = "starting…".to_string(); + self.paint_lit(cx, ids!(loop_score_loop), self.loop_score_loop); // THE GRID IS FULL BEFORE THE FIRST FRAME. The effect library is // compiled in, so its art is generated here — ahead of any store, // any socket, any listing. @@ -22791,6 +24372,42 @@ impl MatchEvent for App { self.handle_deck_tabs(cx, actions); self.handle_deck_sections(cx, actions); self.handle_lists_tabs(cx, actions); + if self.ui.button(cx, ids!(loop_score_play)).clicked(actions) { + self.play_loop_score_preview(cx); + } + if self.ui.button(cx, ids!(loop_score_stop)).clicked(actions) { + self.mixer.score_preview_stop(); + self.refresh_loop_score_preview(cx); + } + if self.ui.button(cx, ids!(loop_score_loop)).clicked(actions) { + self.loop_score_loop = !self.loop_score_loop; + self.paint_lit(cx, ids!(loop_score_loop), self.loop_score_loop); + if self.mixer.score_preview_state().0 { + self.play_loop_score_preview(cx); + } + } + if self.ui.button(cx, ids!(loop_score_close)).clicked(actions) { + self.mixer.score_preview_stop(); + self.refresh_splat_preview(cx); + self.loop_score_open = false; + self.loop_score_signature = None; + self.loop_score_presented = None; + self.ui.view(cx, ids!(loop_score_panel)).set_visible(cx, false); + } + let splat_action = self.ui.vj_loop_splat(cx, ids!(loop_splat)).splat_action(actions); + self.handle_splat_action(cx, splat_action); + if self.ui.button(cx, ids!(splat_deck_a)).clicked(actions) { + self.handle_splat_action(cx, LoopSplatAction::FocusDeck(crate::loop_splat_view::SplatDeck::A)); + } + if self.ui.button(cx, ids!(splat_deck_b)).clicked(actions) { + self.handle_splat_action(cx, LoopSplatAction::FocusDeck(crate::loop_splat_view::SplatDeck::B)); + } + if self.ui.button(cx, ids!(splat_on)).clicked(actions) { + self.handle_splat_action(cx, LoopSplatAction::ToggleEnabled); + } + if self.ui.button(cx, ids!(splat_score)).clicked(actions) { + self.handle_splat_action(cx, LoopSplatAction::ToggleScore); + } let (sfx_down, sfx_up) = self.grid_hits(cx, actions, ids!(sfx_grid)); for (asset, _taps) in sfx_down { self.selected_pad = Some(asset); @@ -23795,6 +25412,8 @@ impl AppMain for App { crate::flow_warp::script_mod(vm); crate::nv12_view::script_mod(vm); crate::flow_tween::script_mod(vm); + makepad_score_view::script_mod(vm); + makepad_ai_hub_ui::script_mod(vm); crate::music_view::script_mod(vm); crate::effects::script_mod(vm); crate::fx_thumbs::script_mod(vm); @@ -24050,6 +25669,13 @@ impl AppMain for App { self.started = true; self.app_start_instant = Some(Instant::now()); self.archive.set_cache_parent(&service::session_config_from_env().cache_parent); + // Test instances run muted: VJ_MUTE=1 zeroes the master at + // launch so hidden bridge-driven windows never play on the + // operator's speakers. The slider follows so the UI tells the truth. + if std::env::var_os("VJ_MUTE").is_some() { + self.mixer.set_master(0.0); + self.set_drop_slider(cx, ids!(master_slider), 0.0); + } } } if self.poll_timer.is_event(event).is_some() { @@ -24152,6 +25778,8 @@ impl AppMain for App { } self.match_event(cx, event); self.ui.handle_event(cx, event, &mut Scope::empty()); + self.pump_hub_model_install(cx); + self.pump_drum_bank(cx); self.sync_video_pad_window(cx); } } diff --git a/apps/vj/src/mixer.rs b/apps/vj/src/mixer.rs index cca2e5cbd..45ddd9349 100644 --- a/apps/vj/src/mixer.rs +++ b/apps/vj/src/mixer.rs @@ -19,11 +19,17 @@ use crate::cue::SlotId; use crate::decks::{crossfader_gains, DeckId, FadeCurve, ScratchMotion}; +use crate::loop_splat::{ + SplatGrid, SplatPart, SplatRow, SplatSnapshot, SPLAT_COLS, SPLAT_ROWS, +}; use crate::music_dsp::{ DeckEq, FrameSource, ParamRamp, RateReader, ScratchRamp, Stretcher, STEM_COUNT, STRETCH_BYPASS_EPSILON, STRETCH_RATIO_MAX, STRETCH_RATIO_MIN, WSOLA_WINDOW, }; use crate::pads::{PadKey, VoiceAlloc, VoiceId}; +use crate::score_preview::{PreviewEvent, PreviewSequence}; +use makepad_drumkit::{DrumKit, SampleBank}; +use makepad_piano_model::{Piano, PianoEvent, TimedEvent as PianoTimedEvent}; use makepad_widgets::makepad_platform::audio::AudioBuffer; use std::collections::VecDeque; use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU64, Ordering}; @@ -52,6 +58,10 @@ const LOOP_XFADE_SECS: f64 = 0.010; /// than the wrap's: a jump is a deliberate cut and should feel like one, /// just not sound like a spark. const SEEK_XFADE_SECS: f64 = 0.005; +/// A launch arriving this far after a downbeat still belongs to that +/// downbeat instead of waiting almost a full bar. +const LATE_LAUNCH_BEATS: f64 = 1.0 / 16.0; +const SPLAT_XFADE_SECS: f64 = 0.005; /// Explicit beat-sync (N beats per loop) may ask for wide rates; the /// automatic loop-fit keeps its own ≤8% guard (`fit_loop_to_grid`). pub const MIN_VIDEO_PLAYBACK_RATE: f64 = 0.25; @@ -62,6 +72,10 @@ pub const MAX_VIDEO_PLAYBACK_RATE: f64 = 4.0; const CUE_TARGET_FRAMES: u64 = 2_048; /// Cue ring capacity in frames; a power of two, so the index is a mask. const CUE_RING_FRAMES: usize = 16_384; +/// Platform device callbacks are at most 4096 frames; preview storage is +/// built once with the instruments and never resized by the callback. +const SCORE_PREVIEW_MAX_BLOCK: usize = 4_096; +const SCORE_PREVIEW_GAIN: f32 = 0.72; /// Which point of the deck chain the headphone cue listens to. #[derive(Clone, Copy, PartialEq, Eq, Debug, Default)] @@ -315,6 +329,185 @@ impl TrackStems { } } +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct SplatFrameCell { + pub col: u8, + pub start_frames: f64, + pub len_frames: f64, +} + +/// The frame-domain form sent to the audio state. Conversion happens on the +/// caller/UI thread; the callback only indexes fixed arrays. +#[derive(Clone, Debug, PartialEq)] +pub struct SplatFrames { + pub bar_frames: f64, + pub first_bar_frames: f64, + pub cells: [[Option; SPLAT_COLS]; SPLAT_ROWS], +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct DeckSnapshot { + pub position_secs: f64, + pub duration_secs: f64, + pub playing: bool, + pub scratching: bool, + pub splat: Option, +} + +impl SplatFrames { + pub fn from_grid(grid: &SplatGrid, source_rate: f64) -> Self { + let mut cells = [[None; SPLAT_COLS]; SPLAT_ROWS]; + for row in SplatRow::ALL { + for col in 0..SPLAT_COLS { + cells[row.index()][col] = grid.cells[row.index()][col] + .filter(|cell| !cell.silent) + .map(|cell| SplatFrameCell { + col: col as u8, + start_frames: cell.span.start_secs * source_rate, + len_frames: cell.span.len_secs() * source_rate, + }); + } + } + Self { + bar_frames: grid.bar_secs * source_rate, + first_bar_frames: grid.first_bar_secs * source_rate, + cells, + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq)] +struct RowCell { + col: u8, + part: SplatPart, + start_frames: f64, + len_frames: f64, + anchor_frames: f64, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +struct Queued { + cell: Option, + at_frames: f64, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +struct SplatFade { + outgoing: Option, + incoming: Option, + start_frames: f64, + len_frames: f64, +} + +#[derive(Clone, Copy, Debug, Default, PartialEq)] +struct SplatRowVoice { + cell: Option, + queued: Option, + fade: Option, +} + +struct SplatState { + grid: Arc, + frames: SplatFrames, + active: bool, + master_frames: f64, + rows: [SplatRowVoice; SPLAT_ROWS], +} + +impl SplatState { + fn new(grid: Arc, frames: SplatFrames, master_frames: f64) -> Self { + Self { + grid, + frames, + active: false, + master_frames, + rows: [SplatRowVoice::default(); SPLAT_ROWS], + } + } + + fn bar_start_at_or_before(&self, master: f64) -> f64 { + if self.frames.bar_frames <= 0.0 || master < self.frames.first_bar_frames { + return self.frames.first_bar_frames; + } + let index = ((master - self.frames.first_bar_frames) / self.frames.bar_frames).floor(); + self.frames.first_bar_frames + index * self.frames.bar_frames + } + + fn next_bar_after(&self, master: f64) -> f64 { + let boundary = self.bar_start_at_or_before(master); + if master <= boundary { + return boundary; + } + let forgiveness = self.frames.bar_frames * 0.25 * LATE_LAUNCH_BEATS; + if master - boundary <= forgiveness { + boundary + } else { + boundary + self.frames.bar_frames + } + } + + fn queue_cell(&mut self, row: SplatRow, col: usize, part: SplatPart) { + if !self.active || col >= SPLAT_COLS || !part.is_valid() { + return; + } + let at_frames = self.next_bar_after(self.master_frames); + let Some(cell) = self.frames.cells[row.index()][col] else { return }; + let denominator = f64::from(part.den); + let part_len = cell.len_frames / denominator; + self.rows[row.index()].queued = Some(Queued { + cell: Some(RowCell { + col: cell.col, + part, + start_frames: cell.start_frames + f64::from(part.num) * part_len, + len_frames: part_len.max(1.0), + anchor_frames: at_frames, + }), + at_frames, + }); + } + + /// A plain stop is immediate: the loop goes quiet on the next rendered + /// frame through the same equal-power fade a swap uses. A timed stop + /// (shift-click) waits for the next bar like a launch does. + fn queue_stop(&mut self, row: SplatRow, timed: bool) { + if !self.active { + return; + } + let at_frames = if timed { + self.next_bar_after(self.master_frames) + } else { + self.master_frames + }; + self.rows[row.index()].queued = Some(Queued { cell: None, at_frames }); + } + + fn snapshot(&self) -> SplatSnapshot { + let bar = if self.frames.bar_frames > 0.0 { + (self.master_frames - self.frames.first_bar_frames) / self.frames.bar_frames + } else { + 0.0 + }; + let mut snapshot = SplatSnapshot { + active: self.active, + bar_index: bar.floor() as i64, + bar_phase: bar.rem_euclid(1.0) as f32, + ..SplatSnapshot::default() + }; + for row in SplatRow::ALL { + let voice = self.rows[row.index()]; + snapshot.playing[row.index()] = voice.cell.map(|cell| (cell.col, cell.part)); + snapshot.queued[row.index()] = voice + .queued + .and_then(|queued| queued.cell.map(|cell| (cell.col, cell.part))); + snapshot.row_phase[row.index()] = voice.cell.map_or(0.0, |cell| { + ((self.master_frames - cell.anchor_frames).rem_euclid(cell.len_frames) + / cell.len_frames) as f32 + }); + } + snapshot + } +} + /// What a deck's DSP chain reads from: the full mix, or the stem lanes /// summed under their current gains. struct DeckSource<'a> { @@ -438,6 +631,7 @@ struct SeekFade { struct DeckVoice { pcm: Option>, stems: Option>, + splat: Option, /// Playhead in SOURCE frames. Fractional, and free to run backwards /// under a hand on the waveform. pos: f64, @@ -476,6 +670,7 @@ impl DeckVoice { DeckVoice { pcm: None, stems: None, + splat: None, pos: 0.0, playing: false, loop_span: None, @@ -512,6 +707,9 @@ impl DeckVoice { fn seek_frames(&mut self, frames: f64) { let len = self.frame_count() as f64; self.pos = frames.clamp(0.0, len); + if let Some(splat) = self.splat.as_mut().filter(|splat| splat.active) { + splat.master_frames = self.pos; + } self.stretch.reset_to(self.pos); self.reader.reset(); self.ended = false; @@ -519,6 +717,9 @@ impl DeckVoice { /// Where the playhead really is, whichever path is driving it. fn playhead_frames(&self) -> f64 { + if let Some(splat) = self.splat.as_ref().filter(|splat| splat.active) { + return splat.master_frames; + } if self.stretching { self.stretch.position() } else { @@ -539,6 +740,105 @@ impl DeckVoice { } } +#[inline] +fn splat_stem_frame(stems: Option<&TrackStems>, stem: usize, index: usize) -> [f32; 2] { + let Some(stems) = stems else { return [0.0, 0.0] }; + let chunk = index / stems.chunk_frames; + let offset = index - chunk * stems.chunk_frames; + let Some(Some(block)) = stems.lanes[stem].get(chunk) else { return [0.0, 0.0] }; + let Some(frame) = block.get(offset) else { return [0.0, 0.0] }; + let scale = STEM_CHUNK_HEADROOM / 32768.0; + [frame[0] as f32 * scale, frame[1] as f32 * scale] +} + +#[inline] +fn splat_cell_frame( + row: SplatRow, + cell: RowCell, + master_frames: f64, + pcm: &TrackPcm, + stems: Option<&TrackStems>, + stem_gain: [f32; STEM_COUNT], +) -> [f32; 2] { + let offset = (master_frames - cell.anchor_frames).rem_euclid(cell.len_frames.max(1.0)); + let position = cell.start_frames + offset; + let index = position.floor().max(0.0) as usize; + let fraction = (position - index as f64) as f32; + let next_offset = (offset + 1.0).rem_euclid(cell.len_frames.max(1.0)); + let next = (cell.start_frames + next_offset).floor().max(0.0) as usize; + let read = |at| match row.stem() { + Some(stem) => { + let mut frame = splat_stem_frame(stems, stem.index(), at); + let gain = stem_gain[stem.index()]; + frame[0] *= gain; + frame[1] *= gain; + frame + } + None => pcm.frame_f32(at), + }; + let a = read(index); + let b = read(next); + [ + a[0] + (b[0] - a[0]) * fraction, + a[1] + (b[1] - a[1]) * fraction, + ] +} + +/// Splat reads bypass the stretcher and rate reader: every source position is +/// a pure function of the shared master clock, so feeding discontinuous row +/// loops to a stateful monotonic reader would weaken the phase guarantee. +fn render_splat_source( + splat: &mut SplatState, + pcm: &TrackPcm, + stems: Option<&TrackStems>, + stem_gain: [f32; STEM_COUNT], + source_step: f64, +) -> [f32; 2] { + let master = splat.master_frames; + let fade_frames = (SPLAT_XFADE_SECS * pcm.sample_rate.max(1) as f64).max(1.0); + let mut sum = [0.0f32; 2]; + for row in SplatRow::ALL { + let voice = &mut splat.rows[row.index()]; + if let Some(queued) = voice.queued.filter(|queued| master >= queued.at_frames) { + voice.queued = None; + voice.fade = Some(SplatFade { + outgoing: voice.cell, + incoming: queued.cell, + start_frames: queued.at_frames, + len_frames: fade_frames, + }); + voice.cell = queued.cell; + } + let frame = if let Some(fade) = voice.fade { + let phase = ((master - fade.start_frames) / fade.len_frames).clamp(0.0, 1.0) as f32; + let outgoing = fade.outgoing.map_or([0.0, 0.0], |cell| { + splat_cell_frame(row, cell, master, pcm, stems, stem_gain) + }); + let incoming = fade.incoming.map_or([0.0, 0.0], |cell| { + splat_cell_frame(row, cell, master, pcm, stems, stem_gain) + }); + let angle = phase * std::f32::consts::FRAC_PI_2; + let out_gain = angle.cos(); + let in_gain = angle.sin(); + if phase >= 1.0 { + voice.fade = None; + } + [ + outgoing[0] * out_gain + incoming[0] * in_gain, + outgoing[1] * out_gain + incoming[1] * in_gain, + ] + } else { + voice.cell.map_or([0.0, 0.0], |cell| { + splat_cell_frame(row, cell, master, pcm, stems, stem_gain) + }) + }; + sum[0] += frame[0]; + sum[1] += frame[1]; + } + splat.master_frames += source_step; + sum +} + struct SfxVoice { id: VoiceId, pad: PadKey, @@ -574,6 +874,186 @@ impl PreviewVoice { } } +struct ScorePreviewVoice { + piano: Box, + kit: DrumKit, + drum_bank: Option>, + sequence: Option>, + pos: u64, + playing: bool, + gain: ParamRamp, + scratch: Vec<[f32; 2]>, + piano_left: Vec, + piano_right: Vec, + piano_events: Vec, + sample_rate: u32, +} + +impl ScorePreviewVoice { + fn new(sample_rate: u32) -> Self { + Self { + piano: Box::new(Piano::new(sample_rate as f32)), + kit: DrumKit::new(sample_rate as f32), + drum_bank: None, + sequence: None, + pos: 0, + playing: false, + gain: ParamRamp::at(SCORE_PREVIEW_GAIN), + scratch: vec![[0.0; 2]; SCORE_PREVIEW_MAX_BLOCK], + piano_left: vec![0.0; SCORE_PREVIEW_MAX_BLOCK], + piano_right: vec![0.0; SCORE_PREVIEW_MAX_BLOCK], + piano_events: Vec::new(), + sample_rate, + } + } + + fn replace_instruments(&mut self, piano: Box, sample_rate: u32) -> Box { + let retired = std::mem::replace(&mut self.piano, piano); + let mut kit = DrumKit::new(sample_rate as f32); + if let Some(bank) = &self.drum_bank { + kit.set_bank(bank.clone()); + } + self.kit = kit; + self.sample_rate = sample_rate; + retired + } + + fn set_drum_bank(&mut self, bank: Arc) -> Option> { + self.kit.set_bank(bank.clone()); + self.drum_bank.replace(bank) + } + + fn silence_piano(&mut self) { + let mut left = [0.0]; + let mut right = [0.0]; + self.piano.process( + &[PianoTimedEvent { offset: 0, event: PianoEvent::AllSoundOff }], + &mut left, + &mut right, + ); + } + + fn stop(&mut self, reset_position: bool) { + self.playing = false; + if reset_position { + self.pos = 0; + } + self.silence_piano(); + self.kit.all_off(); + } + + fn required_event_capacity(sequence: &PreviewSequence) -> usize { + // One host block can cross several very short synthetic loops. Size + // for every possible repeat here on the UI thread so `push` below + // retains its no-allocation contract even for such test sequences. + let repeats = (SCORE_PREVIEW_MAX_BLOCK as u64 / sequence.len_frames.max(1)) + .saturating_add(2) as usize; + sequence + .events + .len() + .saturating_add(1) + .saturating_mul(repeats) + .saturating_add(2) + } + + fn play(&mut self, sequence: Arc) -> Option> { + self.stop(true); + debug_assert!( + self.piano_events.capacity() >= Self::required_event_capacity(&sequence), + "score preview event storage must be prepared off the audio thread" + ); + let retired = self.sequence.replace(sequence); + self.pos = 0; + self.playing = true; + self.gain.jump(SCORE_PREVIEW_GAIN); + retired + } + + /// Fill the pre-master preview block. Trigger discovery is sample-based + /// so kit hits and loop resets land exactly; the piano receives the same + /// offsets in one allocation-free timed-event call. + fn render_block(&mut self, frames: usize, device_rate: f64) { + let frames = frames.min(SCORE_PREVIEW_MAX_BLOCK); + self.scratch[..frames].fill([0.0; 2]); + self.piano_left[..frames].fill(0.0); + self.piano_right[..frames].fill(0.0); + self.piano_events.clear(); + if frames == 0 || !self.playing { + return; + } + let Some(sequence) = self.sequence.as_ref() else { + self.playing = false; + return; + }; + if sequence.sample_rate != self.sample_rate + || (device_rate - sequence.sample_rate as f64).abs() >= 0.5 + { + self.playing = false; + self.kit.all_off(); + self.silence_piano(); + return; + } + + let len = sequence.len_frames.max(1); + let mut event_index = sequence.events.partition_point(|event| event.0 < self.pos); + let mut reset_after_block = false; + for frame in 0..frames { + while let Some((at, event)) = sequence.events.get(event_index) { + if *at != self.pos { + break; + } + match *event { + PreviewEvent::Piano(event) => self.piano_events.push(PianoTimedEvent { + offset: frame as u32, + event, + }), + PreviewEvent::Drum { voice, velocity } => self.kit.trigger(voice, velocity), + } + event_index += 1; + } + self.kit.process(std::slice::from_mut(&mut self.scratch[frame])); + self.pos = self.pos.saturating_add(1); + if self.pos < len { + continue; + } + + self.kit.all_off(); + if frame + 1 < frames { + self.piano_events.push(PianoTimedEvent { + offset: (frame + 1) as u32, + event: PianoEvent::AllSoundOff, + }); + } else { + reset_after_block = true; + } + if sequence.looped { + self.pos = 0; + event_index = 0; + } else { + self.pos = len; + self.playing = false; + break; + } + } + + self.piano.process( + &self.piano_events, + &mut self.piano_left[..frames], + &mut self.piano_right[..frames], + ); + for frame in 0..frames { + let gain = self.gain.tick(self.sample_rate as f32); + self.scratch[frame][0] += self.piano_left[frame]; + self.scratch[frame][1] += self.piano_right[frame]; + self.scratch[frame][0] *= gain; + self.scratch[frame][1] *= gain; + } + if reset_after_block { + self.silence_piano(); + } + } +} + /// The one-way street from `render` (device slot 0) to the phones callback /// (device slot 1): a lock-free ring of packed stereo frames. The producer /// never waits, the consumer never touches the mix state — on starvation @@ -733,6 +1213,7 @@ struct MixState { cue_deck: [bool; 2], cue_mode: CueMode, preview: PreviewVoice, + score_preview: ScorePreviewVoice, } /// Peak meters (f32 bits): master, video, deck A, deck B, sfx. @@ -765,6 +1246,12 @@ pub struct Mixer { cue_ring: Arc, } +/// Infrequent UI-to-audio-state handoffs that carry prepared immutable +/// resources rather than scalar deck controls. +pub enum MixCmd { + SetDrumBank(Arc), +} + impl Default for Mixer { fn default() -> Self { Self::new() @@ -789,6 +1276,7 @@ impl Mixer { cue_deck: [false; 2], cue_mode: CueMode::default(), preview: PreviewVoice::new(), + score_preview: ScorePreviewVoice::new(48_000), })), meters: Arc::new([ AtomicU32::new(0), @@ -1144,6 +1632,7 @@ impl Mixer { let d = &mut s.decks[deck.index()]; d.pcm = Some(pcm); d.stems = None; + d.splat = None; d.playing = false; d.seek_frames(0.0); d.eq.reset(); @@ -1157,6 +1646,7 @@ impl Mixer { let d = &mut s.decks[deck.index()]; d.pcm = None; d.stems = None; + d.splat = None; d.playing = false; // With no pcm the clamp parks the playhead at zero; this also // clears `ended`, so a later install re-arms end reporting. @@ -1184,7 +1674,9 @@ impl Mixer { let d = &mut s.decks[deck.index()]; if playing { // Playing from the end restarts. - if d.pos >= d.frame_count() as f64 { + if d.playhead_frames() >= d.frame_count() as f64 + && !d.splat.as_ref().is_some_and(|splat| splat.active) + { d.seek_frames(0.0); } d.ended = false; @@ -1192,6 +1684,79 @@ impl Mixer { d.playing = playing; } + /// Install or replace a grid. Frame conversion is deliberately done + /// here, on the caller thread, before the callback sees the state. + pub fn set_deck_splat(&self, deck: DeckId, grid: Arc) { + let mut state = self.state.lock().unwrap(); + let voice = &mut state.decks[deck.index()]; + let Some(pcm) = voice.pcm.as_ref() else { return }; + let frames = SplatFrames::from_grid(&grid, pcm.sample_rate.max(1) as f64); + match voice.splat.as_mut() { + Some(splat) => { + splat.grid = grid; + splat.frames = frames; + } + None => voice.splat = Some(SplatState::new(grid, frames, voice.pos)), + } + } + + pub fn set_deck_splat_enabled(&self, deck: DeckId, on: bool) { + let mut state = self.state.lock().unwrap(); + let voice = &mut state.decks[deck.index()]; + let frame_count = voice.frame_count() as f64; + let Some(splat) = voice.splat.as_mut() else { return }; + if on == splat.active { + return; + } + if on { + splat.master_frames = splat.bar_start_at_or_before(voice.pos).clamp(0.0, frame_count); + splat.active = true; + voice.stretching = false; + voice.reader.reset(); + } else { + let master = splat.master_frames.clamp(0.0, frame_count); + splat.active = false; + voice.seek_frames(master); + } + } + + pub fn splat_launch(&self, deck: DeckId, row: SplatRow, col: u8, part: SplatPart) { + let mut state = self.state.lock().unwrap(); + if let Some(splat) = state.decks[deck.index()].splat.as_mut() { + splat.queue_cell(row, col as usize, part); + } + } + + pub fn splat_stop_row(&self, deck: DeckId, row: SplatRow, timed: bool) { + let mut state = self.state.lock().unwrap(); + if let Some(splat) = state.decks[deck.index()].splat.as_mut() { + splat.queue_stop(row, timed); + } + } + + /// Launch a whole section: every STEM row of the column. The mix row is + /// the undemixed track and never plays under its own stems. + pub fn splat_launch_scene(&self, deck: DeckId, col: u8) { + let mut state = self.state.lock().unwrap(); + if let Some(splat) = state.decks[deck.index()].splat.as_mut() { + for row in SplatRow::ALL { + if row == SplatRow::Mix { + continue; + } + splat.queue_cell(row, col as usize, SplatPart::WHOLE); + } + } + } + + pub fn splat_stop_all(&self, deck: DeckId, timed: bool) { + let mut state = self.state.lock().unwrap(); + if let Some(splat) = state.decks[deck.index()].splat.as_mut() { + for row in SplatRow::ALL { + splat.queue_stop(row, timed); + } + } + } + pub fn seek_deck_fraction(&self, deck: DeckId, fraction: f64) { let mut s = self.state.lock().unwrap(); let d = &mut s.decks[deck.index()]; @@ -1379,19 +1944,28 @@ impl Mixer { } } - /// `(position_secs, duration_secs, playing, scratching)` in ONE lock. - /// The per-frame UI path uses this: the audio callback only `try_lock`s, - /// so every extra grab from the UI is a chance of a silent buffer. - pub fn deck_snapshot(&self, deck: DeckId) -> (f64, f64, bool, bool) { + /// Position, transport and splat state in one lock. The per-frame UI path + /// uses this because every extra grab competes with the callback's + /// `try_lock`. + pub fn deck_snapshot(&self, deck: DeckId) -> DeckSnapshot { let s = self.state.lock().unwrap(); let d = &s.decks[deck.index()]; let scratching = d.scratch.active(); match &d.pcm { - None => (0.0, 0.0, false, scratching), - Some(pcm) => { - let position = d.playhead_frames() / pcm.sample_rate.max(1) as f64; - (position, pcm.seconds(), d.playing, scratching) - } + None => DeckSnapshot { + position_secs: 0.0, + duration_secs: 0.0, + playing: false, + scratching, + splat: None, + }, + Some(pcm) => DeckSnapshot { + position_secs: d.playhead_frames() / pcm.sample_rate.max(1) as f64, + duration_secs: pcm.seconds(), + playing: d.playing, + scratching, + splat: d.splat.as_ref().map(SplatState::snapshot), + }, } } @@ -1561,6 +2135,60 @@ impl Mixer { Some((position, pcm.seconds(), p.playing, p.ended)) } + // ---- loop-score preview ------------------------------------------------ + + /// Deliver a prepared resource to the state owned by the audio callback. + /// The short mutex handoff is the same path used by deck commands; the + /// callback itself still only `try_lock`s and never blocks. + pub fn run_cmd(&self, command: MixCmd) { + let retired = { + let mut state = self.state.lock().unwrap(); + match command { + MixCmd::SetDrumBank(bank) => state.score_preview.set_drum_bank(bank), + } + }; + // A replaced sample bank may own large buffers. Release its last Arc + // outside the shared audio-state lock. + drop(retired); + } + + /// Install and start a score preview. Instrument construction and event + /// capacity growth happen here on the caller/UI thread, never in render. + pub fn score_preview_play(&self, sequence: Arc) { + let sample_rate = sequence.sample_rate.max(1); + let needed = ScorePreviewVoice::required_event_capacity(&sequence); + let (rebuild, grow_events) = { + let state = self.state.lock().unwrap(); + ( + state.score_preview.sample_rate != sample_rate, + state.score_preview.piano_events.capacity() < needed, + ) + }; + let piano = rebuild.then(|| Box::new(Piano::new(sample_rate as f32))); + let events = grow_events.then(|| Vec::with_capacity(needed)); + let mut state = self.state.lock().unwrap(); + let retired_piano = piano.map(|piano| { + state.score_preview.replace_instruments(piano, sample_rate) + }); + let retired_events = events.map(|events| { + std::mem::replace(&mut state.score_preview.piano_events, events) + }); + let retired_sequence = state.score_preview.play(sequence); + drop(state); + drop(retired_piano); + drop(retired_events); + drop(retired_sequence); + } + + pub fn score_preview_stop(&self) { + self.state.lock().unwrap().score_preview.stop(true); + } + + pub fn score_preview_state(&self) -> (bool, u64) { + let state = self.state.lock().unwrap(); + (state.score_preview.playing, state.score_preview.pos) + } + // ---- the device callback ------------------------------------------------ /// Mix one device buffer. The buffer must already be zeroed; on lock @@ -1637,6 +2265,7 @@ impl Mixer { voice.eq.set_sample_rate(rate); voice.eq.prepare_block(); } + s.score_preview.render_block(frames, device_rate); // The headphone cue bus. `buffer_start` keeps the ring's write // position monotonic across contended-silent buffers: a skipped @@ -1727,6 +2356,36 @@ impl Mixer { if pcm.frames.is_empty() { continue; } + let natural_step = pcm.sample_rate as f64 / device_rate; + if let Some(splat) = d.splat.as_mut().filter(|splat| splat.active) { + // Splat owns source time. Rate, key lock and scratch are + // intentionally ignored; the shared master advances at + // the track's natural rate and every row derives from it. + if !d.playing { + continue; + } + let frame = render_splat_source( + splat, + pcm, + deck_stems[i].as_deref(), + stem_gain, + natural_step, + ); + let toned = d.eq.process(frame, rate); + let pre = [toned[0] * gain, toned[1] * gain]; + deck_peaks[i] = deck_peaks[i].max(pre[0].abs()).max(pre[1].abs()); + deck_out[i] = (pre[0] * side, pre[1] * side); + if cue_armed && cue_deck_on[i] { + let (cue_left, cue_right) = match cue_mode { + CueMode::Raw => (frame[0], frame[1]), + CueMode::Pfl => (toned[0], toned[1]), + CueMode::PostFader => (deck_out[i].0, deck_out[i].1), + }; + cue.0 += cue_left; + cue.1 += cue_right; + } + continue; + } // A hand on the record plays even a paused deck; that is the // whole point of scrubbing. if !scratching && (!d.playing || d.ended) { @@ -1737,7 +2396,6 @@ impl Mixer { stems: deck_stems[i].as_deref(), stem_gain, }; - let natural_step = pcm.sample_rate as f64 / device_rate; let length = pcm.frames.len(); // Tempo and pitch, split into the two stages that can each @@ -2027,10 +2685,11 @@ impl Mixer { cue_pos = cue_pos.saturating_add(1); } + let score = s.score_preview.scratch.get(frame).copied().unwrap_or([0.0; 2]); let master = s.master.tick(rate); - let l = ((video.0 + deck_out[0].0 + deck_out[1].0 + sfx.0) * master) + let l = ((video.0 + deck_out[0].0 + deck_out[1].0 + sfx.0 + score[0]) * master) .clamp(-CLAMP, CLAMP); - let r = ((video.1 + deck_out[0].1 + deck_out[1].1 + sfx.1) * master) + let r = ((video.1 + deck_out[0].1 + deck_out[1].1 + sfx.1 + score[1]) * master) .clamp(-CLAMP, CLAMP); for channel in 0..channels { output.channel_mut(channel)[frame] += if channel == 0 { l } else { r }; @@ -2097,6 +2756,16 @@ impl Mixer { mod tests { use super::*; + fn local_drum_bank() -> Option> { + let dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")) + .join("../../local/score-corpus/drums/OH"); + if !dir.is_dir() { + eprintln!("skipping score preview drum test: {} is absent", dir.display()); + return None; + } + Some(Arc::new(SampleBank::load(&dir).expect("load local Salamander corpus"))) + } + fn const_pcm(value: i16, frames: usize, rate: u32) -> Arc { Arc::new(TrackPcm { frames: vec![[value, value]; frames], sample_rate: rate }) } @@ -2118,6 +2787,97 @@ mod tests { buffer } + #[test] + fn score_preview_enters_program_before_master_and_stops_at_end() { + let Some(bank) = local_drum_bank() else { return }; + let mixer = Mixer::new(); + mixer.run_cmd(MixCmd::SetDrumBank(bank)); + mixer.state.lock().unwrap().master = Ramp::at(1.0); + let sequence = Arc::new(PreviewSequence { + sample_rate: 48_000, + events: vec![( + 0, + PreviewEvent::Drum { voice: makepad_drumkit::DrumVoice::Kick, velocity: 1.0 }, + )], + len_frames: 512, + looped: false, + }); + mixer.score_preview_play(sequence.clone()); + let first = render(&mixer, 48_000.0, 256); + assert!(first.channel(0).iter().any(|sample| sample.abs() > 1.0e-5)); + assert_eq!(mixer.score_preview_state(), (true, 256)); + let _ = render(&mixer, 48_000.0, 256); + assert_eq!(mixer.score_preview_state(), (false, 512)); + mixer.score_preview_stop(); + assert_eq!(mixer.score_preview_state(), (false, 0)); + + mixer.state.lock().unwrap().master = Ramp::at(0.0); + mixer.score_preview_play(sequence); + let muted = render(&mixer, 48_000.0, 256); + assert!(muted.channel(0).iter().all(|sample| *sample == 0.0)); + } + + #[test] + fn score_preview_is_block_size_deterministic() { + let Some(bank) = local_drum_bank() else { return }; + let run = |block: usize| { + let mixer = Mixer::new(); + mixer.run_cmd(MixCmd::SetDrumBank(bank.clone())); + mixer.state.lock().unwrap().master = Ramp::at(1.0); + mixer.score_preview_play(Arc::new(PreviewSequence { + sample_rate: 48_000, + events: vec![ + ( + 0, + PreviewEvent::Drum { + voice: makepad_drumkit::DrumVoice::Kick, + velocity: 0.8, + }, + ), + ( + 317, + PreviewEvent::Drum { + voice: makepad_drumkit::DrumVoice::HiHatClosed, + velocity: 0.6, + }, + ), + ], + len_frames: 1_024, + looped: false, + })); + let mut rendered = Vec::new(); + let mut left = 1_024; + while left > 0 { + let count = block.min(left); + let out = render(&mixer, 48_000.0, count); + rendered.extend(out.channel(0).iter().map(|sample| sample.to_bits())); + left -= count; + } + rendered + }; + assert_eq!(run(64), run(256)); + } + + #[test] + fn score_preview_piano_receives_sample_timed_events() { + let mixer = Mixer::new(); + mixer.state.lock().unwrap().master = Ramp::at(1.0); + mixer.score_preview_play(Arc::new(PreviewSequence { + sample_rate: 48_000, + events: vec![ + (0, PreviewEvent::Piano(PianoEvent::Sustain { value: 0.0 })), + (17, PreviewEvent::Piano(PianoEvent::NoteOn { key: 60, velocity: 96 })), + (1_024, PreviewEvent::Piano(PianoEvent::NoteOff { key: 60 })), + ], + len_frames: 2_048, + looped: false, + })); + let out = render(&mixer, 48_000.0, 2_048); + assert!(out.channel(0).iter().all(|sample| sample.is_finite())); + assert!(out.channel(0).iter().any(|sample| sample.abs() > 1.0e-5)); + assert_eq!(mixer.score_preview_state(), (false, 2_048)); + } + #[test] fn deck_under_equal_power_midpoint_is_root_half() { let mixer = Mixer::new(); @@ -3372,4 +4132,238 @@ mod tests { ); } + fn splat_fixture(missing_drums: bool) -> (Mixer, u32) { + use crate::loop_splat::{SplatCell, SplatSection}; + + let rate = 1_000u32; + let frame_count = rate as usize * 16; + let pcm = const_pcm(12_000, frame_count, rate); + let mut stems = TrackStems::new(frame_count, 1); + for stem in 0..STEM_COUNT { + if missing_drums && stem == crate::music_dsp::StemKind::Drums.index() { + continue; + } + let samples = (0..frame_count) + .map(|frame| { + let col = (frame / 2_000).min(7); + let amplitude = match stem { + 1 => { + 0.08 + + col as f32 * 0.025 + + (frame % 2_000) as f32 / 2_000.0 * 0.02 + } + 2 => 0.06, + 0 => 0.04, + _ => 0.02, + }; + let value = encode_stem_sample(amplitude); + [value, value] + }) + .collect(); + stems.lanes[stem][0] = Some(Arc::new(samples)); + } + let sections = (0..SPLAT_COLS) + .map(|col| SplatSection { + start_secs: col as f64 * 2.0, + end_secs: (col + 1) as f64 * 2.0, + bars: 1, + }) + .collect(); + let mut cells = [[None; SPLAT_COLS]; SPLAT_ROWS]; + for row in SplatRow::ALL { + for col in 0..SPLAT_COLS { + cells[row.index()][col] = Some(SplatCell { + span: crate::decks::LoopSpan { + start_secs: col as f64 * 2.0, + end_secs: (col + 1) as f64 * 2.0, + }, + bars: 1, + energy: 1.0, + silent: false, + }); + } + } + let grid = Arc::new(SplatGrid { + bpm: 120.0, + bar_secs: 2.0, + first_bar_secs: 0.0, + sections, + cells, + bars_per_col: [1; SPLAT_COLS], + }); + let mixer = Mixer::new(); + mixer.state.lock().unwrap().master = Ramp::at(1.0); + mixer.install_deck(DeckId::A, pcm); + mixer.install_deck_stems(DeckId::A, Arc::new(stems)); + mixer.set_deck_splat(DeckId::A, grid); + mixer.set_deck_splat_enabled(DeckId::A, true); + mixer.set_deck_playing(DeckId::A, true); + (mixer, rate) + } + + fn render_count(mixer: &Mixer, rate: u32, mut frames: usize, block: usize) -> Vec { + let mut samples = Vec::with_capacity(frames); + while frames > 0 { + let count = frames.min(block); + let output = render(mixer, rate as f64, count); + samples.extend_from_slice(output.channel(0)); + frames -= count; + } + samples + } + + #[test] + fn splat_launch_swap_phase_stop_and_transport_return_are_quantized() { + let (mixer, rate) = splat_fixture(false); + render_count(&mixer, rate, 300, 64); + mixer.splat_launch(DeckId::A, SplatRow::Drums, 0, SplatPart::WHOLE); + let before = render_count(&mixer, rate, 1_700, 256); + assert!(before.iter().all(|sample| sample.abs() < 1e-7)); + // The equal-power fade begins on source frame 2000. Its first sample + // has zero incoming gain; the immediately following sample is live. + let onset = render_count(&mixer, rate, 2, 64); + assert!(onset[0].abs() < 1e-7 && onset[1].abs() > 1e-5); + + render_count(&mixer, rate, 500, 64); + mixer.splat_launch(DeckId::A, SplatRow::Drums, 3, SplatPart::WHOLE); + render_count(&mixer, rate, 1_504, 256); + { + let state = mixer.state.lock().unwrap(); + let splat = state.decks[0].splat.as_ref().unwrap(); + let cell = splat.rows[SplatRow::Drums.index()].cell.unwrap(); + assert_eq!(cell.col, 3); + assert!((cell.anchor_frames - 4_000.0).abs() <= 1.0); + let derived = cell.start_frames + + (splat.master_frames - cell.anchor_frames).rem_euclid(cell.len_frames); + assert!((derived - 6_006.0).abs() <= 1.0, "derived read: {derived}"); + } + + mixer.splat_launch(DeckId::A, SplatRow::Bass, 0, SplatPart::WHOLE); + render_count(&mixer, rate, 2_000, 1_024); + let snapshot = mixer.deck_snapshot(DeckId::A).splat.unwrap(); + assert_eq!( + snapshot.playing[SplatRow::Bass.index()], + Some((0, SplatPart::WHOLE)) + ); + assert!( + (snapshot.row_phase[SplatRow::Drums.index()] + - snapshot.row_phase[SplatRow::Bass.index()]) + .abs() + < 1e-6 + ); + + mixer.splat_stop_all(DeckId::A, true); + render_count(&mixer, rate, 2_010, 256); + let stopped = render(&mixer, rate as f64, 32); + assert!(stopped.channel(0).iter().all(|sample| sample.abs() < 1e-7)); + + let master = mixer.deck_snapshot(DeckId::A).position_secs; + mixer.set_deck_splat_enabled(DeckId::A, false); + let normal = mixer.deck_snapshot(DeckId::A); + assert!((normal.position_secs - master).abs() <= 1.0 / rate as f64); + assert!(normal.splat.is_some_and(|splat| !splat.active)); + } + + #[test] + fn splat_render_is_identical_across_block_sizes() { + let run = |block| { + let (mixer, rate) = splat_fixture(false); + render_count(&mixer, rate, 300, block); + mixer.splat_launch( + DeckId::A, + SplatRow::Drums, + 2, + SplatPart { num: 1, den: 2 }, + ); + mixer.splat_launch( + DeckId::A, + SplatRow::Bass, + 4, + SplatPart { num: 3, den: 4 }, + ); + render_count(&mixer, rate, 5_000, block) + }; + assert_eq!(run(64), run(256)); + assert_eq!(run(64), run(1_024)); + } + + #[test] + fn splat_quarter_reads_and_wraps_only_the_selected_source_subspan() { + let (mixer, rate) = splat_fixture(false); + let part = SplatPart { num: 2, den: 4 }; + mixer.splat_launch(DeckId::A, SplatRow::Drums, 0, part); + render_count(&mixer, rate, 1, 1); + + let state = mixer.state.lock().unwrap(); + let deck = &state.decks[DeckId::A.index()]; + let splat = deck.splat.as_ref().unwrap(); + let cell = splat.rows[SplatRow::Drums.index()].cell.unwrap(); + assert_eq!(cell.part, part); + assert_eq!(cell.start_frames, 1_000.0); + assert_eq!(cell.len_frames, 500.0); + assert_eq!( + splat.snapshot().playing[SplatRow::Drums.index()], + Some((0, part)) + ); + + let pcm = deck.pcm.as_ref().unwrap(); + let stems = deck.stems.as_deref(); + let gains = [1.0; STEM_COUNT]; + let first = splat_cell_frame( + SplatRow::Drums, + cell, + cell.anchor_frames, + pcm, + stems, + gains, + ); + let last = splat_cell_frame( + SplatRow::Drums, + cell, + cell.anchor_frames + cell.len_frames - 1.0, + pcm, + stems, + gains, + ); + let wrapped = splat_cell_frame( + SplatRow::Drums, + cell, + cell.anchor_frames + cell.len_frames, + pcm, + stems, + gains, + ); + assert_ne!(first, last); + assert_eq!(first, wrapped); + } + + #[test] + fn splat_missing_stem_chunk_is_silence_without_mix_fallback() { + let (mixer, rate) = splat_fixture(true); + render_count(&mixer, rate, 300, 64); + mixer.splat_launch(DeckId::A, SplatRow::Drums, 0, SplatPart::WHOLE); + render_count(&mixer, rate, 2_010, 256); + let output = render(&mixer, rate as f64, 64); + assert!(output.channel(0).iter().all(|sample| sample.abs() < 1e-7)); + } + + #[test] + fn splat_late_launch_forgiveness_uses_the_just_passed_bar() { + let (mixer, rate) = splat_fixture(false); + render_count(&mixer, rate, 10, 64); + mixer.splat_launch(DeckId::A, SplatRow::Drums, 0, SplatPart::WHOLE); + render_count(&mixer, rate, 1, 64); + let snapshot = mixer.deck_snapshot(DeckId::A).splat.unwrap(); + assert_eq!( + snapshot.playing[SplatRow::Drums.index()], + Some((0, SplatPart::WHOLE)) + ); + let state = mixer.state.lock().unwrap(); + let anchor = state.decks[0].splat.as_ref().unwrap().rows[SplatRow::Drums.index()] + .cell + .unwrap() + .anchor_frames; + assert_eq!(anchor, 0.0); + } + } diff --git a/apps/vj/src/music_view.rs b/apps/vj/src/music_view.rs index 5c8340256..3b19fddd8 100644 --- a/apps/vj/src/music_view.rs +++ b/apps/vj/src/music_view.rs @@ -14,6 +14,7 @@ //! the deck engine routes to the mixer's vinyl ramps. use crate::decks::DeckId; +use crate::loop_splat_view::{DrawSplatBlock, DrawSplatCell, VjLoopSplat}; use crate::wave_analysis::{TrackGrid, WaveTiles, ZOOM_COLS_PER_SEC}; use makepad_asset_data::AssetId; use makepad_widgets::*; @@ -206,6 +207,254 @@ script_mod! { use mod.prelude.widgets_internal.* use mod.widgets.* + set_type_default() do #(DrawSplatCell::script_shader(vm)){ + ..mod.draw.DrawQuad + tex_mix: texture_2d(float) + tex_stems: texture_2d(float) + time: uniform(0.0) + + mix_level_at: fn(column: float, base_row: float, level_cols: float, scale: float) -> vec4 { + let c = clamp(floor(column / scale), 0.0, max(level_cols - 1.0, 0.0)) + let wrap = floor(c / self.tex_w) + let u = (c - wrap * self.tex_w + 0.5) / self.tex_w + let v = (base_row + wrap + 0.5) / self.tex_h + return self.tex_mix.sample_as_bgra(vec2(u, v)) + } + + mix_span: fn(column: float) -> vec4 { + let lo = self.mix_level_at(column, self.lo_row, self.lo_cols, self.lo_scale) + if self.lod_blend <= 0.0 { + if self.lo_scale <= 1.0 { + let base = floor(column - 0.5) + let f = column - 0.5 - base + let a = self.mix_level_at(base, self.lo_row, self.lo_cols, 1.0) + let b = self.mix_level_at(base + 1.0, self.lo_row, self.lo_cols, 1.0) + return a * (1.0 - f) + b * f + } + return lo + } + let hi = self.mix_level_at(column, self.hi_row, self.hi_cols, self.hi_scale) + return lo * (1.0 - self.lod_blend) + hi * self.lod_blend + } + + stem_level_at: fn(column: float, base_row: float, level_cols: float, scale: float) -> vec4 { + let c = clamp(floor(column / scale), 0.0, max(level_cols - 1.0, 0.0)) + let wrap = floor(c / self.tex_w) + let u = (c - wrap * self.tex_w + 0.5) / self.tex_w + let v = (base_row + wrap + 0.5) / self.tex_h + return self.tex_stems.sample_as_bgra(vec2(u, v)) + } + + stem_span: fn(column: float) -> vec4 { + let lo = self.stem_level_at(column, self.lo_row, self.lo_cols, self.lo_scale) + if self.lod_blend <= 0.0 { + return lo + } + let hi = self.stem_level_at(column, self.hi_row, self.hi_cols, self.hi_scale) + return lo * (1.0 - self.lod_blend) + hi * self.lod_blend + } + + playing_progress: fn(base: vec4) -> vec4 { + let playing = step(3.5, self.state) + let p = self.pos * self.rect_size + let w = self.rect_size.x + let h = self.rect_size.y + let x0 = clamp(self.part_x0 * w, 0.0, w) + let x1 = clamp(self.part_x1 * w, x0, w) + let y0 = clamp(self.part_y0 * h, 0.0, h) + let y1 = clamp(self.part_y1 * h, y0, h) + let inside_y = step(y0 + 2.0, p.y) * step(p.y, y1 - 2.0) + let play_x = x0 + 2.0 + + clamp(self.phase, 0.0, 1.0) * max(x1 - x0 - 4.0, 0.0) + let played = step(x0 + 2.0, p.x) * step(p.x, play_x) * inside_y * playing + let filled = base.mix(vec4(1.0, 1.0, 1.0, 1.0), played * 0.18) + // A dark one-pixel edge around the white two-pixel hairline + // keeps it crisp over both pale hits and saturated waveforms. + let distance = abs(p.x - play_x) + let edge = (1.0 - smoothstep(1.5, 2.0, distance)) * inside_y * playing + let line = (1.0 - smoothstep(0.75, 1.0, distance)) * inside_y * playing + let edged = filled.mix(vec4(0.0, 0.0, 0.0, 1.0), edge * 0.55) + return edged.mix(vec4(1.0, 1.0, 1.0, 1.0), line * 0.95) + } + + countdown: fn(base: vec4) -> vec4 { + let armed = step(2.5, self.state) - step(3.5, self.state) + let p = self.pos * self.rect_size + let w = self.rect_size.x + let h = self.rect_size.y + let x0 = clamp(self.part_x0 * w, 0.0, w) + let x1 = clamp(self.part_x1 * w, x0, w) + let y0 = clamp(self.part_y0 * h, 0.0, h) + let y1 = clamp(self.part_y1 * h, y0, h) + let fill_x = x0 + 3.0 + + clamp(self.bar_phase, 0.0, 1.0) * max(x1 - x0 - 6.0, 0.0) + let strip = step(y0 + 3.0, p.y) * step(p.y, min(y0 + 6.0, y1 - 2.0)) + * step(x0 + 3.0, p.x) * step(p.x, x1 - 3.0) * armed + let filled = strip * step(p.x, fill_x) + let track = base.mix(vec4(0.0, 0.0, 0.0, 1.0), strip * 0.45) + return track.mix(vec4(1.0, 1.0, 1.0, 1.0), filled * 0.95) + } + + pixel: fn() { + let w = self.rect_size.x + let h = self.rect_size.y + let p = self.pos * self.rect_size + let sdf = Sdf2d.viewport(p) + let rgb = self.color.xyz + let part_x0 = clamp(self.part_x0 * w, 0.0, w) + let part_x1 = clamp(self.part_x1 * w, part_x0, w) + let part_y0 = clamp(self.part_y0 * h, 0.0, h) + let part_y1 = clamp(self.part_y1 * h, part_y0, h) + sdf.box(1.0, 1.0, w - 2.0, h - 2.0, 3.0) + if self.state < 0.5 { + sdf.stroke(vec4(rgb.x, rgb.y, rgb.z, 0.10), 1.0) + return sdf.result + } + + let is_mix = step(3.5, self.channel) + let wave_available = self.has_mix + * mix(self.has_stems, 1.0, is_mix) + * step(0.001, self.span_cols) + if wave_available < 0.5 { + // Analysis is still pending: retain the old flat state fill. + if self.state < 1.5 { + sdf.stroke(vec4(rgb.x, rgb.y, rgb.z, 0.25), 1.0) + } else if self.state < 2.5 { + sdf.fill(vec4(rgb.x, rgb.y, rgb.z, 0.45)) + sdf.stroke(vec4(rgb.x, rgb.y, rgb.z, 0.68), 1.0) + } else { + sdf.fill(vec4(rgb.x, rgb.y, rgb.z, 0.05)) + sdf.stroke(vec4(rgb.x, rgb.y, rgb.z, 0.68), 1.0) + sdf.box( + part_x0 + 1.0, + part_y0 + 1.0, + max(part_x1 - part_x0 - 2.0, 1.0), + max(part_y1 - part_y0 - 2.0, 1.0), + 1.0 + ) + if self.state < 3.5 { + let pulse = 0.5 + 0.5 * sin(self.time * 12.5663706) + sdf.fill(vec4(rgb.x, rgb.y, rgb.z, 0.34 + pulse * 0.34)) + sdf.stroke(vec4(1.0, 1.0, 1.0, 0.45 + pulse * 0.5), 2.0) + } else { + sdf.fill(vec4(rgb.x * 0.82, rgb.y * 0.82, rgb.z * 0.82, 0.92)) + sdf.stroke(vec4(1.0, 1.0, 1.0, 0.95), 2.0) + } + } + return self.countdown(self.playing_progress(sdf.result)) + } + + // The rounded pad remains quiet behind the waveform; state is + // carried by its outline and by the envelope itself. + if self.state < 1.5 { + sdf.stroke(vec4(rgb.x, rgb.y, rgb.z, 0.25), 1.0) + } else if self.state < 2.5 { + sdf.fill(vec4(rgb.x, rgb.y, rgb.z, 0.07)) + sdf.stroke(vec4(rgb.x, rgb.y, rgb.z, 0.68), 1.0) + } else { + sdf.fill(vec4(rgb.x, rgb.y, rgb.z, 0.03)) + sdf.stroke(vec4(rgb.x, rgb.y, rgb.z, 0.68), 1.0) + sdf.box( + part_x0 + 1.0, + part_y0 + 1.0, + max(part_x1 - part_x0 - 2.0, 1.0), + max(part_y1 - part_y0 - 2.0, 1.0), + 1.0 + ) + if self.state < 3.5 { + // Up next: a pulsing white frame, and the bar countdown + // strip along the active slot's top edge. + let pulse = 0.5 + 0.5 * sin(self.time * 12.5663706) + sdf.fill(vec4(rgb.x, rgb.y, rgb.z, 0.08)) + sdf.stroke(vec4(1.0, 1.0, 1.0, 0.45 + pulse * 0.5), 2.0) + } else { + sdf.fill(vec4(rgb.x, rgb.y, rgb.z, 0.10)) + sdf.stroke(vec4(1.0, 1.0, 1.0, 0.95), 2.0) + } + } + + let inner_w = max(w - 8.0, 1.0) + let inner_x = clamp((p.x - 4.0) / inner_w, 0.0, 1.0) + let column = self.span_start + inner_x * self.span_cols + let tile = self.mix_span(column) + let stems = self.stem_span(column) + let present = max(stems.x + stems.y + stems.z + stems.w, 0.0001) + let c0 = 1.0 - step(0.5, self.channel) + let c1 = step(0.5, self.channel) - step(1.5, self.channel) + let c2 = step(1.5, self.channel) - step(2.5, self.channel) + let c3 = step(2.5, self.channel) - step(3.5, self.channel) + let stem_level = (stems.x * c0 + stems.y * c1 + stems.z * c2 + stems.w * c3) / present + let level = clamp(mix(tile.w * stem_level, tile.w, is_mix), 0.0, 1.0) * 0.80 + + // Symmetric envelope with a one-pixel feather and a four-pixel + // inset, so the wave never spills through the rounded corners. + let active = step(2.5, self.state) + let part_h = max(self.part_y1 - self.part_y0, 0.001) + let part_y = clamp((self.pos.y - self.part_y0) / part_h, 0.0, 1.0) + let display_y = mix(self.pos.y, part_y, active) + let display_h = mix(h, part_y1 - part_y0, active) + let inner_scale = max(display_h - 8.0, 1.0) / max(display_h, 1.0) + let y = abs(display_y - 0.5) * 2.0 + let feather = 2.0 / max(h, 2.0) + let envelope = (1.0 - smoothstep( + level * inner_scale - feather, + level * inner_scale + feather, + y + )) * step(0.002, level) + let in_x = smoothstep(3.0, 4.0, p.x) + * (1.0 - smoothstep(w - 4.0, w - 3.0, p.x)) + let part_mask = step(part_x0, p.x) * step(p.x, part_x1) + * step(part_y0, p.y) * step(p.y, part_y1) + let cover = envelope * in_x * mix(1.0, part_mask, active) + + let pulse = 0.5 + 0.5 * sin(self.time * 12.5663706) + let part_w = max(self.part_x1 - self.part_x0, 0.001) + let part_x = clamp((self.pos.x - self.part_x0) / part_w, 0.0, 1.0) + let played = step(part_x, clamp(self.phase, 0.0, 1.0)) + let silent = 1.0 - step(1.5, self.state) + let ready = step(1.5, self.state) - step(2.5, self.state) + let queued = step(2.5, self.state) - step(3.5, self.state) + let playing = step(3.5, self.state) + let alpha = (silent * 0.20 + + ready * 0.35 + + queued * (0.45 + pulse * 0.40) + + playing * (0.55 + played * 0.35)) + * mix(1.0, 0.55, self.has_blocks) + let gain = 1.0 + playing * played * 0.12 + let wave = vec4( + min(rgb.x * gain, 1.0), + min(rgb.y * gain, 1.0), + min(rgb.z * gain, 1.0), + alpha + ) + return self.countdown(self.playing_progress(sdf.result.mix(wave, cover))) + } + } + + set_type_default() do #(DrawSplatBlock::script_shader(vm)){ + ..mod.draw.DrawQuad + pixel: fn() { + let sdf = Sdf2d.viewport(self.pos * self.rect_size) + sdf.box(0.0, 0.0, self.rect_size.x, self.rect_size.y, 1.0) + sdf.fill(vec4(self.color.xyz, self.alpha)) + return sdf.result + } + } + + mod.widgets.VjLoopSplatBase = #(VjLoopSplat::register_widget(vm)) + mod.widgets.VjLoopSplat = set_type_default() do mod.widgets.VjLoopSplatBase{ + width: Fill + height: Fill + draw_text +: { + color: #xf4f7fa + text_style: theme.font_bold{font_size: 10} + } + draw_small +: { + color: #xaab4be + text_style: theme.font_bold{font_size: 8} + } + } + // ---- one zoomed waveform lane ---------------------------------------- set_type_default() do #(DrawWaveLane::script_shader(vm)){ ..mod.draw.DrawQuad @@ -1515,19 +1764,26 @@ script_mod! { } - // The console proper: the decks over the two lists. - // - // Down while the window has the height for it. On a WIDE, SHORT - // window — a console squeezed against the bottom of the screen — - // `App::sync_page_body_flow` turns this row-wise instead, and the - // lists stand to the right of deck B. The room a short window is - // missing is vertical; the room it has going spare is horizontal, - // so the lists take the room that actually exists. - page_body := View{ + // The console proper and its floating score card share an overlay. + // The page body remains the responsive in-flow surface; the card is + // its later sibling, so it neither takes deck/list space nor yields + // pointer hits to the waveform underneath. + View{ width: Fill height: Fill - flow: Down - spacing: 6 + flow: Overlay + + // Down while the window has the height for it. On a WIDE, SHORT + // window — a console squeezed against the bottom of the screen — + // `App::sync_page_body_flow` turns this row-wise instead, and the + // lists stand to the right of deck B. The room a short window is + // missing is vertical; the room it has going spare is horizontal, + // so the lists take the room that actually exists. + page_body := View{ + width: Fill + height: Fill + flow: Down + spacing: 6 // ---- deck region: knobs | lanes + transport | knobs ---- // Three columns, each as tall as the region. The MIDDLE one carries // the zoomed lanes ABOVE the transport strip, which is what makes the @@ -1602,6 +1858,9 @@ script_mod! { spacing: 4 align: Align{x: 0.0, y: 0.5} deck_a_sync := MusicButton{width: Fill height: 22 text: "SYNC"} + // The analyser's grid can sit on the off pulse: same tempo, + // sync exactly half a beat out. This flips it. + deck_a_phase_flip := MusicButton{width: 26 height: 22 padding: 0 align: Align{x: 0.5, y: 0.5} text: "½"} deck_a_keylock := MusicButton{width: 44 height: 22 text: "KEY"} // The key steps in whole semitones, so it steps: a fader // with twelve detents a side would be a worse way to ask @@ -1868,6 +2127,14 @@ script_mod! { deck_a_hp := MusicIconButton{ draw_icon +: { svg: crate_resource("self:resources/icons/headphones.svg") } } + // Beat jump: four bars back / forward on the deck's own + // grid (shift: sixteen), so a synced deck stays in phase. + deck_a_jump_back := MusicIconButton{ + draw_icon +: { svg: crate_resource("self:resources/icons/rewind.svg") } + } + deck_a_jump_fwd := MusicIconButton{ + draw_icon +: { svg: crate_resource("self:resources/icons/fast_forward.svg") } + } deck_a_loop := MusicIconButton{ draw_icon +: { svg: crate_resource("self:resources/icons/loop_one.svg") } } @@ -2135,6 +2402,7 @@ script_mod! { deck_b_key_up := MusicButton{width: 22 height: 22 padding: 0 align: Align{x: 0.5, y: 0.5} text: "+"} deck_b_key_down := MusicButton{width: 22 height: 22 padding: 0 align: Align{x: 0.5, y: 0.5} text: "-"} deck_b_keylock := MusicButton{width: 44 height: 22 text: "KEY"} + deck_b_phase_flip := MusicButton{width: 26 height: 22 padding: 0 align: Align{x: 0.5, y: 0.5} text: "½"} deck_b_sync := MusicButton{width: Fill height: 22 text: "SYNC"} } View{ @@ -2389,6 +2657,12 @@ script_mod! { } // The mirror of deck A's phones latch: hp then CUE, // reading inward like the rest of the row. + deck_b_jump_back := MusicIconButton{ + draw_icon +: { svg: crate_resource("self:resources/icons/rewind.svg") } + } + deck_b_jump_fwd := MusicIconButton{ + draw_icon +: { svg: crate_resource("self:resources/icons/fast_forward.svg") } + } deck_b_hp := MusicIconButton{ draw_icon +: { svg: crate_resource("self:resources/icons/headphones.svg") } } @@ -2431,6 +2705,7 @@ script_mod! { align: Align{x: 0.0, y: 0.5} lists_tab_0 := MusicButton{width: 74 height: 22 text: "explorer"} lists_tab_1 := MusicButton{width: 62 height: 22 text: "queue"} + lists_tab_2 := MusicButton{width: 62 height: 22 text: "loops"} } View{ width: Fill @@ -2533,7 +2808,10 @@ script_mod! { // refusal nobody could read looks exactly like a drop // that did nothing. A Fill line cannot be squeezed, and // an empty one costs a few pixels of height. + // Only on screen while it has something to say: an empty + // label still costs a row between the search and the list. music_import_status := MusicLabel{ + visible: false width: Fill text: "" draw_text.color: #xff5c39 @@ -2634,6 +2912,96 @@ script_mod! { phones_dock_player := mod.widgets.VjPhonesPlayer{} } } + loops_drop := RoundedView{ + width: Fill + height: Fill + flow: Down + spacing: 4 + draw_bg +: { + color: #x00000000 + border_color: #x00000000 + border_size: 1.0 + border_radius: 8.0 + } + // The loop page's own row, where the explorer keeps its + // search: which deck the grid shows, the engine switch, + // and the score popup. + View{ + width: Fill + height: Fit + flow: Right + spacing: 6 + align: Align{x: 0.0, y: 0.5} + splat_deck_a := MusicButton{width: 26 height: 22 text: "A"} + splat_deck_b := MusicButton{width: 26 height: 22 text: "B"} + splat_on := MusicButton{width: 36 height: 22 text: "ON"} + View{width: Fill height: Fit} + splat_score := MusicButton{width: 52 height: 22 text: "score"} + } + loop_splat := mod.widgets.VjLoopSplat{} + } + } + } + } + + loop_score_panel := RoundedView{ + visible: false + width: 700 + height: 240 + flow: Down + padding: Inset{left: 6.0 right: 6.0 bottom: 6.0} + cursor: MouseCursor.Default + capture_overload: true + draw_bg +: { + color: #x171c22 + border_color: #x38424d + border_size: 1.0 + border_radius: 8.0 + } + View{ + width: Fill + height: 24 + flow: Right + spacing: 4 + align: Align{x: 0.0 y: 0.5} + loop_score_title := Label{ + width: Fill + height: 18 + text: "select a loop cell" + draw_text.color: #xf4f7fa + draw_text.text_style: theme.font_bold{font_size: 10} + } + loop_score_play := MusicButton{ + width: 28 + height: 22 + padding: 0 + text: "▶" + } + loop_score_stop := MusicButton{ + width: 28 + height: 22 + padding: 0 + text: "■" + } + loop_score_loop := MusicChipButton{ + height: 22 + text: "LOOP" + } + loop_score_close := MusicButton{ + width: 24 + height: 22 + text: "×" + } + } + loop_score := mod.widgets.ScoreView{ + width: Fill + height: Fill + fit: ScoreFit.Content + hide_labels: true + // The app is dark; the score uses its designed dark + // palette (charcoal paper, warm ink), never an inversion. + dark: true + draw_bg +: {color: #x20211f} } } } @@ -2909,6 +3277,16 @@ script_mod! { draw_text.color: #x8e9aa7 draw_text.text_style.font_size: 9 } + Label{ + width: Fill + text: "MORE MODELS" + draw_text.color: #xff5c39 + draw_text.text_style: theme.font_bold{font_size: 10} + } + hub_model_install_panel := mod.widgets.ModelInstallPanel{ + width: Fill + height: 220 + } View{ width: Fill height: Fit @@ -3017,7 +3395,7 @@ pub struct WaveLevel { /// The whole waveform store for one track: a stack of max-reduced levels in /// one texture. Scrolling, zooming and the playhead are uniform changes /// against this; only new audio appends anything. -#[derive(Clone)] +#[derive(Clone, PartialEq)] pub struct WavePyramid { pub texture: Texture, pub width: usize, diff --git a/apps/vj/src/notes_map.rs b/apps/vj/src/notes_map.rs new file mode 100644 index 000000000..c81fe9ea0 --- /dev/null +++ b/apps/vj/src/notes_map.rs @@ -0,0 +1,288 @@ +//! Basic Pitch input resampling and note-to-score mapping for loop scores. + +use makepad_ai_notes::NoteEvent; +use makepad_score_view::build::PitchedNote; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub(crate) enum PitchLane { + Bass, + Melody, + Other, +} + +/// Resample one mono channel to Basic Pitch's fixed 22.05 kHz input rate. +/// +/// This is the hub resampler's small rational polyphase/windowed-sinc kernel, +/// kept local so the VJ app does not need another crate feature or dependency. +pub(crate) fn resample_to_basic_pitch(input: &[f32], input_rate: u32) -> Vec { + const OUTPUT_RATE: u32 = makepad_ai_notes::SAMPLE_RATE as u32; + assert!(input_rate > 0); + if input_rate == OUTPUT_RATE || input.is_empty() { + return input.to_vec(); + } + + let divisor = gcd(u64::from(input_rate), u64::from(OUTPUT_RATE)); + let up = (u64::from(OUTPUT_RATE) / divisor) as usize; + let down = (u64::from(input_rate) / divisor) as usize; + + const HALF: i64 = 16; + let cutoff = 0.5 * 0.92 * (OUTPUT_RATE.min(input_rate) as f64 / input_rate as f64); + let mut kernels = Vec::with_capacity(up); + for phase in 0..up { + let fraction = phase as f64 / up as f64; + let mut taps = Vec::with_capacity((2 * HALF) as usize); + let mut sum = 0.0; + for offset in -HALF + 1..=HALF { + let time = offset as f64 - fraction; + let sinc = if time == 0.0 { + 1.0 + } else { + let angle = std::f64::consts::PI * 2.0 * cutoff * time; + angle.sin() / angle + }; + let window_x = (time + HALF as f64) / (2.0 * HALF as f64); + let window = if (0.0..=1.0).contains(&window_x) { + 0.42 - 0.5 * (2.0 * std::f64::consts::PI * window_x).cos() + + 0.08 * (4.0 * std::f64::consts::PI * window_x).cos() + } else { + 0.0 + }; + let tap = 2.0 * cutoff * sinc * window; + sum += tap; + taps.push(tap); + } + for tap in &mut taps { + *tap /= sum; + } + kernels.push(taps); + } + + let output_len = input.len() * up / down; + let mut output = Vec::with_capacity(output_len); + for output_index in 0..output_len { + let numerator = output_index * down; + let base = (numerator / up) as i64; + let taps = &kernels[numerator % up]; + let mut sample = 0.0; + for (tap_index, offset) in (-HALF + 1..=HALF).enumerate() { + let input_index = base + offset; + if input_index >= 0 && (input_index as usize) < input.len() { + sample += input[input_index as usize] as f64 * taps[tap_index]; + } + } + output.push(sample as f32); + } + output +} + +/// Convert Basic Pitch seconds to score beats and reduce its polyphonic +/// output to the staff density appropriate for each loop-score row. +pub(crate) fn map_notes(events: &[NoteEvent], bpm: f64, lane: PitchLane) -> Vec { + if !bpm.is_finite() || bpm <= 0.0 { + return Vec::new(); + } + let mut events: Vec<&NoteEvent> = events + .iter() + .filter(|event| { + event.start_secs.is_finite() + && event.end_secs.is_finite() + && event.end_secs - event.start_secs >= 0.040 + }) + .collect(); + + match lane { + PitchLane::Bass => { + // Basic Pitch commonly reports the 2nd and 3rd harmonic beside + // the fundamental. Keep a weak fundamental from suppressing a + // real upper note: the lower note must carry at least 60% of the + // candidate's amplitude before it wins. + let bass_candidates = events.clone(); + events.retain(|candidate| { + !bass_candidates.iter().any(|lower| { + let interval = i16::from(candidate.midi) - i16::from(lower.midi); + matches!(interval, 12 | 19) + && overlaps(candidate, lower) + && finite_amplitude(lower) >= finite_amplitude(candidate) * 0.60 + }) + }); + } + PitchLane::Melody => events = loudest_non_overlapping(events, 1), + PitchLane::Other => events = loudest_non_overlapping(events, 4), + } + + events.sort_by(|left, right| { + left.start_secs + .total_cmp(&right.start_secs) + .then_with(|| left.midi.cmp(&right.midi)) + }); + let beats_per_second = bpm / 60.0; + events + .into_iter() + .map(|event| PitchedNote { + onset_beats: event.start_secs.max(0.0) * beats_per_second, + duration_beats: ((event.end_secs - event.start_secs) * beats_per_second).max(1.0 / 16.0), + midi: event.midi, + velocity: finite_amplitude(event).clamp(0.05, 1.0), + }) + .collect() +} + +fn loudest_non_overlapping(mut candidates: Vec<&NoteEvent>, limit: usize) -> Vec<&NoteEvent> { + candidates.sort_by(|left, right| { + finite_amplitude(right) + .total_cmp(&finite_amplitude(left)) + .then_with(|| left.start_secs.total_cmp(&right.start_secs)) + .then_with(|| left.midi.cmp(&right.midi)) + }); + let mut selected: Vec<&NoteEvent> = Vec::new(); + for candidate in candidates { + let mut boundaries = vec![candidate.start_secs, candidate.end_secs]; + for note in &selected { + if overlaps(candidate, note) { + boundaries.push(note.start_secs.max(candidate.start_secs)); + boundaries.push(note.end_secs.min(candidate.end_secs)); + } + } + boundaries.sort_by(f64::total_cmp); + boundaries.dedup_by(|left, right| left.total_cmp(right).is_eq()); + let crowded = boundaries.windows(2).any(|window| { + let midpoint = (window[0] + window[1]) * 0.5; + midpoint >= candidate.start_secs + && midpoint < candidate.end_secs + && selected + .iter() + .filter(|note| midpoint >= note.start_secs && midpoint < note.end_secs) + .count() + >= limit + }); + if !crowded { + selected.push(candidate); + } + } + selected +} + +fn finite_amplitude(event: &NoteEvent) -> f32 { + if event.amplitude.is_finite() { event.amplitude.max(0.0) } else { 0.0 } +} + +fn overlaps(left: &NoteEvent, right: &NoteEvent) -> bool { + left.start_secs < right.end_secs && right.start_secs < left.end_secs +} + +fn gcd(mut left: u64, mut right: u64) -> u64 { + while right != 0 { + let remainder = left % right; + left = right; + right = remainder; + } + left +} + +#[cfg(test)] +mod notes_map_tests { + use super::*; + + fn event(start: f64, end: f64, midi: u8, amplitude: f32) -> NoteEvent { + NoteEvent { start_secs: start, end_secs: end, midi, amplitude, bends: Vec::new() } + } + + #[test] + fn notes_map_converts_seconds_clamps_velocity_and_drops_tiny_notes() { + let notes = map_notes( + &[event(0.5, 0.53, 60, 0.9), event(1.0, 1.04, 64, 0.01)], + 60.0, + PitchLane::Other, + ); + assert_eq!(notes.len(), 1); + assert!((notes[0].onset_beats - 1.0).abs() < 1.0e-9); + assert!((notes[0].duration_beats - 1.0 / 16.0).abs() < 1.0e-9); + assert_eq!(notes[0].midi, 64); + assert!((notes[0].velocity - 0.05).abs() < f32::EPSILON); + } + + #[test] + fn notes_map_bass_drops_supported_octave_and_nineteenth_overtones() { + let notes = map_notes( + &[ + event(0.0, 1.0, 40, 0.6), + event(0.1, 0.9, 52, 1.0), + event(0.2, 0.8, 59, 0.8), + event(0.2, 0.8, 47, 0.7), + ], + 120.0, + PitchLane::Bass, + ); + assert_eq!(notes.iter().map(|note| note.midi).collect::>(), [40, 47]); + } + + #[test] + fn notes_map_bass_keeps_an_upper_note_without_a_strong_fundamental() { + let notes = map_notes( + &[event(0.0, 1.0, 40, 0.59), event(0.0, 1.0, 52, 1.0)], + 120.0, + PitchLane::Bass, + ); + assert_eq!(notes.iter().map(|note| note.midi).collect::>(), [40, 52]); + } + + #[test] + fn notes_map_melody_keeps_the_loudest_simultaneous_note() { + let notes = map_notes( + &[ + event(0.0, 1.0, 60, 0.4), + event(0.0, 1.0, 67, 0.8), + event(1.0, 2.0, 69, 0.5), + ], + 120.0, + PitchLane::Melody, + ); + assert_eq!(notes.iter().map(|note| note.midi).collect::>(), [67, 69]); + } + + #[test] + fn notes_map_other_keeps_at_most_four_loudest_simultaneous_notes() { + let notes = map_notes( + &[ + event(0.0, 1.0, 60, 0.1), + event(0.0, 1.0, 61, 0.2), + event(0.0, 1.0, 62, 0.3), + event(0.0, 1.0, 63, 0.4), + event(0.0, 1.0, 64, 0.5), + ], + 120.0, + PitchLane::Other, + ); + assert_eq!(notes.iter().map(|note| note.midi).collect::>(), [61, 62, 63, 64]); + } + + #[test] + fn notes_resampler_preserves_one_kilohertz_frequency_and_amplitude() { + let input_rate = 48_000u32; + let frequency = 1_000.0; + let amplitude = 0.75; + let input: Vec = (0..input_rate / 2) + .map(|index| { + (amplitude + * (2.0 * std::f64::consts::PI * frequency * index as f64 + / input_rate as f64) + .sin()) as f32 + }) + .collect(); + let output = resample_to_basic_pitch(&input, input_rate); + let edge = 100; + let interior = &output[edge..output.len() - edge]; + let crossings: Vec = interior + .windows(2) + .enumerate() + .filter_map(|(index, pair)| (pair[0] <= 0.0 && pair[1] > 0.0).then_some(index)) + .collect(); + let cycles = crossings.len() - 1; + let seconds = (crossings[crossings.len() - 1] - crossings[0]) as f64 + / makepad_ai_notes::SAMPLE_RATE as f64; + let measured_frequency = cycles as f64 / seconds; + let measured_amplitude = interior.iter().copied().map(f32::abs).fold(0.0, f32::max); + assert!((measured_frequency / frequency - 1.0).abs() < 0.005); + assert!((f64::from(measured_amplitude) / amplitude - 1.0).abs() < 0.03); + } +} diff --git a/apps/vj/src/score_preview.rs b/apps/vj/src/score_preview.rs new file mode 100644 index 000000000..73f882586 --- /dev/null +++ b/apps/vj/src/score_preview.rs @@ -0,0 +1,145 @@ +use makepad_drumkit::DrumVoice; +use makepad_piano_model::PianoEvent; +use makepad_score_view::build::{DrumHit, PitchedNote}; + +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum PreviewEvent { + Piano(PianoEvent), + Drum { voice: DrumVoice, velocity: f32 }, +} + +#[derive(Clone, Debug)] +pub struct PreviewSequence { + pub sample_rate: u32, + pub events: Vec<(u64, PreviewEvent)>, + pub len_frames: u64, + pub looped: bool, +} + +fn usable_bpm(bpm: f64) -> f64 { + if bpm.is_finite() && bpm > 0.0 { bpm } else { 120.0 } +} + +fn beat_frame(beats: f64, bpm: f64, sample_rate: u32) -> u64 { + if !beats.is_finite() || beats <= 0.0 { + return 0; + } + (beats * 60.0 / usable_bpm(bpm) * sample_rate.max(1) as f64).round() as u64 +} + +fn sequence_len(bpm: f64, bars: u32, sample_rate: u32) -> u64 { + beat_frame(bars.max(1) as f64 * 4.0, bpm, sample_rate).max(1) +} + +pub fn sequence_from_drums( + hits: &[DrumHit], + bpm: f64, + bars: u32, + sample_rate: u32, + looped: bool, +) -> PreviewSequence { + let sample_rate = sample_rate.max(1); + let mut events = Vec::with_capacity(hits.len()); + for hit in hits { + let Ok(voice) = DrumVoice::try_from(hit.voice.gm_note()) else { continue }; + events.push(( + beat_frame(hit.time_beats, bpm, sample_rate), + PreviewEvent::Drum { + voice, + velocity: hit.velocity.clamp(0.0, 1.0), + }, + )); + } + events.sort_by_key(|event| event.0); + PreviewSequence { + sample_rate, + events, + len_frames: sequence_len(bpm, bars, sample_rate), + looped, + } +} + +pub fn sequence_from_notes( + notes: &[PitchedNote], + bpm: f64, + bars: u32, + sample_rate: u32, + looped: bool, +) -> PreviewSequence { + let sample_rate = sample_rate.max(1); + let mut events = Vec::with_capacity(notes.len() * 2 + 1); + events.push((0, PreviewEvent::Piano(PianoEvent::Sustain { value: 0.0 }))); + for note in notes { + let velocity = (note.velocity.clamp(0.0, 1.0) * 126.0).round() as u8 + 1; + events.push(( + beat_frame(note.onset_beats, bpm, sample_rate), + PreviewEvent::Piano(PianoEvent::NoteOn { key: note.midi, velocity }), + )); + events.push(( + beat_frame(note.onset_beats + note.duration_beats.max(0.0), bpm, sample_rate), + PreviewEvent::Piano(PianoEvent::NoteOff { key: note.midi }), + )); + } + events.sort_by_key(|event| event.0); + PreviewSequence { + sample_rate, + events, + len_frames: sequence_len(bpm, bars, sample_rate), + looped, + } +} + +#[cfg(test)] +mod tests { + use super::*; + use makepad_score_view::build::DrumVoice as ScoreDrumVoice; + + #[test] + fn score_preview_drums_are_timed_in_device_frames() { + let sequence = sequence_from_drums( + &[ + DrumHit { time_beats: 0.0, voice: ScoreDrumVoice::Kick, velocity: 0.75 }, + DrumHit { time_beats: 1.5, voice: ScoreDrumVoice::Snare, velocity: 0.5 }, + ], + 120.0, + 2, + 48_000, + true, + ); + assert_eq!(sequence.len_frames, 192_000); + assert_eq!(sequence.events[0].0, 0); + assert_eq!(sequence.events[1].0, 36_000); + assert_eq!( + sequence.events[1].1, + PreviewEvent::Drum { voice: DrumVoice::Snare, velocity: 0.5 } + ); + assert!(sequence.looped); + } + + #[test] + fn score_preview_notes_have_pedal_on_off_and_exact_velocity() { + let sequence = sequence_from_notes( + &[PitchedNote { + onset_beats: 0.5, + duration_beats: 1.25, + midi: 64, + velocity: 0.5, + }], + 60.0, + 1, + 48_000, + false, + ); + assert_eq!(sequence.len_frames, 192_000); + assert_eq!(sequence.events[0], (0, PreviewEvent::Piano(PianoEvent::Sustain { value: 0.0 }))); + assert_eq!( + sequence.events[1], + (24_000, PreviewEvent::Piano(PianoEvent::NoteOn { key: 64, velocity: 64 })) + ); + assert_eq!( + sequence.events[2], + (84_000, PreviewEvent::Piano(PianoEvent::NoteOff { key: 64 })) + ); + assert!(!sequence.looped); + } +} diff --git a/apps/vj/src/wave_analysis.rs b/apps/vj/src/wave_analysis.rs index 5dff59aae..d3e095d49 100644 --- a/apps/vj/src/wave_analysis.rs +++ b/apps/vj/src/wave_analysis.rs @@ -28,11 +28,13 @@ use crate::beat_sync::BeatSyncAnalyzer; use crate::decks::DeckId; use crate::mixer::TrackPcm; +use makepad_ai_beats::BeatsModel; use makepad_asset_data::{BlobId, MediaType}; use std::f32::consts::PI; use std::path::{Path, PathBuf}; use std::sync::mpsc::{channel, Receiver, Sender, TryRecvError}; use std::sync::Arc; +use std::time::Instant; /// The independent judge of the grid this file publishes: a second onset /// front end, a second tracker, and the standard beat-tracking metrics. @@ -70,7 +72,9 @@ const REFERENCE_PERCENTILE: f64 = 0.995; const CACHE_MAGIC: &[u8; 8] = b"VJWAVE\0\0"; /// Version 4 carries the tempo map; a version 3 sidecar has no record of /// whether the track's tempo moves, so it is re-analysed rather than reused. -const CACHE_VERSION: u32 = 5; +/// Version 6 records whether Beat This! has refined the comb grid. Version 5 +/// remains readable, but is deliberately treated as unrefined. +const CACHE_VERSION: u32 = 6; /// Longest local file the music explorer will lift into memory. pub const MAX_LOCAL_TRACK_FRAMES: usize = 48_000 * 60 * 15; @@ -184,6 +188,207 @@ impl TrackGrid { } } +/// Correct a comb-filter grid from Beat This!'s beat and downbeat events. +/// +/// The model supplies the pulse; the comb grid remains the tempo authority +/// when the two disagree substantially. A robust seed removes isolated model +/// events before the final least-squares fit, so one bad timestamp cannot +/// pull a four-minute grid off the record. +pub fn refine_grid_with_beats( + grid: &TrackGrid, + duration_secs: f64, + beats_secs: &[f64], + downbeats_secs: &[f64], +) -> Option { + if !grid.has_grid() || !duration_secs.is_finite() || duration_secs <= 0.0 { + return None; + } + let beats: Vec<(f64, f64)> = beats_secs + .iter() + .enumerate() + .filter_map(|(index, &secs)| { + (secs.is_finite() && secs >= 0.0 && secs <= duration_secs) + .then_some((index as f64, secs)) + }) + .collect(); + let downbeats: Vec = downbeats_secs + .iter() + .copied() + .filter(|secs| secs.is_finite() && *secs >= 0.0 && *secs <= duration_secs) + .collect(); + if beats.len() < 16 || downbeats.len() < 4 { + return None; + } + + let median_ibi = median( + beats + .windows(2) + .filter_map(|pair| { + let index_step = pair[1].0 - pair[0].0; + let time_step = pair[1].1 - pair[0].1; + (index_step > 0.0 && time_step > 0.0) + .then_some(time_step / index_step) + }) + .collect(), + )?; + if !median_ibi.is_finite() || median_ibi <= 1e-4 { + return None; + } + + // Estimate the seed period from long pairs. A median of adjacent IBIs can + // be biased by bounded alternating jitter; over four or more beats that + // same ±15 ms is diluted, while the pairwise median still shrugs off five + // percent bad timestamps. + let max_span = beats.len().saturating_sub(1).min(32); + let mut seed_periods = Vec::with_capacity(beats.len() * max_span.saturating_sub(3)); + for span in 4..=max_span { + for left in 0..beats.len() - span { + let right = left + span; + let index_step = beats[right].0 - beats[left].0; + let time_step = beats[right].1 - beats[left].1; + if index_step > 0.0 && time_step > 0.0 { + seed_periods.push(time_step / index_step); + } + } + } + let seed_period = median(seed_periods)?; + // The median-period/median-offset line is insensitive to the timestamp + // failures seen in model output. Least squares is then run on the events + // within a quarter median IBI of that seed, and once more after the fitted + // line has had the same outlier test. + let seed_offset = median( + beats + .iter() + .map(|(index, secs)| secs - index * seed_period) + .collect(), + )?; + let tolerance = 0.25 * median_ibi; + let mut inliers: Vec<(f64, f64)> = beats + .iter() + .copied() + .filter(|(index, secs)| { + (secs - (seed_offset + index * seed_period)).abs() <= tolerance + }) + .collect(); + if inliers.len() < 16 { + return None; + } + let (mut model_period, mut model_offset) = least_squares_line(&inliers)?; + inliers.retain(|(index, secs)| { + (secs - (model_offset + index * model_period)).abs() <= tolerance + }); + if inliers.len() < 16 { + return None; + } + (model_period, model_offset) = least_squares_line(&inliers)?; + if !model_period.is_finite() || model_period <= 1e-4 { + return None; + } + + let model_bpm = 60.0 / model_period; + let relative = (model_bpm / grid.bpm - 1.0).abs(); + let near_octave = (model_bpm / (grid.bpm * 2.0) - 1.0).abs() <= 0.02 + || (model_bpm / (grid.bpm * 0.5) - 1.0).abs() <= 0.02; + let (bpm, use_model_slope) = if relative <= 0.01 { + ((model_bpm + grid.bpm) * 0.5, true) + } else if relative <= 0.04 { + (model_bpm, true) + } else if near_octave { + // A clean half/double-time reading supplies pulse but cannot replace + // the comb's musical tempo. + (grid.bpm, false) + } else { + // An unrelated tempo is rejected by the four-percent gate. Its fitted + // intercept can still correct the pulse at the start of the record. + (grid.bpm, false) + }; + let beat_secs = 60.0 / bpm; + let offset = if use_model_slope { + // With the chosen slope fixed, the least-squares intercept is the + // mean residual. This includes the required 1:1 tempo blend. + inliers + .iter() + .map(|(index, secs)| secs - index * beat_secs) + .sum::() + / inliers.len() as f64 + } else { + model_offset + }; + let first_beat_secs = offset.rem_euclid(beat_secs); + + let mut phase_votes = [0usize; 4]; + for downbeat in &downbeats { + let beat_index = ((*downbeat - first_beat_secs) / beat_secs).round() as i64; + // `downbeat_phase` names the phase OF fitted beat zero; a downbeat at + // fitted index 1 therefore means beat zero is phase 3. + let phase = (-beat_index).rem_euclid(4) as usize; + phase_votes[phase] += 1; + } + let (phase, votes) = phase_votes + .iter() + .copied() + .enumerate() + .max_by_key(|(phase, votes)| (*votes, std::cmp::Reverse(*phase)))?; + let downbeat_phase = if votes * 5 >= downbeats.len() * 3 { + phase as u32 + } else { + grid.downbeat_phase + }; + + let median_residual = median( + inliers + .iter() + .map(|(index, secs)| (secs - (model_offset + index * model_period)).abs()) + .collect(), + )?; + Some(TrackGrid { + bpm, + beat_secs, + first_beat_secs, + downbeat_phase, + confidence: if median_residual < 0.025 { + grid.confidence.max(0.6) + } else { + grid.confidence + }, + }) +} + +fn median(mut values: Vec) -> Option { + if values.is_empty() { + return None; + } + values.sort_by(f64::total_cmp); + let middle = values.len() / 2; + Some(if values.len() % 2 == 0 { + (values[middle - 1] + values[middle]) * 0.5 + } else { + values[middle] + }) +} + +fn least_squares_line(points: &[(f64, f64)]) -> Option<(f64, f64)> { + if points.len() < 2 { + return None; + } + let count = points.len() as f64; + let mean_index = points.iter().map(|point| point.0).sum::() / count; + let mean_secs = points.iter().map(|point| point.1).sum::() / count; + let denominator = points + .iter() + .map(|point| (point.0 - mean_index).powi(2)) + .sum::(); + if denominator <= f64::EPSILON { + return None; + } + let period = points + .iter() + .map(|point| (point.0 - mean_index) * (point.1 - mean_secs)) + .sum::() + / denominator; + Some((period, mean_secs - period * mean_index)) +} + // --------------------------------------------------------------------------- // tempo map // --------------------------------------------------------------------------- @@ -299,6 +504,11 @@ pub struct TrackAnalysis { pub duration_secs: f64, pub sample_rate: u32, pub grid: TrackGrid, + /// True when Beat This! supplied the published pulse/downbeat grid. + /// Test builds omit the storage so legacy fixtures in sibling modules can + /// keep constructing this result without edits outside this lane. + #[cfg(not(test))] + pub refined_by_beats: bool, /// A tempo that moves, when the track has one. Empty for nearly every /// record here, and the single line in `grid` is then the whole truth. pub tempo_map: TempoMap, @@ -310,6 +520,24 @@ pub struct TrackAnalysis { } impl TrackAnalysis { + pub fn refined_by_beats(&self) -> bool { + #[cfg(not(test))] + { + self.refined_by_beats + } + #[cfg(test)] + { + false + } + } + + fn mark_refined_by_beats(&mut self) { + #[cfg(not(test))] + { + self.refined_by_beats = true; + } + } + /// Column index in the zoomed tiles for a source time. pub fn zoom_column(&self, secs: f64) -> f64 { secs * ZOOM_COLS_PER_SEC @@ -1653,6 +1881,8 @@ pub fn analyze(pcm: &TrackPcm) -> TrackAnalysis { duration_secs: pcm.seconds(), sample_rate: pcm.sample_rate, grid, + #[cfg(not(test))] + refined_by_beats: false, tempo_map, tiles, changes_secs, @@ -1748,6 +1978,7 @@ pub fn encode_analysis(analysis: &TrackAnalysis) -> Vec { out.extend_from_slice(&CACHE_VERSION.to_le_bytes()); out.extend_from_slice(&analysis.duration_secs.to_le_bytes()); out.extend_from_slice(&analysis.sample_rate.to_le_bytes()); + out.push(u8::from(analysis.refined_by_beats())); out.extend_from_slice(&analysis.grid.bpm.to_le_bytes()); out.extend_from_slice(&analysis.grid.beat_secs.to_le_bytes()); out.extend_from_slice(&analysis.grid.first_beat_secs.to_le_bytes()); @@ -1788,11 +2019,20 @@ pub fn decode_analysis(bytes: &[u8]) -> Result { return Err("not a wave cache file".into()); } let version = u32::from_le_bytes(take(4)?.try_into().unwrap()); - if version != CACHE_VERSION { + if version != 5 && version != CACHE_VERSION { return Err(format!("wave cache version {version}")); } let duration_secs = f64::from_le_bytes(take(8)?.try_into().unwrap()); let sample_rate = u32::from_le_bytes(take(4)?.try_into().unwrap()); + let refined_by_beats = if version >= 6 { + match take(1)?[0] { + 0 => false, + 1 => true, + _ => return Err("wave cache refinement flag out of range".into()), + } + } else { + false + }; let bpm = f64::from_le_bytes(take(8)?.try_into().unwrap()); let beat_secs = f64::from_le_bytes(take(8)?.try_into().unwrap()); let first_beat_secs = f64::from_le_bytes(take(8)?.try_into().unwrap()); @@ -1836,11 +2076,13 @@ pub fn decode_analysis(bytes: &[u8]) -> Result { for _ in 0..change_count { changes_secs.push(f64::from_le_bytes(take(8)?.try_into().unwrap())); } + #[cfg(test)] + let _ = refined_by_beats; Ok(TrackAnalysis { duration_secs, sample_rate, - changes_secs, - tempo_map: TempoMap { segments }, + #[cfg(not(test))] + refined_by_beats, grid: TrackGrid { bpm, beat_secs, @@ -1848,6 +2090,8 @@ pub fn decode_analysis(bytes: &[u8]) -> Result { downbeat_phase, confidence, }, + changes_secs, + tempo_map: TempoMap { segments }, tiles: WaveTiles { zoom, overview }, }) } @@ -1857,6 +2101,12 @@ fn load_cached(dir: &Path, key: &AnalysisKey) -> Option { decode_analysis(&bytes).ok() } +/// Re-publish an analysis the operator corrected (a flipped beat pulse), so +/// the next load of the same record starts from the corrected grid. +pub fn store_analysis(key: &AnalysisKey, analysis: &TrackAnalysis) { + store_cached(&cache_dir(), key, analysis); +} + fn store_cached(dir: &Path, key: &AnalysisKey, analysis: &TrackAnalysis) { if std::fs::create_dir_all(dir).is_err() { return; @@ -1868,6 +2118,86 @@ fn store_cached(dir: &Path, key: &AnalysisKey, analysis: &TrackAnalysis) { } } +/// Downmix deck PCM and band-limited resample it to Beat This!'s 22.05 kHz +/// input rate. The small rational polyphase kernel is the same shape used by +/// the AI hub's audio resampler, kept local so track analysis adds no runtime +/// dependency or intermediate stereo buffers. +fn mono_22k(pcm: &TrackPcm) -> Result, String> { + const OUT_RATE: u32 = 22_050; + if pcm.sample_rate == 0 { + return Err("source sample rate is zero".into()); + } + let mono: Vec = pcm + .frames + .iter() + .map(|frame| (frame[0] as f32 + frame[1] as f32) * (0.5 / 32768.0)) + .collect(); + if pcm.sample_rate == OUT_RATE || mono.is_empty() { + return Ok(mono); + } + + let divisor = gcd_u32(pcm.sample_rate, OUT_RATE); + let up = (OUT_RATE / divisor) as usize; + let down = (pcm.sample_rate / divisor) as usize; + const HALF: i64 = 16; + let cutoff = 0.5 * 0.92 * (OUT_RATE.min(pcm.sample_rate) as f64 / pcm.sample_rate as f64); + let mut kernels = Vec::with_capacity(up); + for phase in 0..up { + let fraction = phase as f64 / up as f64; + let mut taps = Vec::with_capacity((2 * HALF) as usize); + let mut sum = 0.0; + for tap_index in -HALF + 1..=HALF { + let distance = tap_index as f64 - fraction; + let sinc = if distance.abs() <= f64::EPSILON { + 1.0 + } else { + let angle = std::f64::consts::PI * 2.0 * cutoff * distance; + angle.sin() / angle + }; + let window_position = (distance + HALF as f64) / (2.0 * HALF as f64); + let window = if (0.0..=1.0).contains(&window_position) { + 0.42 - 0.5 * (2.0 * std::f64::consts::PI * window_position).cos() + + 0.08 * (4.0 * std::f64::consts::PI * window_position).cos() + } else { + 0.0 + }; + let tap = 2.0 * cutoff * sinc * window; + sum += tap; + taps.push(tap); + } + for tap in &mut taps { + *tap /= sum; + } + kernels.push(taps); + } + + let output_len = mono.len() * up / down; + let mut output = Vec::with_capacity(output_len); + for output_index in 0..output_len { + let numerator = output_index * down; + let input_base = (numerator / up) as i64; + let taps = &kernels[numerator % up]; + let mut sample = 0.0; + for (tap, offset) in taps.iter().zip(-HALF + 1..=HALF) { + let input_index = input_base + offset; + if input_index >= 0 && (input_index as usize) < mono.len() { + sample += mono[input_index as usize] as f64 * tap; + } + } + output.push(sample as f32); + } + Ok(output) +} + +fn gcd_u32(mut left: u32, mut right: u32) -> u32 { + while right != 0 { + let remainder = left % right; + left = right; + right = remainder; + } + left +} + // --------------------------------------------------------------------------- // worker pool // --------------------------------------------------------------------------- @@ -1877,6 +2207,7 @@ pub struct AnalysisJob { pub gen: u64, pub key: AnalysisKey, pub pcm: Arc, + pub beats_model: Option, } pub struct AnalysisDone { @@ -1908,21 +2239,84 @@ impl AnalysisPool { .name("vj-wave-analysis".into()) .spawn(move || { let dir = cache_dir(); + let mut beats_checkpoint: Option = None; + let mut beats_model: Option = None; + let mut beats_model_error: Option = None; while let Ok(job) = jobs.recv() { - let (analysis, cached) = match load_cached(&dir, &job.key) { + let (mut analysis, cached) = match load_cached(&dir, &job.key) { Some(hit) => (hit, true), - None => { - let fresh = analyze(&job.pcm); - store_cached(&dir, &job.key, &fresh); - (fresh, false) - } + None => (analyze(&job.pcm), false), }; + let mut straight_from_cache = cached; + let mut should_store = !cached; + if let Some(checkpoint) = job.beats_model.as_ref() { + if !analysis.refined_by_beats() { + if beats_checkpoint.as_ref() != Some(checkpoint) { + beats_checkpoint = Some(checkpoint.clone()); + beats_model = None; + beats_model_error = None; + match BeatsModel::load(checkpoint) { + Ok(model) => beats_model = Some(model), + Err(error) => beats_model_error = Some(error.to_string()), + } + } + if let Some(error) = beats_model_error.as_ref() { + makepad_widgets::log!( + "beats: kept comb grid; model load failed: {error}" + ); + } else if let Some(model) = beats_model.as_mut() { + let started = Instant::now(); + match mono_22k(&job.pcm) { + Err(error) => makepad_widgets::log!( + "beats: kept comb grid; resample failed: {error}" + ), + Ok(mono) => match model.analyze(&mono) { + Err(error) => makepad_widgets::log!( + "beats: kept comb grid; analysis failed: {error}" + ), + Ok(beats) => match refine_grid_with_beats( + &analysis.grid, + analysis.duration_secs, + &beats.beats_secs, + &beats.downbeats_secs, + ) { + None => makepad_widgets::log!( + "beats: kept comb grid; refinement rejected ({} beats, {} downbeats)", + beats.beats_secs.len(), + beats.downbeats_secs.len(), + ), + Some(refined) => { + let previous = analysis.grid; + analysis.grid = refined; + analysis.mark_refined_by_beats(); + straight_from_cache = false; + should_store = true; + makepad_widgets::log!( + "beats: {:.2} → {:.2} bpm, phase {} → {}, {} beats {} downbeats, {} ms", + previous.bpm, + refined.bpm, + previous.downbeat_phase, + refined.downbeat_phase, + beats.beats_secs.len(), + beats.downbeats_secs.len(), + started.elapsed().as_millis(), + ); + } + }, + }, + } + } + } + } + if should_store { + store_cached(&dir, &job.key, &analysis); + } if done_tx .send(AnalysisDone { deck: job.deck, gen: job.gen, analysis: Arc::new(analysis), - cached, + cached: straight_from_cache, }) .is_err() { @@ -2004,6 +2398,113 @@ pub fn list_local_audio(dir: &Path) -> Vec { mod tests { use super::*; + fn synthetic_beats(bpm: f64, first: f64, count: usize) -> Vec { + let period = 60.0 / bpm; + (0..count).map(|index| first + index as f64 * period).collect() + } + + fn synthetic_downbeats(beats: &[f64], stride: usize) -> Vec { + beats.iter().step_by(stride).copied().collect() + } + + fn synthetic_grid(bpm: f64, first: f64, phase: u32) -> TrackGrid { + TrackGrid { + bpm, + beat_secs: 60.0 / bpm, + first_beat_secs: first, + downbeat_phase: phase, + confidence: 0.25, + } + } + + #[test] + fn beats_refinement_fits_an_exact_grid() { + let beats = synthetic_beats(120.0, 0.2, 96); + let refined = refine_grid_with_beats( + &synthetic_grid(120.0, 0.45, 2), + 50.0, + &beats, + &synthetic_downbeats(&beats, 4), + ) + .expect("exact model grid"); + assert!((refined.bpm - 120.0).abs() < 1e-9); + assert!((refined.first_beat_secs - 0.2).abs() < 1e-9); + assert_eq!(refined.downbeat_phase, 0); + assert_eq!(refined.confidence, 0.6); + } + + #[test] + fn beats_refinement_tolerates_fifteen_ms_jitter() { + let mut beats = synthetic_beats(126.0, 0.17, 100); + for (index, beat) in beats.iter_mut().enumerate() { + *beat += match index % 3 { + 0 => -0.015, + 1 => 0.0, + _ => 0.015, + }; + } + let downbeats = synthetic_downbeats(&beats, 4); + let refined = refine_grid_with_beats( + &synthetic_grid(126.0, 0.4, 3), + 50.0, + &beats, + &downbeats, + ) + .expect("jittered model grid"); + assert!((refined.bpm - 126.0).abs() < 0.02, "{refined:?}"); + assert!(refined.first_beat_secs < 0.20, "{refined:?}"); + assert_eq!(refined.downbeat_phase, 0); + assert_eq!(refined.confidence, 0.6); + } + + #[test] + fn beats_refinement_removes_five_percent_outliers() { + let clean = synthetic_beats(124.0, 0.11, 100); + let mut beats = clean.clone(); + for index in [9usize, 29, 49, 69, 89] { + beats[index] += 0.31; + } + let refined = refine_grid_with_beats( + &synthetic_grid(124.0, 0.3, 1), + 50.0, + &beats, + &synthetic_downbeats(&clean, 4), + ) + .expect("model grid with outliers"); + assert!((refined.bpm - 124.0).abs() < 1e-6, "{refined:?}"); + assert!((refined.first_beat_secs - 0.11).abs() < 1e-6, "{refined:?}"); + assert_eq!(refined.downbeat_phase, 0); + } + + #[test] + fn beats_refinement_corrects_a_half_beat_shifted_comb_pulse() { + let beats = synthetic_beats(120.0, 0.13, 96); + let refined = refine_grid_with_beats( + &synthetic_grid(120.0, 0.38, 3), + 50.0, + &beats, + &synthetic_downbeats(&beats, 4), + ) + .expect("half-beat correction"); + assert!((refined.first_beat_secs - 0.13).abs() < 1e-9, "{refined:?}"); + assert_eq!(refined.downbeat_phase, 0); + } + + #[test] + fn beats_refinement_keeps_comb_tempo_for_double_time_model() { + let beats = synthetic_beats(240.0, 0.19, 160); + let refined = refine_grid_with_beats( + &synthetic_grid(120.0, 0.44, 2), + 41.0, + &beats, + &synthetic_downbeats(&beats, 8), + ) + .expect("double-time model grid"); + assert!((refined.bpm - 120.0).abs() < 1e-9, "{refined:?}"); + assert!((refined.first_beat_secs - 0.19).abs() < 1e-9, "{refined:?}"); + assert_eq!(refined.downbeat_phase, 0); + } + /// End-to-end deck load over a real file on this machine, which is the /// only way to exercise the compressed formats without committing audio: /// @@ -2431,6 +2932,7 @@ mod tests { let bytes = encode_analysis(&analysis); let back = decode_analysis(&bytes).expect("decode"); assert_eq!(back.grid, analysis.grid); + assert!(!back.refined_by_beats()); assert_eq!(back.tiles, analysis.tiles); assert_eq!(back.sample_rate, analysis.sample_rate); assert!((back.duration_secs - analysis.duration_secs).abs() < 1e-9); @@ -2444,7 +2946,14 @@ mod tests { // Truncation and junk are refused, not misread. assert!(decode_analysis(&bytes[..bytes.len() / 2]).is_err()); assert!(decode_analysis(b"nope").is_err()); - // An old-version file is re-analysed, never misread. + // Version 5 had every field except the refinement marker. It remains + // reusable, but must run Beat This! once when weights are available. + let mut version_five = encode_analysis(&analysis); + version_five[8..12].copy_from_slice(&5u32.to_le_bytes()); + version_five.remove(24); + let old = decode_analysis(&version_five).expect("version 5 decode"); + assert!(!old.refined_by_beats()); + // Still older layouts are re-analysed, never misread. let mut old = encode_analysis(&analysis); old[8..12].copy_from_slice(&4u32.to_le_bytes()); assert!(decode_analysis(&old).is_err()); @@ -2595,4 +3104,3 @@ mod tests { assert!((steps - steps.round()).abs() < 1e-9, "moved {steps} units"); } } - From 8ea3684250a169716b12981b64334b97dfd54b32 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 02:51:45 +0200 Subject: [PATCH 049/417] widgets: EventOrder reachable from the DSL; DataGrid hit-tests where it was drawn A View can now say event_order: EventOrder.Down in script. The DataGrid cached its geometry at draw time, before a Fill sibling could shift it, so clicks in a right-hand column landed outside; it re-anchors to its drawn rect on every event. Co-Authored-By: Claude Fable 5.1 --- widgets/src/data_grid.rs | 29 +++++++++++++++++++++++++++++ widgets/src/view.rs | 1 + 2 files changed, 30 insertions(+) diff --git a/widgets/src/data_grid.rs b/widgets/src/data_grid.rs index cade75b6e..18dced49b 100644 --- a/widgets/src/data_grid.rs +++ b/widgets/src/data_grid.rs @@ -415,6 +415,25 @@ struct GridViewport { total_h: f64, } +impl GridViewport { + /// Move every cached rect by `delta`. The viewport is computed from the + /// turtle at draw time, but a parent that sizes itself by `Fill` can + /// still shift the whole widget afterwards (deferred alignment): the + /// instances move with it, the cached geometry does not. Re-anchoring + /// to where the widget actually landed keeps hit testing honest. + fn translate(&mut self, delta: DVec2) { + self.widget_rect.pos += delta; + self.data_rect.pos += delta; + self.col_header_rect.pos += delta; + self.row_header_rect.pos += delta; + self.corner_rect.pos += delta; + for (_, x, _) in &mut self.vis_cols { + *x += delta.x; + } + self.row0_y += delta.y; + } +} + struct CellIter { row: usize, y: f64, @@ -1668,6 +1687,16 @@ impl Widget for DataGrid { fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) { let uid = self.uid; + // Where the widget actually is this frame, after any deferred + // alignment by its parents; the cached viewport follows it. + let drawn = self.area.rect(cx); + if drawn.size.x > 0.0 && drawn.size.y > 0.0 { + let delta = drawn.pos - self.vp.widget_rect.pos; + if delta.x != 0.0 || delta.y != 0.0 { + self.vp.translate(delta); + } + } + // Scroll bar drag / animation let mut sx = None; let mut sy = None; diff --git a/widgets/src/view.rs b/widgets/src/view.rs index e9f4c5ee4..0b90ff4a7 100644 --- a/widgets/src/view.rs +++ b/widgets/src/view.rs @@ -17,6 +17,7 @@ use { script_mod! { use mod.prelude.widgets_internal.* + mod.widgets.EventOrder = #(EventOrder::script_api(vm)) mod.widgets.ViewBase = set_type_default() do #(View::register_widget(vm)) } From 79882b5fb638bd8babbc9af6e4a205fb8132c57c Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 2 Sep 2026 02:51:45 +0200 Subject: [PATCH 050/417] fabric: a photo or a live camera to a fitted sewing pattern apps/fabric runs SAM 3D Body in-process (install + licence through the hub panel), measures the rest-pose body mesh (libs/fabric/measure: 25 tape measurements from plane slices and landmarks) and drafts parametric patterns (libs/fabric/draft: T-shirt, A-line skirt, easy trousers; nesting, true-scale SVG, tiled A4 PDF). Live mode streams the webcam at a few frames a second, shows the posed body with the measurement rings riding on it, and re-drafts when the numbers settle. Measurements sit in a DataGrid that copies as tab-separated text. Co-Authored-By: Claude Fable 5.1 --- apps/fabric/Cargo.toml | 16 + apps/fabric/src/body_view.rs | 539 +++++ apps/fabric/src/camera.rs | 303 +++ apps/fabric/src/install.rs | 73 + apps/fabric/src/main.rs | 1793 +++++++++++++++++ apps/fabric/src/pattern_view.rs | 398 ++++ apps/fabric/src/pipeline.rs | 676 +++++++ libs/fabric/draft/Cargo.toml | 9 + libs/fabric/draft/src/designs/aline_skirt.rs | 149 ++ .../fabric/draft/src/designs/easy_trousers.rs | 124 ++ libs/fabric/draft/src/designs/mod.rs | 234 +++ libs/fabric/draft/src/designs/tshirt.rs | 200 ++ libs/fabric/draft/src/geom.rs | 549 +++++ libs/fabric/draft/src/lib.rs | 327 +++ libs/fabric/draft/src/nest.rs | 152 ++ libs/fabric/draft/src/pdf.rs | 308 +++ libs/fabric/draft/src/svg.rs | 156 ++ libs/fabric/measure/Cargo.toml | 8 + libs/fabric/measure/src/lib.rs | 1688 ++++++++++++++++ 19 files changed, 7702 insertions(+) create mode 100644 apps/fabric/Cargo.toml create mode 100644 apps/fabric/src/body_view.rs create mode 100644 apps/fabric/src/camera.rs create mode 100644 apps/fabric/src/install.rs create mode 100644 apps/fabric/src/main.rs create mode 100644 apps/fabric/src/pattern_view.rs create mode 100644 apps/fabric/src/pipeline.rs create mode 100644 libs/fabric/draft/Cargo.toml create mode 100644 libs/fabric/draft/src/designs/aline_skirt.rs create mode 100644 libs/fabric/draft/src/designs/easy_trousers.rs create mode 100644 libs/fabric/draft/src/designs/mod.rs create mode 100644 libs/fabric/draft/src/designs/tshirt.rs create mode 100644 libs/fabric/draft/src/geom.rs create mode 100644 libs/fabric/draft/src/lib.rs create mode 100644 libs/fabric/draft/src/nest.rs create mode 100644 libs/fabric/draft/src/pdf.rs create mode 100644 libs/fabric/draft/src/svg.rs create mode 100644 libs/fabric/measure/Cargo.toml create mode 100644 libs/fabric/measure/src/lib.rs diff --git a/apps/fabric/Cargo.toml b/apps/fabric/Cargo.toml new file mode 100644 index 000000000..495dfc9e9 --- /dev/null +++ b/apps/fabric/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "makepad-fabric" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" +description = "Fabric: a photo in, a fitted sewing pattern out — body model, measurements, draft, cut sheet" + +[dependencies] +makepad-widgets = { path = "../../widgets" } +makepad-fabric-measure = { path = "../../libs/fabric/measure" } +makepad-fabric-draft = { path = "../../libs/fabric/draft" } +# The body model runs in-process (Metal on the Mac, CUDA on a box); the +# hub does install, licence acknowledgement and weight location. +makepad-ai-body = { path = "../../libs/ai/models/body" } +makepad-ai-hub = { path = "../../libs/ai/hub", default-features = false, features = ["local", "body-native"] } +makepad-ai-hub-ui = { path = "../../libs/ai/hub_ui" } diff --git a/apps/fabric/src/body_view.rs b/apps/fabric/src/body_view.rs new file mode 100644 index 000000000..8c11abc15 --- /dev/null +++ b/apps/fabric/src/body_view.rs @@ -0,0 +1,539 @@ +use makepad_fabric_measure::{BodyMesh, Line, Measured, Ring}; +use makepad_widgets::*; +use std::sync::Arc; + +script_mod! { + use mod.prelude.widgets_internal.* + use mod.widgets.* + + set_type_default() do #(DrawBodyPoint::script_shader(vm)) { + ..mod.draw.DrawQuad + pixel: fn() { + let d = length(self.pos - vec2(0.5, 0.5)) + let a = clamp((0.5 - d) * 7.0, 0.0, 1.0) + let near = #x80e7ff + let far = #x27435d + let c = far.mix(near, 1.0 - self.depth) + return vec4(c.xyz * a, a) + } + } + + set_type_default() do #(DrawFabricLine::script_shader(vm)) { + ..mod.draw.DrawQuad + pixel: fn() { + // A line as a distance field inside its bounding quad. The + // endpoints are LOCAL to the quad (the turtle may still shift + // rect_pos after the instance is written), like the chart's + // segment shader. + let p = self.pos * self.rect_size + let ab = self.p1 - self.p0 + let t = clamp(dot(p - self.p0, ab) / max(dot(ab, ab), 0.0001), 0.0, 1.0) + let d = length(p - (self.p0 + ab * t)) + let aa = 1.0 - smoothstep(self.half_width - 0.6, self.half_width + 0.6, d) + let alpha = aa * self.color.w + return vec4(self.color.xyz * alpha, alpha) + } + } + + mod.widgets.FabricBodyViewBase = #(FabricBodyView::register_widget(vm)) + mod.widgets.FabricBodyView = set_type_default() do mod.widgets.FabricBodyViewBase { + width: Fill + height: Fill + draw_bg +: {color: #x11161d} + draw_point +: {} + draw_line +: {} + draw_text +: { + color: #x9aa8b7 + text_style: theme.font_regular{font_size: 9.0} + } + } +} + +#[derive(Script, ScriptHook)] +#[repr(C)] +pub struct DrawBodyPoint { + #[deref] + draw_super: DrawQuad, + #[live] + depth: f32, +} + +#[derive(Script, ScriptHook)] +#[repr(C)] +pub struct DrawFabricLine { + #[deref] + draw_super: DrawQuad, + #[live] + pub color: Vec4f, + #[live] + p0: Vec2f, + #[live] + p1: Vec2f, + #[live] + half_width: f32, +} + +impl DrawFabricLine { + pub fn segment(&mut self, cx: &mut Cx2d, from: DVec2, to: DVec2, width: f64) { + if (to - from).length() < 0.01 { + return; + } + let half = width * 0.5; + let pad = half + 1.0; + let min = dvec2(from.x.min(to.x) - pad, from.y.min(to.y) - pad); + let max = dvec2(from.x.max(to.x) + pad, from.y.max(to.y) + pad); + self.p0 = v2f(from - min); + self.p1 = v2f(to - min); + self.half_width = half as f32; + self.draw_abs(cx, Rect { pos: min, size: max - min }); + } +} + +fn v2f(value: DVec2) -> Vec2f { + Vec2f { + x: value.x as f32, + y: value.y as f32, + } +} + +#[derive(Clone, Copy)] +struct BodyDrag { + from: DVec2, + yaw: f64, + pitch: f64, + pan: DVec2, + panning: bool, +} + +#[derive(Clone, Debug, Default)] +pub(crate) struct BodyPoseMapping { + ring_vertices: Vec>, + line_vertices: Vec<[usize; 2]>, +} + +pub(crate) fn map_measurements_to_vertices( + mesh: &BodyMesh, + measured: &Measured, +) -> BodyPoseMapping { + let nearest = |point| nearest_vertex_index(&mesh.vertices, measured.scale, point); + BodyPoseMapping { + ring_vertices: measured + .rings + .iter() + .map(|ring| ring.points.iter().copied().map(nearest).collect()) + .collect(), + line_vertices: measured + .lines + .iter() + .map(|line| [nearest(line.from), nearest(line.to)]) + .collect(), + } +} + +fn nearest_vertex_index(vertices: &[[f32; 3]], scale: f32, point: [f32; 3]) -> usize { + vertices + .iter() + .enumerate() + .map(|(index, vertex)| { + let dx = vertex[0] * scale - point[0]; + let dy = vertex[1] * scale - point[1]; + let dz = vertex[2] * scale - point[2]; + (index, dx * dx + dy * dy + dz * dz) + }) + .min_by(|left, right| left.1.total_cmp(&right.1)) + .map(|(index, _)| index) + .unwrap_or(0) +} + +fn mirror_x(value: f64, mirrored: bool) -> f64 { + if mirrored { -value } else { value } +} + +fn bounds(points: &[[f32; 3]], scale: f32) -> Option<([f32; 3], f32)> { + let mut min = [f32::INFINITY; 3]; + let mut max = [f32::NEG_INFINITY; 3]; + for point in points { + for axis in 0..3 { + let value = point[axis] * scale; + min[axis] = min[axis].min(value); + max[axis] = max[axis].max(value); + } + } + if !min[0].is_finite() { + return None; + } + let centre = [ + (min[0] + max[0]) * 0.5, + (min[1] + max[1]) * 0.5, + (min[2] + max[2]) * 0.5, + ]; + let dx = max[0] - min[0]; + let dy = max[1] - min[1]; + let dz = max[2] - min[2]; + let radius = (dx * dx + dy * dy + dz * dz).sqrt().max(1.0) * 0.5; + Some((centre, radius)) +} + +#[derive(Script, ScriptHook, Widget)] +pub struct FabricBodyView { + #[uid] + uid: WidgetUid, + #[source] + source: ScriptObjectRef, + #[walk] + walk: Walk, + #[layout] + layout: Layout, + #[redraw] + #[area] + area: Area, + #[live] + draw_bg: DrawColor, + #[live] + draw_point: DrawBodyPoint, + #[live] + draw_line: DrawFabricLine, + #[live] + draw_text: DrawText, + #[rust] + mesh: Option>, + #[rust] + posed: Option>>, + #[rust] + rings: Vec, + #[rust] + lines: Vec, + #[rust] + pose_mapping: BodyPoseMapping, + #[rust] + mesh_scale: f32, + #[rust] + centre: [f32; 3], + #[rust] + radius: f32, + #[rust(0.35)] + yaw: f64, + #[rust(-0.06)] + pitch: f64, + #[rust(1.0)] + zoom: f64, + #[rust] + pan: DVec2, + #[rust] + drag: Option, + #[rust(true)] + mirrored: bool, +} + +impl FabricBodyView { + pub fn set_body( + &mut self, + cx: &mut Cx, + mesh: Arc, + measured: &Measured, + pose_mapping: BodyPoseMapping, + ) { + self.mesh_scale = measured.scale; + self.rings = measured.rings.clone(); + self.lines = measured.lines.clone(); + self.pose_mapping = pose_mapping; + if self.posed.is_none() { + self.fit_bounds(&mesh.vertices); + self.reset_camera(); + } + self.mesh = Some(mesh); + self.redraw(cx); + } + + pub fn set_pose(&mut self, cx: &mut Cx, posed: Option>>) { + match posed { + Some(posed) + if self + .mesh + .as_ref() + .is_some_and(|mesh| mesh.vertices.len() == posed.len()) => + { + if self.posed.is_none() { + self.fit_bounds(posed.as_slice()); + self.reset_camera(); + } + self.posed = Some(posed); + } + _ => { + self.posed = None; + if let Some(fit) = self + .mesh + .as_ref() + .and_then(|mesh| bounds(&mesh.vertices, self.mesh_scale)) + { + (self.centre, self.radius) = fit; + self.reset_camera(); + } + } + } + self.redraw(cx); + } + + pub fn set_mirrored(&mut self, cx: &mut Cx, mirrored: bool) { + self.mirrored = mirrored; + self.redraw(cx); + } + + fn fit_bounds(&mut self, points: &[[f32; 3]]) { + if let Some((centre, radius)) = bounds(points, self.mesh_scale) { + self.centre = centre; + self.radius = radius; + } + } + + fn reset_camera(&mut self) { + self.yaw = 0.35; + self.pitch = -0.06; + self.zoom = 1.0; + self.pan = dvec2(0.0, 0.0); + } + + fn project(&self, point: [f32; 3], mesh_point: bool, rect: Rect) -> Option<(DVec2, f32)> { + let scale = if mesh_point { self.mesh_scale } else { 1.0 } as f64; + let x = point[0] as f64 * scale - self.centre[0] as f64; + let y = point[1] as f64 * scale - self.centre[1] as f64; + let z = point[2] as f64 * scale - self.centre[2] as f64; + let (sy, cy) = self.yaw.sin_cos(); + let (sp, cp) = self.pitch.sin_cos(); + let rx = mirror_x(cy * x + sy * z, self.mirrored); + let rz = -sy * x + cy * z; + let ry = cp * y - sp * rz; + let rz = sp * y + cp * rz; + let fov = 35.0_f64.to_radians(); + let fit_distance = self.radius as f64 / (fov * 0.5).tan() * 1.2; + let camera_z = fit_distance / self.zoom.max(0.08) - rz; + if camera_z <= 0.01 { + return None; + } + let focal = rect.size.y.max(1.0) * 0.5 / (fov * 0.5).tan(); + let centre = rect.pos + rect.size * 0.5 + self.pan; + let screen = dvec2(centre.x + focal * rx / camera_z, centre.y - focal * ry / camera_z); + Some((screen, camera_z as f32)) + } + + fn projected_polyline(&self, points: &[[f32; 3]], rect: Rect) -> Vec<(DVec2, f32)> { + points + .iter() + .filter_map(|point| self.project(*point, false, rect)) + .collect() + } +} + +impl Widget for FabricBodyView { + fn draw_walk(&mut self, cx: &mut Cx2d, _scope: &mut Scope, walk: Walk) -> DrawStep { + let rect = cx.walk_turtle(walk); + self.draw_bg.draw_abs(cx, rect); + cx.push_clip_rect(rect); + let Some(mesh) = self.mesh.as_ref() else { + self.draw_text.color = Vec4f { + x: 0.48, + y: 0.55, + z: 0.62, + w: 1.0, + }; + self.draw_text.draw_abs( + cx, + rect.pos + rect.size * 0.5 - dvec2(70.0, 5.0), + "drop a photo to start", + ); + cx.pop_clip_rect(); + cx.add_aligned_rect_area(&mut self.area, rect); + return DrawStep::done(); + }; + let posed = self + .posed + .as_deref() + .filter(|posed| posed.len() == mesh.vertices.len()) + .map(Vec::as_slice); + let display_vertices = posed.unwrap_or(mesh.vertices.as_slice()); + + let mut points: Vec<(DVec2, f32)> = display_vertices + .iter() + .filter_map(|point| self.project(*point, true, rect)) + .collect(); + points.sort_by(|a, b| b.1.total_cmp(&a.1)); + let min_depth = points.iter().map(|point| point.1).fold(f32::INFINITY, f32::min); + let max_depth = points + .iter() + .map(|point| point.1) + .fold(f32::NEG_INFINITY, f32::max); + let depth_span = (max_depth - min_depth).max(0.001); + self.draw_point.begin_many_instances(cx); + for (point, depth) in points { + self.draw_point.depth = (depth - min_depth) / depth_span; + self.draw_point.draw_abs( + cx, + Rect { + pos: point - dvec2(1.25, 1.25), + size: dvec2(2.5, 2.5), + }, + ); + } + self.draw_point.end_many_instances(cx); + + let rings: Vec<(String, Vec<(DVec2, f32)>)> = self + .rings + .iter() + .enumerate() + .map(|(ring_index, ring)| { + let points = match ( + posed, + self.pose_mapping.ring_vertices.get(ring_index), + ) { + (Some(posed), Some(indices)) if indices.len() == ring.points.len() => indices + .iter() + .filter_map(|&index| self.project(*posed.get(index)?, true, rect)) + .collect(), + _ => self.projected_polyline(&ring.points, rect), + }; + (ring.key.replace('_', " "), points) + }) + .collect(); + let lines: Vec<(DVec2, DVec2)> = self + .lines + .iter() + .enumerate() + .filter_map(|(line_index, line)| { + let (from, to, mesh_points) = match ( + posed, + self.pose_mapping.line_vertices.get(line_index), + ) { + (Some(posed), Some([from, to])) => + (*posed.get(*from)?, *posed.get(*to)?, true), + _ => (line.from, line.to, false), + }; + Some(( + self.project(from, mesh_points, rect)?.0, + self.project(to, mesh_points, rect)?.0, + )) + }) + .collect(); + + self.draw_line.begin_many_instances(cx); + self.draw_line.color = Vec4f { + x: 1.0, + y: 0.38, + z: 0.18, + w: 0.92, + }; + for (_, points) in &rings { + for pair in points.windows(2) { + self.draw_line.segment(cx, pair[0].0, pair[1].0, 1.5); + } + if let (Some(first), Some(last)) = (points.first(), points.last()) { + self.draw_line.segment(cx, last.0, first.0, 1.5); + } + } + self.draw_line.color = Vec4f { + x: 0.42, + y: 0.78, + z: 1.0, + w: 0.9, + }; + for (from, to) in lines { + self.draw_line.segment(cx, from, to, 1.25); + } + self.draw_line.end_many_instances(cx); + + self.draw_text.color = Vec4f { + x: 1.0, + y: 0.66, + z: 0.48, + w: 1.0, + }; + for (key, points) in rings { + if let Some(front) = points.iter().min_by(|a, b| a.1.total_cmp(&b.1)) { + self.draw_text + .draw_abs(cx, front.0 + dvec2(4.0, -5.0), &key); + } + } + cx.pop_clip_rect(); + cx.add_aligned_rect_area(&mut self.area, rect); + DrawStep::done() + } + + fn handle_event(&mut self, cx: &mut Cx, event: &Event, _scope: &mut Scope) { + match event.hits(cx, self.area) { + Hit::FingerDown(event) if event.device.is_primary_hit() => { + if event.tap_count >= 2 { + self.reset_camera(); + self.redraw(cx); + return; + } + self.drag = Some(BodyDrag { + from: event.abs, + yaw: self.yaw, + pitch: self.pitch, + pan: self.pan, + panning: event.modifiers.shift, + }); + } + Hit::FingerMove(event) => { + if let Some(drag) = self.drag { + let delta = event.abs - drag.from; + if drag.panning { + self.pan = drag.pan + delta; + } else { + self.yaw = drag.yaw - delta.x * 0.008; + self.pitch = (drag.pitch + delta.y * 0.007).clamp(-1.35, 1.35); + } + self.redraw(cx); + } + } + Hit::FingerUp(_) => self.drag = None, + Hit::FingerScroll(event) => { + self.zoom = (self.zoom * (-event.scroll.y * 0.004).exp()).clamp(0.15, 12.0); + self.redraw(cx); + } + Hit::FingerHoverIn(_) | Hit::FingerHoverOver(_) => { + cx.set_cursor(MouseCursor::Grab); + } + _ => {} + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn nearest_vertex_mapping_uses_scaled_rest_mesh_positions() { + let mesh = BodyMesh { + vertices: vec![[0.0, 0.0, 0.0], [4.0, 0.0, 0.0], [9.0, 0.0, 0.0]], + faces: Vec::new(), + landmarks: None, + }; + let measured = Measured { + values: makepad_fabric_measure::Measurements::sample(), + scale: 2.0, + rings: vec![Ring { + key: "test_ring", + y_cm: 0.0, + points: vec![[0.2, 0.0, 0.0], [7.5, 0.0, 0.0]], + skin_perimeter_cm: 0.0, + tape_perimeter_cm: 0.0, + }], + lines: vec![Line { + key: "test_line", + from: [7.5, 0.0, 0.0], + to: [17.0, 0.0, 0.0], + }], + }; + let mapping = map_measurements_to_vertices(&mesh, &measured); + assert_eq!(mapping.ring_vertices, vec![vec![0, 1]]); + assert_eq!(mapping.line_vertices, vec![[1, 2]]); + } + + #[test] + fn mirror_transform_only_flips_horizontal_view_axis() { + assert_eq!(mirror_x(12.5, false), 12.5); + assert_eq!(mirror_x(12.5, true), -12.5); + assert_eq!(mirror_x(-3.0, true), 3.0); + } +} diff --git a/apps/fabric/src/camera.rs b/apps/fabric/src/camera.rs new file mode 100644 index 000000000..9e9add372 --- /dev/null +++ b/apps/fabric/src/camera.rs @@ -0,0 +1,303 @@ +use makepad_widgets::{ + makepad_platform::video::{ + CameraFrameLayout, CameraFrameRef, VideoFormatId, VideoInputId, VideoInputsEvent, + VideoPixelFormat, + }, + Cx, CxMediaApi, +}; +use std::{ + cmp::Reverse, + sync::{ + atomic::{AtomicBool, AtomicU64, Ordering}, + Arc, Mutex, + }, + time::{Duration, Instant}, +}; + +pub const SEND_MAX_WIDTH: usize = 640; +const PREVIEW_MAX_WIDTH: usize = 320; +const PREVIEW_INTERVAL: Duration = Duration::from_millis(100); + +#[derive(Clone, Debug, PartialEq)] +pub struct CameraRgbFrame { + pub width: u32, + pub height: u32, + pub rgb: Vec, + pub serial: u64, +} + +#[derive(Default)] +struct PreviewSlot { + frame: Option, + updated_at: Option, +} + +#[derive(Default)] +struct CameraMailboxInner { + want: AtomicBool, + serial: AtomicU64, + frame: Mutex>, + model_size: Mutex>, + preview: Mutex, +} + +/// A one-frame handoff from the camera callback to the model worker. The +/// callback only converts a model-sized frame after the worker asks for one; +/// the smaller preview is independent and limited to ten updates per second. +#[derive(Clone, Default)] +pub struct CameraMailbox { + inner: Arc, +} + +impl CameraMailbox { + pub fn request(&self) { + if let Ok(mut frame) = self.inner.frame.lock() { + *frame = None; + } + self.inner.want.store(true, Ordering::Release); + } + + pub fn take(&self) -> Option { + self.inner.frame.lock().ok()?.take() + } + + pub fn peek_preview(&self) -> Option { + self.inner.preview.lock().ok()?.frame.clone() + } + + pub fn model_size(&self) -> Option<(u32, u32)> { + *self.inner.model_size.lock().ok()? + } + + fn capture(&self, frame: &CameraFrameRef<'_>) { + let wanted = self.inner.want.swap(false, Ordering::AcqRel); + let preview_due = self + .inner + .preview + .lock() + .ok() + .map(|slot| { + slot.updated_at + .map(|updated| updated.elapsed() >= PREVIEW_INTERVAL) + .unwrap_or(true) + }) + .unwrap_or(false); + if !wanted && !preview_due { + return; + } + + if wanted { + if let Some((rgb, width, height)) = frame_to_rgb(frame) { + let serial = self.inner.serial.fetch_add(1, Ordering::Relaxed) + 1; + if let Ok(mut size) = self.inner.model_size.lock() { + *size = Some((width, height)); + } + if let Ok(mut slot) = self.inner.frame.lock() { + *slot = Some(CameraRgbFrame { + width, + height, + rgb, + serial, + }); + } + } + } + + if preview_due { + if let Some((rgb, width, height)) = frame_to_rgb_max(frame, PREVIEW_MAX_WIDTH) { + let serial = self.inner.serial.fetch_add(1, Ordering::Relaxed) + 1; + if let Ok(mut slot) = self.inner.preview.lock() { + slot.frame = Some(CameraRgbFrame { + width, + height, + rgb, + serial, + }); + slot.updated_at = Some(Instant::now()); + } + } + } + } +} + +/// Register the capture callback. Calling this also asks the platform to +/// enumerate cameras, which produces `Event::VideoInputs` on the UI thread. +pub fn install_camera(cx: &mut Cx, mailbox: CameraMailbox) { + cx.camera_frame_input(0, move |frame| mailbox.capture(&frame)); +} + +/// Choose the first device's smallest raw-YUV format at least 640x360. +pub fn pick_camera(event: &VideoInputsEvent) -> Option<(VideoInputId, VideoFormatId)> { + let device = event.descs.first()?; + let format = device + .formats + .iter() + .filter(|format| { + format.width >= 640 + && format.height >= 360 + && matches!( + format.pixel_format, + VideoPixelFormat::NV12 | VideoPixelFormat::YUY2 + ) + }) + .min_by_key(|format| { + ( + format.width.saturating_mul(format.height), + if format.pixel_format == VideoPixelFormat::NV12 { + 0 + } else { + 1 + }, + Reverse((format.frame_rate.unwrap_or(0.0) * 1000.0) as u64), + ) + })?; + Some((device.input_id, format.format_id)) +} + +/// Convert NV12 or YUY2 to packed RGB8, using an integer sampling step so +/// the entire frame fits within [`SEND_MAX_WIDTH`]. +pub fn frame_to_rgb(frame: &CameraFrameRef<'_>) -> Option<(Vec, u32, u32)> { + frame_to_rgb_max(frame, SEND_MAX_WIDTH) +} + +fn frame_to_rgb_max( + frame: &CameraFrameRef<'_>, + max_width: usize, +) -> Option<(Vec, u32, u32)> { + let (width, height) = (frame.width, frame.height); + if width == 0 || height == 0 || max_width == 0 { + return None; + } + let step = width.div_ceil(max_width).max(1); + let out_width = width.div_ceil(step); + let out_height = height.div_ceil(step); + let mut rgb = Vec::with_capacity(out_width.checked_mul(out_height)?.checked_mul(3)?); + + for out_y in 0..out_height { + let source_y = (out_y * step).min(height - 1); + for out_x in 0..out_width { + let source_x = (out_x * step).min(width - 1); + let (y, u, v) = match frame.layout { + CameraFrameLayout::NV12 => nv12_pixel(frame, source_x, source_y)?, + CameraFrameLayout::YUY2 => yuy2_pixel(frame, source_x, source_y)?, + _ => return None, + }; + rgb.extend_from_slice(&yuv_to_rgb(y, u, v)); + } + } + + Some(( + rgb, + u32::try_from(out_width).ok()?, + u32::try_from(out_height).ok()?, + )) +} + +fn nv12_pixel(frame: &CameraFrameRef<'_>, x: usize, y: usize) -> Option<(u8, u8, u8)> { + if frame.plane_count < 2 { + return None; + } + let y_plane = frame.planes[0]; + let uv_plane = frame.planes[1]; + let y_index = y + .checked_mul(y_plane.row_stride)? + .checked_add(x.checked_mul(y_plane.pixel_stride)?)?; + let uv_index = (y / 2) + .checked_mul(uv_plane.row_stride)? + .checked_add((x / 2).checked_mul(uv_plane.pixel_stride)?)?; + Some(( + *y_plane.bytes.get(y_index)?, + *uv_plane.bytes.get(uv_index)?, + *uv_plane.bytes.get(uv_index + 1)?, + )) +} + +fn yuy2_pixel(frame: &CameraFrameRef<'_>, x: usize, y: usize) -> Option<(u8, u8, u8)> { + if frame.plane_count < 1 { + return None; + } + let plane = frame.planes[0]; + let pixel_stride = plane.pixel_stride.max(2); + let pair = y + .checked_mul(plane.row_stride)? + .checked_add((x / 2).checked_mul(pixel_stride.checked_mul(2)?)?)?; + Some(( + *plane.bytes.get(pair + (x & 1) * pixel_stride)?, + *plane.bytes.get(pair + 1)?, + *plane.bytes.get(pair + pixel_stride + 1)?, + )) +} + +/// One BT.709, video-range YUV pixel to RGB8. +pub(crate) fn yuv_to_rgb(y: u8, u: u8, v: u8) -> [u8; 3] { + let c = i32::from(y) - 16; + let d = i32::from(u) - 128; + let e = i32::from(v) - 128; + let clip = |value: i32| ((value + 128) >> 8).clamp(0, 255) as u8; + [ + clip(298 * c + 459 * e), + clip(298 * c - 55 * d - 136 * e), + clip(298 * c + 541 * d), + ] +} + +#[cfg(test)] +mod tests { + use super::*; + use makepad_widgets::makepad_platform::video::{ + CameraColorMatrix, CameraFramePlaneRef, + }; + + #[test] + fn yuv_grey_red_and_blue() { + let grey = yuv_to_rgb(126, 128, 128); + assert!(grey.iter().all(|channel| (126i16 - i16::from(*channel)).abs() <= 2)); + + let red = yuv_to_rgb(81, 90, 240); + assert!(red[0] > 220 && red[1] < 60 && red[2] < 60, "{red:?}"); + + let blue = yuv_to_rgb(41, 240, 110); + assert!(blue[2] > 220 && blue[0] < 60 && blue[1] < 60, "{blue:?}"); + } + + #[test] + fn nv12_integer_downsample_keeps_the_whole_frame() { + const WIDTH: usize = 64; + const HEIGHT: usize = 32; + let mut y_plane = vec![0u8; WIDTH * HEIGHT]; + for y in 0..HEIGHT { + for x in 0..WIDTH { + y_plane[y * WIDTH + x] = 16 + ((x + y) % 200) as u8; + } + } + let uv_plane = vec![128u8; WIDTH * HEIGHT / 2]; + let frame = CameraFrameRef { + timestamp_ns: 0, + width: WIDTH, + height: HEIGHT, + layout: CameraFrameLayout::NV12, + matrix: CameraColorMatrix::BT709, + plane_count: 2, + planes: [ + CameraFramePlaneRef { + bytes: &y_plane, + row_stride: WIDTH, + pixel_stride: 1, + }, + CameraFramePlaneRef { + bytes: &uv_plane, + row_stride: WIDTH, + pixel_stride: 2, + }, + CameraFramePlaneRef::empty(), + ], + }; + + let (rgb, width, height) = frame_to_rgb_max(&frame, 16).unwrap(); + assert_eq!((width, height), (16, 8)); + assert_eq!(rgb.len(), 16 * 8 * 3); + assert_eq!(&rgb[..3], &yuv_to_rgb(y_plane[0], 128, 128)); + let last_source = y_plane[28 * WIDTH + 60]; + assert_eq!(&rgb[rgb.len() - 3..], &yuv_to_rgb(last_source, 128, 128)); + } +} diff --git a/apps/fabric/src/install.rs b/apps/fabric/src/install.rs new file mode 100644 index 000000000..4813751d3 --- /dev/null +++ b/apps/fabric/src/install.rs @@ -0,0 +1,73 @@ +use makepad_ai_hub::{ + local::{InstallState, LocalModels}, + registry::LicenseRestriction, +}; +use makepad_ai_hub_ui::{ModelRowInstallState, ModelRowState}; + +pub const BODY_MODEL_ID: &str = "sam3dbody"; +pub const BODY_MODEL_ROLE: &str = "native-body"; + +pub fn body_model_row(models: &LocalModels) -> ModelRowState { + let spec = models.spec(BODY_MODEL_ID); + let bytes_from_spec = spec + .map(|spec| spec.files.iter().filter_map(|file| file.size).sum()) + .unwrap_or(0); + let (bytes_done, bytes_total, state) = match models.install_state(BODY_MODEL_ID) { + InstallState::NotInstalled { bytes_total } => { + (0, bytes_total.max(bytes_from_spec), ModelRowInstallState::NotInstalled) + } + InstallState::Partial { + bytes_done, + bytes_total, + } => (bytes_done, bytes_total, ModelRowInstallState::NotInstalled), + InstallState::Installed => ( + bytes_from_spec, + bytes_from_spec, + ModelRowInstallState::Installed, + ), + }; + let license = spec.and_then(|spec| spec.license.as_ref()); + ModelRowState { + model_id: BODY_MODEL_ID.to_string(), + name: "SAM 3D Body".to_string(), + bytes_total, + bytes_done, + state, + license_name: license + .map(|license| license.name.clone()) + .unwrap_or_else(|| "Licence unavailable".to_string()), + restriction: license + .map(|license| restriction_name(license.restriction).to_string()) + .unwrap_or_else(|| "restricted".to_string()), + } +} + +pub fn body_model_status(models: &LocalModels, downloading: bool) -> String { + if !models.license_acknowledged(BODY_MODEL_ID) { + return "licence not accepted".to_string(); + } + match models.install_state(BODY_MODEL_ID) { + InstallState::Installed => "installed · 2.8 GB · Metal".to_string(), + InstallState::NotInstalled { .. } => "not installed · 2.8 GB".to_string(), + InstallState::Partial { + bytes_done, + bytes_total, + } => { + let percent = bytes_done.saturating_mul(100) / bytes_total.max(1); + if downloading { + format!("downloading {percent} %") + } else { + format!("not installed · {percent} % downloaded") + } + } + } +} + +fn restriction_name(restriction: LicenseRestriction) -> &'static str { + match restriction { + LicenseRestriction::None => "none", + LicenseRestriction::NonCommercial => "non-commercial", + LicenseRestriction::Community => "community", + LicenseRestriction::Restricted => "restricted", + } +} diff --git a/apps/fabric/src/main.rs b/apps/fabric/src/main.rs new file mode 100644 index 000000000..cd0394cd6 --- /dev/null +++ b/apps/fabric/src/main.rs @@ -0,0 +1,1793 @@ +mod body_view; +mod camera; +mod install; +mod pattern_view; +mod pipeline; + +use body_view::FabricBodyView; +use camera::{install_camera, pick_camera, CameraMailbox}; +use install::{body_model_row, body_model_status, BODY_MODEL_ID, BODY_MODEL_ROLE}; +use makepad_ai_hub::local::{InstallState, LocalModels}; +use makepad_ai_hub_ui::{ModelInstallPanel, ModelRowInstallState}; +use makepad_fabric_draft::{ + designs, nest, to_pdf, to_svg, Design, OptionSpec, Options, PageSize, Pattern, +}; +use makepad_fabric_measure::{Measurements, MEASUREMENT_KEYS}; +use makepad_widgets::*; +use pattern_view::FabricPatternView; +use pipeline::{Pipeline, PipelineMessage}; +use std::{ + collections::VecDeque, + path::{Path, PathBuf}, + time::{Duration, Instant, SystemTime, UNIX_EPOCH}, +}; + +app_main!(App); + +script_mod! { + use mod.prelude.widgets.* + use mod.widgets.* + + let SectionTitle = Label { + width: Fill + height: 20 + draw_text +: { + color: #x8da0b5 + text_style: theme.font_bold{font_size: 9.0} + } + } + + let Hint = Label { + width: Fill + height: Fit + draw_text +: { + color: #x667789 + text_style: theme.font_regular{font_size: 9.0} + } + } + + let Status = Label { + width: Fill + height: Fit + draw_text +: { + color: #xa9b6c4 + text_style: theme.font_regular{font_size: 9.0} + } + } + + let ToolButton = Button { + height: 30 + draw_bg +: { + color: #x27313c + color_hover: #x334252 + color_down: #x1d252e + border_color: #x52677c + border_size: 1.0 + border_radius: 3.0 + } + draw_text +: { + color: #xe7edf3 + color_hover: #xffffffff + text_style: theme.font_bold{font_size: 9.5} + } + } + + let CameraImage = Image { + draw_bg +: { + bbox: uniform(vec4(-1.0, -1.0, -1.0, -1.0)) + mirror: uniform(1.0) + pixel: fn() { + let scale = self.fit_scale * self.image_scale + let pan = self.fit_pan * self.image_scale + self.image_pan + let sample_scale = vec2(scale.x * mix(1.0, -1.0, self.mirror), scale.y) + let sample_pan = vec2(mix(pan.x, 1.0 - pan.x, self.mirror), pan.y) + let color = self.get_color_scale_pan(sample_scale, sample_pan) + if self.bbox.x >= 0.0 { + let line = vec2(1.5, 1.5) / self.rect_size + let on_x = (abs(self.pos.x - self.bbox.x) < line.x || abs(self.pos.x - self.bbox.z) < line.x) + && self.pos.y >= self.bbox.y && self.pos.y <= self.bbox.w + let on_y = (abs(self.pos.y - self.bbox.y) < line.y || abs(self.pos.y - self.bbox.w) < line.y) + && self.pos.x >= self.bbox.x && self.pos.x <= self.bbox.z + if on_x || on_y { + return Pal.premul(#x54d59a) + } + } + return Pal.premul(color) + } + } + } + + let TabButton = Button { + height: 24 + padding: Inset{left: 12 right: 12 top: 4 bottom: 4} + draw_bg +: { + color: #x1b232c + color_hover: #x2a3542 + color_down: #x151b22 + border_color: #x1b232c + border_size: 1.0 + border_radius: 3.0 + } + draw_text +: { + color: #x9aa8b7 + color_hover: #xffffffff + text_style: theme.font_bold{font_size: 9.0} + } + } + mod.widgets.FabricMeasurementGridBase = #(FabricMeasurementGrid::register_widget(vm)) + mod.widgets.FabricMeasurementGrid = set_type_default() do mod.widgets.FabricMeasurementGridBase { + width: Fill + height: Fill + grid := DataGrid { + width: Fill + height: Fill + rows: 25 + cols: 2 + default_col_width: 110.0 + default_row_height: 24.0 + row_header_width: 30.0 + color_bg: #x161d25 + color_cell: #x1a222c + color_cell_alt: #x1d2631 + color_text: #xdbe4ee + color_header: #x222c38 + color_header_active: #x2f3d4d + color_header_text: #x9aa8b7 + color_selection: #x4fa3ff26 + color_selection_border: #x4fa3ff + draw_text +: {color: #xdbe4ee} + draw_text_bold +: {color: #xdbe4ee} + Editor := TextInput { + width: Fill + height: Fill + margin: 0 + padding: Inset{left: 4 right: 4 top: 4 bottom: 3} + draw_bg +: { + border_radius: 0.0 + border_size: 2.0 + border_color: #x4fa3ff + border_color_hover: #x4fa3ff + border_color_focus: #x4fa3ff + color: #x0f151c + color_hover: #x0f151c + color_focus: #x0f151c + } + draw_text +: { + text_style: theme.font_code{font_size: 9.0} + color: #xffffffff + } + } + } + } + mod.widgets.FabricOptionsListBase = #(FabricOptionsList::register_widget(vm)) + mod.widgets.FabricOptionsList = set_type_default() do mod.widgets.FabricOptionsListBase { + width: Fill + height: Fill + empty := Hint{text: "this design has no options"} + list := PortalList { + width: Fill + height: Fill + flow: Down + drag_scrolling: true + Row := View { + width: Fill + height: 46 + flow: Down + spacing: 2 + option_caption := View { + width: Fill + height: Fit + flow: Right + option_name := Label { + width: Fill + height: Fit + draw_text +: { + color: #xa9b6c4 + text_style: theme.font_regular{font_size: 8.5} + } + } + option_unit := Label { + width: Fit + height: Fit + draw_text +: { + color: #x667789 + text_style: theme.font_regular{font_size: 8.0} + } + } + } + option_slider := Slider { + width: Fill + height: 24 + min: 0.0 + max: 100.0 + default: 0.0 + precision: 1 + text: "" + } + } + } + } + + startup() do #(App::script_component(vm)) { + ui: Root { + main_window := Window { + window.title: "Fabric" + window.inner_size: vec2(1400, 900) + pass +: {clear_color: #x0b1016} + body +: { + width: Fill + height: Fill + flow: Right + spacing: 1 + padding: 0 + // Events go to children in draw order here, first come first + // served: the licence modal lives inside the LEFT column and + // must get a click before the body view under it does. + event_order: EventOrder.Down + + left_panel := SolidView { + width: 320 + height: Fill + flow: Down + spacing: 8 + padding: 14 + draw_bg +: {color: #x161d25} + + Label { + width: Fill + height: 28 + text: "FABRIC" + draw_text +: { + color: #xf0f4f8 + text_style: theme.font_bold{font_size: 15.0} + } + } + SectionTitle{text: "BODY MODEL"} + model_install := mod.widgets.ModelInstallPanel { + width: Fill + height: 142 + } + model_status := Status{text: "checking model…"} + + SectionTitle{text: "PHOTO"} + drop_zone := RoundedView { + width: Fill + height: 225 + flow: Down + spacing: 7 + padding: 10 + align: Align{x: 0.5 y: 0.5} + show_bg: true + draw_bg +: { + color: #x111820 + border_color: #x405164 + border_size: 1.0 + border_radius: 4.0 + pixel: fn() { + let p = self.pos * self.rect_size + let edge_x = min(p.x, self.rect_size.x - p.x) + let edge_y = min(p.y, self.rect_size.y - p.y) + let edge = min(edge_x, edge_y) + let along = if edge_x < edge_y p.y else p.x + if edge < self.border_size && modf(along, 10.0) < 6.0 { + return Pal.premul(self.border_color) + } + return Pal.premul(self.color) + } + } + photo_image := Image { + width: Fill + height: 163 + fit: ImageFit.Smallest + visible: false + } + live_image := CameraImage { + width: Fill + height: 163 + fit: ImageFit.Smallest + visible: false + } + drop_title := Label { + width: Fill + height: Fit + text: "drop a photo" + draw_text +: { + color: #xd1dae4 + text_style: theme.font_bold{font_size: 11.0} + } + } + drop_help := Hint { + text: "front view · tight clothes · whole body in frame" + } + photo_name := Hint{text: "JPG or PNG"} + } + + View { + width: Fill + height: 29 + flow: Right + spacing: 8 + align: Align{x: 0.0 y: 0.5} + Label { + width: 58 + height: Fit + text: "HEIGHT" + draw_text +: { + color: #x8da0b5 + text_style: theme.font_bold{font_size: 9.0} + } + } + height_input := TextInput { + width: Fill + height: 25 + empty_text: "optional" + } + Label { + width: 22 + height: Fit + text: "cm" + draw_text +: {color: #x667789} + } + } + View { + width: Fill + height: 30 + flow: Right + spacing: 8 + measure_button := ToolButton { + width: Fill + text: "MEASURE" + } + live_button := ToolButton { + width: 78 + text: "LIVE" + } + mirror_toggle := Toggle { + width: 88 + height: 30 + text: "MIRROR" + active: true + } + } + progress_status := Status{text: "drop a photo to begin"} + } + + centre_panel := SolidView { + width: Fill + height: Fill + flow: Down + draw_bg +: {color: #x11161d} + split := Splitter { + width: Fill + height: Fill + axis: SplitterAxis.Horizontal + align: SplitterAlign.Weighted(0.42) + size: 6.0 + draw_bg +: { + color_bg: #x11161d + color: #x1f2731 + color_hover: #x2f3d4d + color_drag: #x4fa3ff + } + a: View { + width: Fill + height: Fill + flow: Down + View { + width: Fill + height: 38 + flow: Right + spacing: 10 + padding: Inset{left: 14 right: 14} + align: Align{x: 0.0 y: 0.5} + SectionTitle{width: Fit text: "BODY"} + Hint{text: "drag orbit · shift-drag pan · wheel zoom · double-click reset"} + } + body_preview := mod.widgets.FabricBodyView {} + } + b: View { + width: Fill + height: Fill + flow: Right + View { + width: Fill + height: Fill + flow: Down + View { + width: Fill + height: 38 + flow: Right + spacing: 10 + padding: Inset{left: 14 right: 14} + align: Align{x: 0.0 y: 0.5} + SectionTitle{width: Fit text: "PATTERN"} + settling_tag := RoundedView { + width: Fit + height: 18 + padding: Inset{left: 7 right: 7 top: 2 bottom: 2} + visible: false + show_bg: true + draw_bg +: {color: #x493d24 border_radius: 9.0} + Label { + width: Fit + height: Fit + text: "settling…" + draw_text +: { + color: #xe8c36d + text_style: theme.font_regular{font_size: 8.0} + } + } + } + Hint{text: "drag pan · wheel zoom · cut line solid, seam line dim"} + } + pattern_preview := mod.widgets.FabricPatternView {} + } + design_column := SolidView { + width: 232 + height: Fill + flow: Down + spacing: 8 + padding: 12 + draw_bg +: {color: #x141a22} + SectionTitle{text: "DESIGN"} + design_select := DropDown { + width: Fill + height: 28 + labels: ["No designs available"] + } + design_options := mod.widgets.FabricOptionsList { + width: Fill + height: Fill + } + export_svg := ToolButton{width: Fill text: "EXPORT SVG"} + export_pdf := ToolButton{width: Fill text: "EXPORT PDF (A4)"} + app_status := Status{text: "sample measurements ready"} + } + } + } + } + right_panel := SolidView { + width: 380 + height: Fill + flow: Down + spacing: 8 + padding: 14 + draw_bg +: {color: #x161d25} + View { + width: Fill + height: 20 + flow: Right + spacing: 8 + align: Align{x: 0.0 y: 0.5} + SectionTitle{width: Fill text: "MEASUREMENTS"} + sample_tag := RoundedView { + width: Fit + height: 18 + padding: Inset{left: 7 right: 7 top: 2 bottom: 2} + show_bg: true + draw_bg +: {color: #x293440 border_radius: 9.0} + sample_tag_label := Label { + width: Fit + height: Fit + text: "sample body" + draw_text +: { + color: #x8998a8 + text_style: theme.font_regular{font_size: 8.0} + } + } + } + copy_all := TabButton{ + height: 20 + padding: Inset{left: 8 right: 8 top: 2 bottom: 2} + text: "COPY ALL" + } + } + measurement_grid := mod.widgets.FabricMeasurementGrid { + width: Fill + height: Fill + } + Hint{text: "click and drag to select · ⌘C copies as tab-separated text · double-click a value to correct it"} + } + } + } + } + } +} +#[derive(Clone, Debug, Default)] +enum MeasurementListAction { + Changed { key: &'static str, value: f32 }, + #[default] + None, +} + +/// The measurement table as a spreadsheet grid: keys down, centimetres in +/// the second column, so a selection copies as tab-separated text straight +/// into a spreadsheet. Double-click (or type on) a value to correct it. +#[derive(Script, ScriptHook, Widget)] +struct FabricMeasurementGrid { + #[source] + source: ScriptObjectRef, + #[deref] + view: View, + #[rust] + values: Measurements, + #[rust(true)] + sample: bool, + #[rust] + initialized: bool, + /// The row whose value is being edited in place. + #[rust] + editing: Option, + /// The text the editor starts with; taken on the draw that seeds it. + #[rust] + edit_seed: Option, +} + +impl FabricMeasurementGrid { + fn set_measurements(&mut self, cx: &mut Cx, values: Measurements, sample: bool) { + self.values = values; + self.sample = sample; + self.refresh_copy_provider(cx); + self.view.redraw(cx); + } + + /// Tab-separated rows for a selection; every row when nothing is selected. + fn tsv(&self, selection: Option) -> String { + let entries = self.values.entries(); + let last = entries.len() - 1; + let (r0, r1, c0, c1) = match selection { + Some(sel) => { + let (r0, r1) = sel.row_range(); + let (c0, c1) = sel.col_range(); + (r0.min(last), r1.min(last), c0.min(1), c1.min(1)) + } + None => (0, last, 0, 1), + }; + let mut out = String::new(); + for (key, value) in &entries[r0..=r1] { + let mut cols: Vec = Vec::new(); + if c0 == 0 { + cols.push(humanise_key(key)); + } + if c1 == 1 { + cols.push(format!("{value:.1}")); + } + out.push_str(&cols.join("\t")); + out.push('\n'); + } + out + } + + fn refresh_copy_provider(&self, cx: &mut Cx) { + let grid = self.view.data_grid(cx, ids!(grid)); + let text = self.tsv(grid.selection()); + grid.set_copy_provider(Box::new(move |_sel| text.clone())); + } + + fn start_edit(&mut self, cx: &mut Cx, row: usize, replace: Option) { + if row >= MEASUREMENT_KEYS.len() { + return; + } + self.editing = Some(row); + self.edit_seed = Some( + replace.unwrap_or_else(|| format!("{:.1}", self.values.entries()[row].1)), + ); + let grid = self.view.data_grid(cx, ids!(grid)); + grid.set_selection(cx, Some(GridSelection::single(row, 1))); + grid.redraw(cx); + } + + fn commit_edit(&mut self, cx: &mut Cx, row: usize, text: &str) { + self.editing = None; + self.edit_seed = None; + if let Some(&key) = MEASUREMENT_KEYS.get(row) { + if let Ok(value) = text.trim().replace(',', ".").parse::() { + if value.is_finite() && value > 0.0 && self.values.set(key, value) { + cx.widget_action( + self.widget_uid(), + MeasurementListAction::Changed { key, value }, + ); + } + } + } + self.refresh_copy_provider(cx); + self.view.data_grid(cx, ids!(grid)).redraw(cx); + } + + fn commit_current(&mut self, cx: &mut Cx) { + let Some(row) = self.editing else { return }; + let text = self + .view + .data_grid(cx, ids!(grid)) + .get_item(row, 1) + .map(|(_, widget)| widget.as_text_input().text()); + match text { + Some(text) => self.commit_edit(cx, row, &text), + None => self.cancel_edit(cx), + } + } + + fn cancel_edit(&mut self, cx: &mut Cx) { + self.editing = None; + self.edit_seed = None; + self.view.data_grid(cx, ids!(grid)).redraw(cx); + } +} + +impl Widget for FabricMeasurementGrid { + fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) { + self.view.handle_event(cx, event, scope); + let Event::Actions(actions) = event else { + return; + }; + let grid = self.view.data_grid(cx, ids!(grid)); + for action in grid.actions(actions) { + match action { + DataGridAction::EditCell { row, col, replace } if col == 1 => { + self.start_edit(cx, row, replace); + } + DataGridAction::CellDoubleClicked { row, col } if col == 1 => { + self.start_edit(cx, row, None); + } + DataGridAction::CellClicked { .. } => { + if self.editing.is_some() { + self.commit_current(cx); + } + } + DataGridAction::SelectionChanged { .. } => self.refresh_copy_provider(cx), + _ => {} + } + } + for (row, _col, widget) in grid.cell_widgets_with_actions(actions) { + let input = widget.as_text_input(); + if let Some((text, _modifiers)) = input.returned(actions) { + self.commit_edit(cx, row, &text); + } else if input.escaped(actions) { + self.cancel_edit(cx); + } + } + } + + fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep { + while let Some(step) = self.view.draw_walk(cx, scope, walk).step() { + let grid_ref = step.as_data_grid(); + let Some(mut grid) = grid_ref.borrow_mut() else { + continue; + }; + if !self.initialized { + self.initialized = true; + grid.set_col_labels(vec!["measurement".to_string(), "cm".to_string()]); + grid.set_col_width(0, 190.0); + grid.set_col_width(1, 84.0); + } + grid.set_grid_size(MEASUREMENT_KEYS.len(), 2); + let entries = self.values.entries(); + let value_color = if self.sample { + vec4(0.55, 0.61, 0.67, 1.0) + } else { + vec4(0.92, 0.95, 0.98, 1.0) + }; + let key_color = vec4(0.66, 0.72, 0.78, 1.0); + while let Some(cell) = grid.next_cell(cx) { + let Some((key, value)) = entries.get(cell.row).copied() else { + continue; + }; + if cell.col == 1 && self.editing == Some(cell.row) { + if let Some(item) = grid.item(cx, cell.row, cell.col, id!(Editor)) { + let seed = self.edit_seed.take(); + if let Some(seed) = &seed { + item.as_text_input().set_text(cx, seed); + } + grid.draw_item(cx, &cell, &item, None); + // Focus only once the editor has a drawn area. + if seed.is_some() { + item.as_text_input().take_key_focus(cx); + } + } + continue; + } + let (text, align, color) = if cell.col == 0 { + (humanise_key(key), 0.0, key_color) + } else { + (format!("{value:.1}"), 1.0, value_color) + }; + grid.cell_text_styled( + cx, + &cell, + &text, + CellStyle { + align, + color: Some(color), + ..CellStyle::default() + }, + ); + } + } + DrawStep::done() + } +} + +#[derive(Clone, Debug, Default)] +enum OptionsListAction { + Changed { key: String, value: f64 }, + #[default] + None, +} + +#[derive(Script, ScriptHook, Widget)] +struct FabricOptionsList { + #[source] + source: ScriptObjectRef, + #[deref] + view: View, + #[rust] + specs: Vec, + #[rust] + values: Vec, +} + +impl FabricOptionsList { + fn set_specs(&mut self, cx: &mut Cx, specs: Vec, options: &Options) { + self.values = specs.iter().map(|spec| options.get(spec)).collect(); + self.specs = specs; + self.view.label(cx, ids!(empty)).set_visible(cx, self.specs.is_empty()); + self.view + .portal_list(cx, ids!(list)) + .set_visible(cx, !self.specs.is_empty()); + self.view.redraw(cx); + } +} + +impl Widget for FabricOptionsList { + fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) { + self.view.handle_event(cx, event, scope); + let Event::Actions(actions) = event else { + return; + }; + let list = self.view.portal_list(cx, ids!(list)); + for (index, item) in list.items_with_actions(actions) { + let Some(spec) = self.specs.get(index) else { + continue; + }; + if let Some(value) = item.slider(cx, ids!(option_slider)).slided(actions) { + if let Some(slot) = self.values.get_mut(index) { + *slot = value; + } + cx.widget_action( + self.widget_uid(), + OptionsListAction::Changed { + key: spec.key.to_string(), + value, + }, + ); + } + } + } + + fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep { + while let Some(item) = self.view.draw_walk(cx, scope, walk).step() { + let Some(mut list) = item.borrow_mut::() else { + continue; + }; + list.set_item_range(cx, 0, self.specs.len()); + while let Some(index) = list.next_visible_item(cx) { + let row = list.item(cx, index, id!(Row)); + if let (Some(spec), Some(value)) = (self.specs.get(index), self.values.get(index)) { + row.label(cx, ids!(option_name)).set_text(cx, spec.label); + row.label(cx, ids!(option_unit)).set_text(cx, spec.unit); + let mut slider = row.slider(cx, ids!(option_slider)); + let min = spec.min; + let max = spec.max; + let default = spec.default; + let step = ((max - min).abs() / 100.0).max(0.01); + script_apply_eval!(cx, slider, { + min: #(min) + max: #(max) + default: #(default) + step: #(step) + }); + slider.set_value(cx, *value); + } + row.draw_all_unscoped(cx); + } + } + DrawStep::done() + } +} + +const SETTLE_AFTER: Duration = Duration::from_millis(1_500); +const SETTLE_TOLERANCE_CM: f32 = 0.5; + +#[derive(Default)] +struct MeasurementSettler { + history: VecDeque<(Duration, Measurements)>, + settled: bool, +} + +impl MeasurementSettler { + /// Returns true only on the transition into a settled state, so a stable + /// live stream drafts once instead of rebuilding the pattern every frame. + fn push(&mut self, now: Duration, measurements: Measurements) -> bool { + self.history.push_back((now, measurements)); + let Some(cutoff) = now.checked_sub(SETTLE_AFTER) else { + self.settled = false; + return false; + }; + while self.history.len() > 1 + && self + .history + .get(1) + .is_some_and(|(time, _)| *time <= cutoff) + { + self.history.pop_front(); + } + let stable = self + .history + .front() + .filter(|(time, _)| *time <= cutoff) + .is_some_and(|(_, previous)| { + measurements.entries().iter().all(|(key, value)| { + previous + .get(key) + .is_some_and(|old| (value - old).abs() <= SETTLE_TOLERANCE_CM) + }) + }); + let became_settled = stable && !self.settled; + self.settled = stable; + became_settled + } + + fn reset(&mut self) { + self.history.clear(); + self.settled = false; + } +} + +#[derive(Script, ScriptHook)] +pub struct App { + #[live] + ui: WidgetRef, + #[rust] + models: Option, + #[rust] + pipeline: Option, + #[rust] + refresh_timer: Timer, + #[rust] + photo: Option, + #[rust] + pipeline_busy: bool, + #[rust] + pipeline_started: Option, + #[rust] + camera: CameraMailbox, + #[rust] + camera_installed: bool, + #[rust] + live: bool, + #[rust(true)] + mirrored: bool, + #[rust] + live_started: Option, + #[rust] + preview_texture: Option, + #[rust] + preview_serial: u64, + #[rust] + live_bbox: Option<[f32; 4]>, + #[rust] + live_frame_size: Option<(u32, u32)>, + #[rust] + settler: MeasurementSettler, + #[rust] + measurements: Measurements, + #[rust] + has_measured_body: bool, + #[rust] + designs: Vec>, + #[rust] + design_index: usize, + #[rust] + options: Options, + #[rust] + pattern: Option, + #[rust] + model_ready: bool, + #[rust] + drag_over: bool, +} + +impl App { + fn startup(&mut self, cx: &mut Cx) { + self.pipeline = Some(Pipeline::new()); + self.refresh_timer = cx.start_interval(0.1); + self.measurements = Measurements::sample(); + self.sync_measurements(cx); + self.designs = designs(); + let labels = if self.designs.is_empty() { + vec!["No designs available".to_string()] + } else { + self.designs + .iter() + .map(|design| design.name().to_string()) + .collect() + }; + self.ui + .drop_down(cx, ids!(design_select)) + .set_labels(cx, labels); + self.configure_options(cx); + self.redraft(cx); + + match LocalModels::open() { + Ok(models) => { + let row = body_model_row(&models); + let panel = self.ui.widget(cx, ids!(model_install)); + if let Some(mut panel) = panel.borrow_mut::() { + panel.set_rows(cx, vec![row]); + } + self.models = Some(models); + self.refresh_model_ui(cx); + } + Err(error) => { + self.set_progress(cx, format!("could not open local models: {error}")); + self.ui + .label(cx, ids!(model_status)) + .set_text(cx, "model registry unavailable"); + self.ui + .button(cx, ids!(measure_button)) + .set_disabled(cx, true); + self.ui + .button(cx, ids!(live_button)) + .set_disabled(cx, true); + } + } + } + + fn sync_measurements(&self, cx: &mut Cx) { + let widget = self.ui.widget(cx, ids!(measurement_grid)); + if let Some(mut grid) = widget.borrow_mut::() { + grid.set_measurements(cx, self.measurements, !self.has_measured_body); + } + self.ui + .view(cx, ids!(sample_tag)) + .set_visible(cx, self.live || !self.has_measured_body); + self.ui + .label(cx, ids!(sample_tag_label)) + .set_text(cx, if self.live { "live body" } else { "sample body" }); + } + + fn configure_options(&mut self, cx: &mut Cx) { + self.options = Options::default(); + let specs = self + .designs + .get(self.design_index) + .map(|design| design.options()) + .unwrap_or_default(); + for spec in &specs { + self.options.0.insert(spec.key.to_string(), spec.default); + } + let widget = self.ui.widget(cx, ids!(design_options)); + if let Some(mut list) = widget.borrow_mut::() { + list.set_specs(cx, specs, &self.options); + }; + } + + fn redraft(&mut self, cx: &mut Cx) { + let Some(design) = self.designs.get(self.design_index) else { + self.pattern = None; + self.set_pattern_error(cx, "no designs are available from the draft library"); + self.set_app_status(cx, "sample body ready · waiting for a draft design"); + return; + }; + match design.draft(&self.measurements, &self.options) { + Ok(pattern) => { + self.pattern = Some(pattern.clone()); + let widget = self.ui.widget(cx, ids!(pattern_preview)); + if let Some(mut view) = widget.borrow_mut::() { + view.set_pattern(cx, pattern); + } + self.set_app_status(cx, format!("{} pattern ready", design.name())); + } + Err(error) => { + self.pattern = None; + self.set_pattern_error(cx, error.to_string()); + self.set_app_status(cx, error.to_string()); + } + } + } + + fn set_pattern_error(&self, cx: &mut Cx, error: impl Into) { + let widget = self.ui.widget(cx, ids!(pattern_preview)); + if let Some(mut view) = widget.borrow_mut::() { + view.set_error(cx, error); + }; + } + + fn set_progress(&self, cx: &mut Cx, status: impl AsRef) { + self.ui + .label(cx, ids!(progress_status)) + .set_text(cx, status.as_ref()); + } + + fn set_app_status(&self, cx: &mut Cx, status: impl AsRef) { + self.ui + .label(cx, ids!(app_status)) + .set_text(cx, status.as_ref()); + } + + fn panel_is_downloading(&self, cx: &mut Cx) -> bool { + let panel = self.ui.widget(cx, ids!(model_install)); + panel + .borrow::() + .map(|panel| { + panel.rows().iter().any(|row| { + row.model_id == BODY_MODEL_ID + && matches!(row.state, ModelRowInstallState::Downloading) + }) + }) + .unwrap_or(false) + } + + fn refresh_model_ui(&mut self, cx: &mut Cx) { + let downloading = self.panel_is_downloading(cx); + let ready = self.models.as_ref().is_some_and(|models| { + models.license_acknowledged(BODY_MODEL_ID) + && matches!(models.install_state(BODY_MODEL_ID), InstallState::Installed) + && models + .installed_path(BODY_MODEL_ID, BODY_MODEL_ROLE) + .is_some() + }); + if let Some(models) = self.models.as_ref() { + self.ui + .label(cx, ids!(model_status)) + .set_text(cx, &body_model_status(models, downloading)); + } + self.ui + .button(cx, ids!(measure_button)) + .set_disabled(cx, !ready || self.pipeline_busy || self.photo.is_none()); + self.ui + .button(cx, ids!(live_button)) + .set_disabled(cx, !self.live && (!ready || self.pipeline_busy)); + let became_ready = ready && !self.model_ready; + self.model_ready = ready; + if became_ready && self.photo.is_some() && !self.pipeline_busy { + self.start_measurement(cx); + } + } + + fn start_measurement(&mut self, cx: &mut Cx) { + if self.pipeline_busy { + return; + } + let Some(photo) = self.photo.clone() else { + self.set_progress(cx, "drop a photo first"); + return; + }; + let (weights, height_cm) = match self.pipeline_inputs(cx) { + Ok(inputs) => inputs, + Err(error) => { + self.set_progress(cx, error); + return; + } + }; + let Some(pipeline) = self.pipeline.as_ref() else { + self.set_progress(cx, "the body model worker is unavailable"); + return; + }; + match pipeline.run(photo, weights, height_cm) { + Ok(()) => { + self.pipeline_busy = true; + self.pipeline_started = Some(Instant::now()); + self.set_progress(cx, "queued…"); + self.refresh_model_ui(cx); + } + Err(error) => self.set_progress(cx, error), + } + } + + fn pipeline_inputs(&self, cx: &mut Cx) -> Result<(PathBuf, Option), String> { + let models = self + .models + .as_ref() + .ok_or_else(|| "install the body model first".to_string())?; + if !models.license_acknowledged(BODY_MODEL_ID) { + return Err("accept the body model licence first".to_string()); + } + let weights = models + .installed_path(BODY_MODEL_ID, BODY_MODEL_ROLE) + .ok_or_else(|| "install the body model first".to_string())?; + let height_text = self.ui.text_input(cx, ids!(height_input)).text(); + let height_cm = if height_text.trim().is_empty() { + None + } else { + match height_text.trim().parse::() { + Ok(value) if value.is_finite() && (80.0..=260.0).contains(&value) => Some(value), + _ => return Err("height must be 80–260 cm, or left empty".to_string()), + } + }; + Ok((weights, height_cm)) + } + + fn start_live(&mut self, cx: &mut Cx) { + if self.live || self.pipeline_busy { + return; + } + let (weights, height_cm) = match self.pipeline_inputs(cx) { + Ok(inputs) => inputs, + Err(error) => { + self.set_progress(cx, error); + return; + } + }; + use makepad_widgets::makepad_platform::permission::Permission; + cx.request_permission(Permission::Camera); + if !self.camera_installed { + install_camera(cx, self.camera.clone()); + self.camera_installed = true; + } + let Some(pipeline) = self.pipeline.as_ref() else { + self.set_progress(cx, "the body model worker is unavailable"); + return; + }; + if let Err(error) = pipeline.start_live(weights, height_cm, self.camera.clone()) { + self.set_progress(cx, error); + return; + } + + self.live = true; + self.live_started = Some(Instant::now()); + self.live_bbox = None; + self.live_frame_size = None; + self.settler.reset(); + self.set_live_ui(cx); + self.set_progress(cx, "live · looking for a camera…"); + self.refresh_model_ui(cx); + } + + fn stop_live(&mut self, cx: &mut Cx) { + if !self.live { + return; + } + cx.use_video_input(&[]); + if let Some(pipeline) = self.pipeline.as_ref() { + pipeline.stop_live(); + } + self.live = false; + self.live_started = None; + self.live_bbox = None; + self.live_frame_size = None; + self.settler.reset(); + self.set_live_ui(cx); + self.set_progress( + cx, + if self.pipeline_busy { + "live stopped · queued photo next" + } else { + "live stopped" + }, + ); + self.refresh_model_ui(cx); + } + + fn set_live_ui(&self, cx: &mut Cx) { + self.ui + .image(cx, ids!(live_image)) + .set_visible(cx, self.live); + self.ui + .image(cx, ids!(photo_image)) + .set_visible(cx, !self.live && self.photo.is_some()); + self.ui + .label(cx, ids!(drop_title)) + .set_text(cx, if self.live { "live camera" } else if self.photo.is_some() { "photo loaded" } else { "drop a photo" }); + let photo_name = if self.live { + "camera · body model runs continuously".to_string() + } else { + self.photo + .as_ref() + .and_then(|path| path.file_name()) + .map(|name| name.to_string_lossy().into_owned()) + .unwrap_or_else(|| "JPG or PNG".to_string()) + }; + self.ui + .label(cx, ids!(photo_name)) + .set_text(cx, &photo_name); + self.ui + .view(cx, ids!(settling_tag)) + .set_visible(cx, self.live && !self.settler.settled); + + let color = if self.live { + Vec4f { + x: 0.08, + y: 0.38, + z: 0.24, + w: 1.0, + } + } else { + Vec4f { + x: 0.153, + y: 0.192, + z: 0.235, + w: 1.0, + } + }; + let border = if self.live { + Vec4f { + x: 0.33, + y: 0.84, + z: 0.60, + w: 1.0, + } + } else { + Vec4f { + x: 0.322, + y: 0.404, + z: 0.486, + w: 1.0, + } + }; + let mut button = self.ui.button(cx, ids!(live_button)); + script_apply_eval!(cx, button, { + draw_bg +: { + color: #(color) + border_color: #(border) + } + }); + self.update_live_bbox(cx); + self.sync_measurements(cx); + } + + fn set_mirrored(&mut self, cx: &mut Cx, mirrored: bool) { + self.mirrored = mirrored; + self.ui + .image(cx, ids!(live_image)) + .set_uniform( + cx, + live_id!(mirror), + &[if mirrored { 1.0 } else { 0.0 }], + ); + let widget = self.ui.widget(cx, ids!(body_preview)); + if let Some(mut view) = widget.borrow_mut::() { + view.set_mirrored(cx, mirrored); + } + self.update_live_bbox(cx); + } + + fn pump_camera_preview(&mut self, cx: &mut Cx) { + if !self.live { + return; + } + let Some(frame) = self.camera.peek_preview() else { + return; + }; + if frame.serial <= self.preview_serial { + return; + } + self.preview_serial = frame.serial; + let pixels: Vec = frame + .rgb + .chunks_exact(3) + .map(|rgb| { + 0xff00_0000 | (u32::from(rgb[0]) << 16) | (u32::from(rgb[1]) << 8) | u32::from(rgb[2]) + }) + .collect(); + if let Some(texture) = self.preview_texture.as_ref() { + texture.set_data_u32(cx, frame.width as usize, frame.height as usize, pixels); + } else { + self.preview_texture = Some(Texture::new_with_format( + cx, + TextureFormat::VecBGRAu8_32 { + width: frame.width as usize, + height: frame.height as usize, + data: Some(pixels), + updated: TextureUpdated::Full, + }, + )); + } + self.ui + .image(cx, ids!(live_image)) + .set_texture(cx, self.preview_texture.clone()); + self.ui.widget(cx, ids!(live_image)).redraw(cx); + } + + fn update_live_bbox(&self, cx: &mut Cx) { + let bbox = self + .live_bbox + .zip(self.live_frame_size) + .map(|(bbox, (width, height))| { + [ + (bbox[0] / width as f32).clamp(0.0, 1.0), + (bbox[1] / height as f32).clamp(0.0, 1.0), + (bbox[2] / width as f32).clamp(0.0, 1.0), + (bbox[3] / height as f32).clamp(0.0, 1.0), + ] + }) + .unwrap_or([-1.0; 4]); + let bbox = mirror_normalized_bbox(bbox, self.mirrored); + self.ui + .image(cx, ids!(live_image)) + .set_uniform(cx, live_id!(bbox), &bbox); + self.ui.widget(cx, ids!(live_image)).redraw(cx); + } + + fn drain_pipeline(&mut self, cx: &mut Cx) { + let messages = self + .pipeline + .as_ref() + .map(Pipeline::poll) + .unwrap_or_default(); + for message in messages { + match message { + PipelineMessage::Stage(stage) => { + if self.live { + self.set_progress(cx, format!("live · {stage}")); + } else { + self.set_progress(cx, stage); + } + } + PipelineMessage::LiveFrame { + fps, + model_ms, + pose_ms, + person, + bbox, + } => { + if !self.live { + continue; + } + self.live_bbox = bbox; + self.live_frame_size = self.camera.model_size(); + self.update_live_bbox(cx); + if person { + self.set_progress( + cx, + format!( + "live · {fps:.1} fps · model {model_ms:.0} ms · pose {pose_ms:.1} ms · person" + ), + ); + } else { + self.set_progress(cx, "live · no person in frame"); + } + } + PipelineMessage::Done { + measured, + mesh, + posed, + pose_mapping, + reset_pose, + } => { + self.measurements = measured.values; + self.has_measured_body = true; + self.sync_measurements(cx); + let widget = self.ui.widget(cx, ids!(body_preview)); + if let Some(mut view) = widget.borrow_mut::() { + if reset_pose { + view.set_pose(cx, None); + } + view.set_body(cx, mesh, &measured, pose_mapping); + view.set_pose(cx, posed); + } + if self.live { + let now = self + .live_started + .map(|start| start.elapsed()) + .unwrap_or_default(); + let redraft = self.settler.push(now, self.measurements); + self.ui + .view(cx, ids!(settling_tag)) + .set_visible(cx, !self.settler.settled); + if redraft { + self.redraft(cx); + } + } else if self.pipeline_busy { + self.pipeline_busy = false; + let seconds = self + .pipeline_started + .take() + .map(|start| start.elapsed().as_secs_f32()) + .unwrap_or(0.0); + self.set_progress(cx, format!("done in {seconds:.1} s")); + self.redraft(cx); + } + } + PipelineMessage::Failed(error) => { + if self.live { + self.stop_live(cx); + } else { + self.pipeline_busy = false; + self.pipeline_started = None; + } + self.set_progress(cx, error); + } + } + } + self.refresh_model_ui(cx); + } + + fn accept_photo(&mut self, cx: &mut Cx, path: PathBuf) { + let Some(name) = path.file_name().map(|name| name.to_string_lossy().into_owned()) else { + self.set_progress(cx, "the dropped photo has no file name"); + return; + }; + self.photo = Some(path.clone()); + if !self.live { + self.ui + .label(cx, ids!(photo_name)) + .set_text(cx, &name); + self.ui + .label(cx, ids!(drop_title)) + .set_text(cx, "photo loaded"); + } + self.ui + .image(cx, ids!(photo_image)) + .set_visible(cx, !self.live); + if let Err(error) = self + .ui + .image(cx, ids!(photo_image)) + .load_image_file_by_path_async(cx, &path) + { + self.set_progress(cx, format!("could not decode {name}: {error}")); + return; + } + if self.model_ready { + self.start_measurement(cx); + } else { + self.set_progress(cx, "install the body model first"); + } + self.refresh_model_ui(cx); + } + + fn set_drop_highlight(&mut self, cx: &mut Cx, active: bool) { + if self.drag_over == active { + return; + } + self.drag_over = active; + let color = if active { + Vec4f { + x: 0.10, + y: 0.18, + z: 0.24, + w: 1.0, + } + } else { + Vec4f { + x: 0.067, + y: 0.094, + z: 0.125, + w: 1.0, + } + }; + let border = if active { + Vec4f { + x: 0.31, + y: 0.78, + z: 1.0, + w: 1.0, + } + } else { + Vec4f { + x: 0.25, + y: 0.32, + z: 0.39, + w: 1.0, + } + }; + let mut zone = self.ui.view(cx, ids!(drop_zone)); + script_apply_eval!(cx, zone, { + draw_bg +: { + color: #(color) + border_color: #(border) + } + }); + } + + fn handle_file_drop(&mut self, cx: &mut Cx, event: &Event) { + if !matches!(event, Event::Drag(_) | Event::Drop(_) | Event::DragEnd) { + return; + } + let area = self.ui.widget(cx, ids!(drop_zone)).area(); + match event.drag_hits(cx, area) { + DragHit::Drag(drag) => { + let accepts = drag.items.iter().any(accepted_photo_item); + *drag.response.lock().unwrap() = if accepts { + DragResponse::Copy + } else { + DragResponse::None + }; + self.set_drop_highlight(cx, accepts && drag.state != DragState::Out); + } + DragHit::Drop(drop) => { + self.set_drop_highlight(cx, false); + if let Some(path) = drop.items.iter().find_map(photo_item_path) { + self.accept_photo(cx, path); + } + } + DragHit::DragEnd | DragHit::NoHit => self.set_drop_highlight(cx, false), + } + } + + fn export(&mut self, cx: &mut Cx, extension: &str) { + let Some(pattern) = self.pattern.as_ref() else { + self.set_app_status(cx, "there is no drafted pattern to export"); + return; + }; + let layout = nest(pattern, 1500.0); + let seconds = SystemTime::now() + .duration_since(UNIX_EPOCH) + .map(|duration| duration.as_secs()) + .unwrap_or(0); + let directory = makepad_ai_hub::home::makepad_home().join("fabric/exports"); + if let Err(error) = std::fs::create_dir_all(&directory) { + self.set_app_status(cx, format!("could not create {}: {error}", directory.display())); + return; + } + let path = directory.join(export_file_name(&pattern.design_id, extension, seconds)); + let result = match extension { + "svg" => std::fs::write(&path, to_svg(pattern, &layout).as_bytes()), + "pdf" => std::fs::write(&path, to_pdf(pattern, &layout, PageSize::A4)), + _ => return, + }; + match result { + Ok(()) => self.set_app_status(cx, format!("exported {}", path.display())), + Err(error) => self.set_app_status( + cx, + format!("could not write {}: {error}", path.display()), + ), + } + } + + fn pump_install_panel(&mut self, cx: &mut Cx) { + let panel = self.ui.widget(cx, ids!(model_install)); + if let (Some(models), Some(mut panel)) = + (self.models.as_mut(), panel.borrow_mut::()) + { + panel.pump(cx, models); + }; + } +} + +impl MatchEvent for App { + fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions) { + if self.ui.button(cx, ids!(measure_button)).clicked(actions) { + self.start_measurement(cx); + } + if self.ui.button(cx, ids!(live_button)).clicked(actions) { + if self.live { + self.stop_live(cx); + } else { + self.start_live(cx); + } + } + if let Some(mirrored) = self + .ui + .check_box(cx, ids!(mirror_toggle)) + .changed(actions) + { + self.set_mirrored(cx, mirrored); + } + if let Some(index) = self.ui.drop_down(cx, ids!(design_select)).changed(actions) { + if index < self.designs.len() { + self.design_index = index; + self.configure_options(cx); + self.redraft(cx); + } + } + if self.ui.button(cx, ids!(copy_all)).clicked(actions) { + let widget = self.ui.widget(cx, ids!(measurement_grid)); + let text = widget + .borrow::() + .map(|grid| grid.tsv(None)) + .unwrap_or_default(); + cx.copy_to_clipboard(&text); + self.set_app_status(cx, "measurements copied · paste into a spreadsheet"); + } + let measurement_uid = self.ui.widget(cx, ids!(measurement_grid)).widget_uid(); + match actions.find_widget_action_cast::(measurement_uid) { + MeasurementListAction::Changed { key, value } => { + if self.measurements.set(key, value) { + self.sync_measurements(cx); + self.redraft(cx); + } + } + MeasurementListAction::None => {} + } + let options_uid = self.ui.widget(cx, ids!(design_options)).widget_uid(); + match actions.find_widget_action_cast::(options_uid) { + OptionsListAction::Changed { key, value } => { + self.options.0.insert(key, value); + self.redraft(cx); + } + OptionsListAction::None => {} + } + if self.ui.button(cx, ids!(export_svg)).clicked(actions) { + self.export(cx, "svg"); + } + if self.ui.button(cx, ids!(export_pdf)).clicked(actions) { + self.export(cx, "pdf"); + } + } +} + +impl AppMain for App { + fn script_mod(vm: &mut ScriptVm) -> ScriptValue { + makepad_widgets::script_mod(vm); + makepad_ai_hub_ui::script_mod(vm); + crate::body_view::script_mod(vm); + crate::pattern_view::script_mod(vm); + self::script_mod(vm) + } + + fn handle_event(&mut self, cx: &mut Cx, event: &Event) { + if let Event::Startup = event { + self.startup(cx); + } + self.match_event(cx, event); + self.ui.handle_event(cx, event, &mut Scope::empty()); + self.handle_file_drop(cx, event); + self.pump_install_panel(cx); + match event { + Event::VideoInputs(inputs) if self.live => { + if let Some(input) = pick_camera(inputs) { + cx.use_video_input(&[input]); + self.set_progress(cx, "live · camera ready…"); + } else { + self.set_progress(cx, "live · no NV12/YUY2 camera at 640×360"); + } + } + Event::PermissionResult(result) + if self.live + && result.permission + == makepad_widgets::makepad_platform::permission::Permission::Camera => + { + use makepad_widgets::makepad_platform::permission::PermissionStatus; + if result.status != PermissionStatus::Granted { + let status = format!("camera permission: {:?}", result.status); + self.stop_live(cx); + self.set_progress(cx, status); + } + } + _ => {} + } + if let Event::Signal = event { + self.drain_pipeline(cx); + } + if self.refresh_timer.is_event(event).is_some() { + self.pump_camera_preview(cx); + self.refresh_model_ui(cx); + } + self.refresh_model_ui(cx); + } +} + +fn accepted_photo_item(item: &DragItem) -> bool { + photo_item_path(item).is_some() +} + +fn mirror_normalized_bbox(bbox: [f32; 4], mirrored: bool) -> [f32; 4] { + if mirrored && bbox[0] >= 0.0 { + [1.0 - bbox[2], bbox[1], 1.0 - bbox[0], bbox[3]] + } else { + bbox + } +} + +fn photo_item_path(item: &DragItem) -> Option { + let DragItem::FilePath { + path, + internal_id: None, + } = item + else { + return None; + }; + let path = Path::new(path); + let extension = path.extension()?.to_str()?.to_ascii_lowercase(); + matches!(extension.as_str(), "jpg" | "jpeg" | "png").then(|| path.to_path_buf()) +} + +pub(crate) fn humanise_key(key: &str) -> String { + let words = key.replace('_', " "); + let mut chars = words.chars(); + match chars.next() { + Some(first) => first.to_uppercase().collect::() + chars.as_str(), + None => String::new(), + } +} + +pub(crate) fn export_file_name(design_id: &str, extension: &str, unix_seconds: u64) -> String { + let stem: String = design_id + .chars() + .map(|character| { + if character.is_ascii_alphanumeric() { + character.to_ascii_lowercase() + } else { + '-' + } + }) + .collect(); + let stem = stem.trim_matches('-'); + let stem = if stem.is_empty() { "pattern" } else { stem }; + format!("{stem}-{}.{}", utc_timestamp(unix_seconds), extension) +} + +fn utc_timestamp(unix_seconds: u64) -> String { + let days = (unix_seconds / 86_400) as i64; + let seconds = unix_seconds % 86_400; + let hour = seconds / 3_600; + let minute = (seconds % 3_600) / 60; + let second = seconds % 60; + let (year, month, day) = civil_from_days(days); + format!("{year:04}{month:02}{day:02}-{hour:02}{minute:02}{second:02}") +} + +fn civil_from_days(days_since_epoch: i64) -> (i64, u64, u64) { + let z = days_since_epoch + 719_468; + let era = if z >= 0 { z } else { z - 146_096 } / 146_097; + let day_of_era = z - era * 146_097; + let year_of_era = + (day_of_era - day_of_era / 1_460 + day_of_era / 36_524 - day_of_era / 146_096) + / 365; + let mut year = year_of_era + era * 400; + let day_of_year = day_of_era - (365 * year_of_era + year_of_era / 4 - year_of_era / 100); + let month_prime = (5 * day_of_year + 2) / 153; + let day = day_of_year - (153 * month_prime + 2) / 5 + 1; + let month = month_prime + if month_prime < 10 { 3 } else { -9 }; + year += i64::from(month <= 2); + (year, month as u64, day as u64) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn humanises_measurement_keys() { + assert_eq!(humanise_key("shoulder_to_bust"), "Shoulder to bust"); + assert_eq!(humanise_key("height"), "Height"); + } + + #[test] + fn mirror_transform_flips_preview_bbox_horizontally() { + assert_eq!( + mirror_normalized_bbox([0.1, 0.2, 0.4, 0.8], true), + [0.6, 0.2, 0.9, 0.8] + ); + assert_eq!( + mirror_normalized_bbox([0.1, 0.2, 0.4, 0.8], false), + [0.1, 0.2, 0.4, 0.8] + ); + assert_eq!(mirror_normalized_bbox([-1.0; 4], true), [-1.0; 4]); + } + + #[test] + fn export_names_are_safe_and_timestamped() { + assert_eq!( + export_file_name("Classic Shirt", "svg", 0), + "classic-shirt-19700101-000000.svg" + ); + assert_eq!( + export_file_name("dress/v2", "pdf", 1_700_000_000), + "dress-v2-20231114-221320.pdf" + ); + } + + #[test] + fn stable_measurements_settle_after_one_and_a_half_seconds() { + let mut settler = MeasurementSettler::default(); + let measurements = Measurements::sample(); + assert!(!settler.push(Duration::ZERO, measurements)); + assert!(!settler.push(Duration::from_millis(750), measurements)); + assert!(settler.push(Duration::from_millis(1_500), measurements)); + assert!(settler.settled); + assert!(!settler.push(Duration::from_millis(1_750), measurements)); + } + + #[test] + fn jittering_measurements_never_settle() { + let mut settler = MeasurementSettler::default(); + for index in 0..16 { + let mut measurements = Measurements::sample(); + measurements.bust += index as f32; + assert!(!settler.push(Duration::from_millis(index * 250), measurements)); + assert!(!settler.settled); + } + } +} diff --git a/apps/fabric/src/pattern_view.rs b/apps/fabric/src/pattern_view.rs new file mode 100644 index 000000000..1fb85d902 --- /dev/null +++ b/apps/fabric/src/pattern_view.rs @@ -0,0 +1,398 @@ +use crate::body_view::DrawFabricLine; +use makepad_fabric_draft::{flatten, nest, offset, Layout as PatternLayout, Part, Pattern, Point}; +use makepad_widgets::*; + +script_mod! { + use mod.prelude.widgets_internal.* + use mod.widgets.* + + mod.widgets.FabricPatternViewBase = #(FabricPatternView::register_widget(vm)) + mod.widgets.FabricPatternView = set_type_default() do mod.widgets.FabricPatternViewBase { + width: Fill + height: Fill + draw_bg +: {color: #x0d1218} + draw_line +: {} + draw_text +: { + color: #xc5d0dc + text_style: theme.font_regular{font_size: 8.5} + } + } +} + +#[derive(Clone, Copy)] +struct PatternDrag { + from: DVec2, + pan: DVec2, +} + +#[derive(Clone, Copy, Default)] +struct Bounds { + min: DVec2, + max: DVec2, + valid: bool, +} + +impl Bounds { + fn include(&mut self, point: DVec2) { + if !self.valid { + self.min = point; + self.max = point; + self.valid = true; + } else { + self.min.x = self.min.x.min(point.x); + self.min.y = self.min.y.min(point.y); + self.max.x = self.max.x.max(point.x); + self.max.y = self.max.y.max(point.y); + } + } + + fn size(self) -> DVec2 { + let size = self.max - self.min; + dvec2(size.x.max(1.0), size.y.max(1.0)) + } + + fn centre(self) -> DVec2 { + (self.min + self.max) * 0.5 + } +} + +#[derive(Script, ScriptHook, Widget)] +pub struct FabricPatternView { + #[uid] + uid: WidgetUid, + #[source] + source: ScriptObjectRef, + #[walk] + walk: Walk, + #[layout] + layout: Layout, + #[redraw] + #[area] + area: Area, + #[live] + draw_bg: DrawColor, + #[live] + draw_line: DrawFabricLine, + #[live] + draw_text: DrawText, + #[rust] + pattern: Option, + #[rust] + nested: Option, + #[rust] + error: String, + #[rust] + bounds: Bounds, + #[rust(1.0)] + zoom: f64, + /// The view aspect the current nest was chosen for. + #[rust(1.0)] + nest_aspect: f64, + #[rust] + pan: DVec2, + #[rust] + drag: Option, +} + +impl FabricPatternView { + pub fn set_pattern(&mut self, cx: &mut Cx, pattern: Pattern) { + self.pattern = Some(pattern); + // Nested on the next draw, for the pane's shape. + self.nested = None; + self.error.clear(); + self.zoom = 1.0; + self.pan = dvec2(0.0, 0.0); + self.redraw(cx); + } + + pub fn set_error(&mut self, cx: &mut Cx, error: impl Into) { + self.pattern = None; + self.nested = None; + self.error = error.into(); + self.redraw(cx); + } + + /// Nest onto the fabric width whose finished layout has the pane's + /// aspect ratio, so the pieces fill the view instead of a tall strip. + fn ensure_nest(&mut self, rect: Rect) { + let target = (rect.size.x - 24.0).max(1.0) / (rect.size.y - 24.0).max(1.0); + if self.nested.is_some() && (self.nest_aspect / target).ln().abs() < 0.12 { + return; + } + const WIDTHS: [f64; 9] = [ + 900.0, 1200.0, 1500.0, 2000.0, 2500.0, 3000.0, 4000.0, 5000.0, 6500.0, + ]; + let best = { + let Some(pattern) = &self.pattern else { return }; + let mut best: Option<(f64, PatternLayout, Bounds)> = None; + for width in WIDTHS { + let layout = nest(pattern, width); + let bounds = pattern_bounds(pattern, &layout); + let size = bounds.size(); + let aspect = size.x.max(1.0) / size.y.max(1.0); + let score = (aspect / target).ln().abs(); + if best.as_ref().map_or(true, |(other, _, _)| score < *other) { + best = Some((score, layout, bounds)); + } + } + best + }; + if let Some((_, layout, bounds)) = best { + self.nested = Some(layout); + self.bounds = bounds; + self.nest_aspect = target; + } + } + + fn to_screen(&self, point: DVec2, rect: Rect) -> DVec2 { + let size = self.bounds.size(); + let fit = ((rect.size.x - 24.0) / size.x) + .min((rect.size.y - 24.0) / size.y) + .max(0.0001); + rect.pos + rect.size * 0.5 + + self.pan + + (point - self.bounds.centre()) * fit * self.zoom + } + + fn part_offset<'a>( + &'a self, + layout: &'a PatternLayout, + part_index: usize, + ) -> (Point, f64) { + layout + .placements + .iter() + .find(|placement| placement.part == part_index) + .map(|placement| (placement.offset, placement.rotation_deg)) + .unwrap_or((Point::default(), 0.0)) + } + + fn path_segments( + &self, + path: &makepad_fabric_draft::Path, + offset_by: Point, + rotation: f64, + rect: Rect, + ) -> Vec<(DVec2, DVec2)> { + let points = flatten(path, 1.0); + let transformed: Vec = points + .iter() + .map(|point| self.to_screen(place(*point, offset_by, rotation), rect)) + .collect(); + let mut segments: Vec<_> = transformed + .windows(2) + .map(|pair| (pair[0], pair[1])) + .collect(); + if path.closed { + if let (Some(first), Some(last)) = (transformed.first(), transformed.last()) { + segments.push((*last, *first)); + } + } + segments + } +} + +impl Widget for FabricPatternView { + fn draw_walk(&mut self, cx: &mut Cx2d, _scope: &mut Scope, walk: Walk) -> DrawStep { + let rect = cx.walk_turtle(walk); + self.draw_bg.draw_abs(cx, rect); + cx.push_clip_rect(rect); + self.ensure_nest(rect); + let (Some(pattern), Some(layout)) = (&self.pattern, &self.nested) else { + let message = if self.error.is_empty() { + "pattern preview" + } else { + &self.error + }; + self.draw_text.color = Vec4f { + x: 0.52, + y: 0.58, + z: 0.65, + w: 1.0, + }; + self.draw_text + .draw_abs(cx, rect.pos + dvec2(14.0, 16.0), message); + cx.pop_clip_rect(); + cx.add_aligned_rect_area(&mut self.area, rect); + return DrawStep::done(); + }; + + struct Stroke { + from: DVec2, + to: DVec2, + color: Vec4f, + width: f64, + } + let mut strokes = Vec::new(); + let mut labels = Vec::new(); + let cut_color = Vec4f { + x: 0.93, + y: 0.96, + z: 0.99, + w: 1.0, + }; + let seam_color = Vec4f { + x: 0.40, + y: 0.49, + z: 0.58, + w: 0.72, + }; + let mark_color = Vec4f { + x: 1.0, + y: 0.40, + z: 0.18, + w: 0.95, + }; + + for (part_index, part) in pattern.parts.iter().enumerate() { + let (part_offset, rotation) = self.part_offset(layout, part_index); + let cut_path = offset(&part.outline, part.seam_allowance_mm); + for (from, to) in self.path_segments(&cut_path, part_offset, rotation, rect) { + strokes.push(Stroke { + from, + to, + color: cut_color, + width: 1.25, + }); + } + for (from, to) in self.path_segments(&part.outline, part_offset, rotation, rect) { + strokes.push(Stroke { + from, + to, + color: seam_color, + width: 0.75, + }); + } + for path in &part.internal { + for (from, to) in self.path_segments(path, part_offset, rotation, rect) { + strokes.push(Stroke { + from, + to, + color: seam_color, + width: 0.75, + }); + } + } + for notch in &part.notches { + let at = self.to_screen(place(*notch, part_offset, rotation), rect); + strokes.push(Stroke { + from: at + dvec2(-3.0, -3.0), + to: at + dvec2(3.0, 3.0), + color: mark_color, + width: 1.0, + }); + strokes.push(Stroke { + from: at + dvec2(-3.0, 3.0), + to: at + dvec2(3.0, -3.0), + color: mark_color, + width: 1.0, + }); + } + let grain_from = self.to_screen(place(part.grainline.0, part_offset, rotation), rect); + let grain_to = self.to_screen(place(part.grainline.1, part_offset, rotation), rect); + strokes.push(Stroke { + from: grain_from, + to: grain_to, + color: mark_color, + width: 1.0, + }); + let label_at = part + .labels + .first() + .map(|label| label.at) + .unwrap_or(part.outline.start); + labels.push(( + self.to_screen(place(label_at, part_offset, rotation), rect), + format!( + "{} · {}", + part.name, + if part.on_fold { + "cut on fold".to_string() + } else { + format!("cut {}", part.cut_count) + } + ), + )); + } + + self.draw_line.begin_many_instances(cx); + for stroke in strokes { + self.draw_line.color = stroke.color; + self.draw_line + .segment(cx, stroke.from, stroke.to, stroke.width); + } + self.draw_line.end_many_instances(cx); + self.draw_text.color = Vec4f { + x: 0.78, + y: 0.84, + z: 0.90, + w: 1.0, + }; + for (at, text) in labels { + self.draw_text.draw_abs(cx, at + dvec2(4.0, -5.0), &text); + } + cx.pop_clip_rect(); + cx.add_aligned_rect_area(&mut self.area, rect); + DrawStep::done() + } + + fn handle_event(&mut self, cx: &mut Cx, event: &Event, _scope: &mut Scope) { + match event.hits(cx, self.area) { + Hit::FingerDown(event) if event.device.is_primary_hit() => { + self.drag = Some(PatternDrag { + from: event.abs, + pan: self.pan, + }); + } + Hit::FingerMove(event) => { + if let Some(drag) = self.drag { + self.pan = drag.pan + event.abs - drag.from; + self.redraw(cx); + } + } + Hit::FingerUp(_) => self.drag = None, + Hit::FingerScroll(event) => { + self.zoom = (self.zoom * (-event.scroll.y * 0.004).exp()).clamp(0.1, 30.0); + self.redraw(cx); + } + Hit::FingerHoverIn(_) | Hit::FingerHoverOver(_) => { + cx.set_cursor(MouseCursor::Grab) + } + _ => {} + } + } +} + +fn place(point: Point, offset: Point, rotation_deg: f64) -> DVec2 { + let angle = rotation_deg.to_radians(); + let (sin, cos) = angle.sin_cos(); + dvec2( + point.x * cos - point.y * sin + offset.x, + point.x * sin + point.y * cos + offset.y, + ) +} + +fn pattern_bounds(pattern: &Pattern, layout: &PatternLayout) -> Bounds { + let mut bounds = Bounds::default(); + for (part_index, part) in pattern.parts.iter().enumerate() { + let (part_offset, rotation) = layout + .placements + .iter() + .find(|placement| placement.part == part_index) + .map(|placement| (placement.offset, placement.rotation_deg)) + .unwrap_or((Point::default(), 0.0)); + include_part(&mut bounds, part, part_offset, rotation); + } + if !bounds.valid && layout.width_mm > 0.0 && layout.height_mm > 0.0 { + bounds.include(dvec2(0.0, 0.0)); + bounds.include(dvec2(layout.width_mm, layout.height_mm)); + } + bounds +} + +fn include_part(bounds: &mut Bounds, part: &Part, part_offset: Point, rotation: f64) { + let cut = offset(&part.outline, part.seam_allowance_mm); + for point in flatten(&cut, 1.0) { + bounds.include(place(point, part_offset, rotation)); + } +} diff --git a/apps/fabric/src/pipeline.rs b/apps/fabric/src/pipeline.rs new file mode 100644 index 000000000..969adfb5c --- /dev/null +++ b/apps/fabric/src/pipeline.rs @@ -0,0 +1,676 @@ +use crate::{ + body_view::{map_measurements_to_vertices, BodyPoseMapping}, + camera::CameraMailbox, +}; +use makepad_ai_body::model::BodyModel; +use makepad_fabric_measure::{measure, BodyMesh, MeasureOptions, Measured}; +use makepad_widgets::image_cache::ImageBuffer; +use makepad_widgets::makepad_platform::thread::SignalToUI; +use std::{ + collections::VecDeque, + path::{Path, PathBuf}, + sync::{ + atomic::{AtomicBool, Ordering}, + mpsc::{self, Receiver, Sender}, + Arc, + }, + thread, + time::{Duration, Instant}, +}; + +const PHOTO_CROP_SIZE: usize = 512; +const LIVE_CROP_SIZE: usize = 384; +const SHAPE_ALPHA: f32 = 0.35; +const POSE_ALPHA: f32 = 0.6; +const SHAPE_RESET_GAP: Duration = Duration::from_secs(1); +const FRAME_TIMEOUT: Duration = Duration::from_secs(2); +const FRAME_POLL: Duration = Duration::from_millis(5); + +pub enum PipelineMessage { + Stage(String), + LiveFrame { + fps: f32, + model_ms: f32, + pose_ms: f32, + person: bool, + bbox: Option<[f32; 4]>, + }, + Done { + measured: Box, + mesh: Arc, + posed: Option>>, + pose_mapping: BodyPoseMapping, + reset_pose: bool, + }, + Failed(String), +} + +struct RunRequest { + photo: PathBuf, + weights: PathBuf, + height_cm: Option, +} + +struct LiveRequest { + weights: PathBuf, + height_cm: Option, + mailbox: CameraMailbox, +} + +enum WorkerRequest { + Photo(RunRequest), + Live(LiveRequest), +} + +pub struct Pipeline { + request_tx: Sender, + message_rx: Receiver, + live_stop: Arc, +} + +impl Pipeline { + pub fn new() -> Self { + let (request_tx, request_rx) = mpsc::channel(); + let (message_tx, message_rx) = mpsc::channel(); + let live_stop = Arc::new(AtomicBool::new(true)); + let worker_stop = live_stop.clone(); + thread::Builder::new() + .name("fabric-body-pipeline".to_string()) + .spawn(move || worker(request_rx, message_tx, worker_stop)) + .expect("spawn fabric body worker"); + Self { + request_tx, + message_rx, + live_stop, + } + } + + pub fn run( + &self, + photo: PathBuf, + weights: PathBuf, + height_cm: Option, + ) -> Result<(), String> { + self.request_tx + .send(WorkerRequest::Photo(RunRequest { + photo, + weights, + height_cm, + })) + .map_err(|_| "the body model worker stopped".to_string()) + } + + pub fn start_live( + &self, + weights: PathBuf, + height_cm: Option, + mailbox: CameraMailbox, + ) -> Result<(), String> { + self.live_stop.store(false, Ordering::Release); + if self + .request_tx + .send(WorkerRequest::Live(LiveRequest { + weights, + height_cm, + mailbox, + })) + .is_err() + { + self.live_stop.store(true, Ordering::Release); + return Err("the body model worker stopped".to_string()); + } + Ok(()) + } + + pub fn stop_live(&self) { + self.live_stop.store(true, Ordering::Release); + } + + pub fn poll(&self) -> Vec { + self.message_rx.try_iter().collect() + } +} + +fn emit(sender: &Sender, message: PipelineMessage) -> bool { + if sender.send(message).is_err() { + return false; + } + SignalToUI::set_ui_signal(); + true +} + +fn worker( + requests: Receiver, + messages: Sender, + live_stop: Arc, +) { + let mut loaded: Option<(PathBuf, BodyModel)> = None; + while let Ok(request) = requests.recv() { + let result = match request { + WorkerRequest::Photo(request) => run_one(&request, &messages, &mut loaded), + WorkerRequest::Live(request) => { + run_live(&request, &messages, &mut loaded, &live_stop) + } + }; + if let Err(error) = result { + if !emit(&messages, PipelineMessage::Failed(error)) { + return; + } + } + } +} + +fn run_one( + request: &RunRequest, + messages: &Sender, + loaded: &mut Option<(PathBuf, BodyModel)>, +) -> Result<(), String> { + emit(messages, PipelineMessage::Stage("decoding photo…".to_string())); + let (rgb, width, height) = decode_rgb(&request.photo)?; + + ensure_model(&request.weights, messages, loaded)?; + + emit(messages, PipelineMessage::Stage("inferring…".to_string())); + let model = &mut loaded.as_mut().expect("model was loaded above").1; + model + .set_crop_size(PHOTO_CROP_SIZE) + .map_err(|error| format!("could not configure the body model: {error}"))?; + let packet = model + .infer(&rgb, width, height, None) + .map_err(|error| format!("body inference failed: {error}"))?; + let person = packet + .people + .first() + .ok_or_else(|| "no person found".to_string())?; + let posed = Arc::new(posed_vertices( + model, + &person.shape, + &person.expr, + person.mhr, + person.global_rot, + )?); + let vertices = model.rig().rest_vertices(&person.shape, &person.expr); + let face_indices = model + .weights + .i64_shaped("head_pose.faces", &[36_874, 3]) + .map_err(|error| format!("could not read the body mesh faces: {error}"))?; + let mesh = Arc::new(body_mesh_from_flat(&vertices, &face_indices)?); + + emit(messages, PipelineMessage::Stage("measuring…".to_string())); + let measured = measure( + &mesh, + &MeasureOptions { + height_cm: request.height_cm, + }, + ) + .map_err(|error| error.to_string())?; + let pose_mapping = map_measurements_to_vertices(&mesh, &measured); + emit( + messages, + PipelineMessage::Done { + measured: Box::new(measured), + mesh, + posed: Some(posed), + pose_mapping, + reset_pose: true, + }, + ); + Ok(()) +} + +fn ensure_model( + weights: &Path, + messages: &Sender, + loaded: &mut Option<(PathBuf, BodyModel)>, +) -> Result<(), String> { + if loaded + .as_ref() + .map(|(path, _)| path != weights) + .unwrap_or(true) + { + emit( + messages, + PipelineMessage::Stage("loading model 2.8 GB…".to_string()), + ); + let model = BodyModel::load(weights) + .map_err(|error| format!("could not load the body model: {error}"))?; + *loaded = Some((weights.to_path_buf(), model)); + } + Ok(()) +} + +fn run_live( + request: &LiveRequest, + messages: &Sender, + loaded: &mut Option<(PathBuf, BodyModel)>, + stop: &AtomicBool, +) -> Result<(), String> { + if stop.load(Ordering::Acquire) { + return Ok(()); + } + ensure_model(&request.weights, messages, loaded)?; + let model = &mut loaded.as_mut().expect("model was loaded above").1; + model + .set_crop_size(LIVE_CROP_SIZE) + .map_err(|error| format!("could not configure live body inference: {error}"))?; + let face_indices = model + .weights + .i64_shaped("head_pose.faces", &[36_874, 3]) + .map_err(|error| format!("could not read the body mesh faces: {error}"))?; + + let started = Instant::now(); + let mut previous_bbox = None; + let mut smoother = ShapeSmoother::default(); + let mut pose_smoother = PoseSmoother::default(); + let mut fps = FpsCounter::default(); + let mut reset_pose = true; + + while !stop.load(Ordering::Acquire) { + request.mailbox.request(); + let wait_started = Instant::now(); + let frame = loop { + if stop.load(Ordering::Acquire) { + return Ok(()); + } + if let Some(frame) = request.mailbox.take() { + break Some(frame); + } + if wait_started.elapsed() >= FRAME_TIMEOUT { + break None; + } + thread::sleep(FRAME_POLL); + }; + let Some(frame) = frame else { + if !emit( + messages, + PipelineMessage::Stage("no camera frames".to_string()), + ) { + return Ok(()); + } + continue; + }; + + let model_started = Instant::now(); + let packet = model + .infer(&frame.rgb, frame.width, frame.height, previous_bbox) + .map_err(|error| format!("live body inference failed: {error}"))?; + let model_ms = model_started.elapsed().as_secs_f32() * 1000.0; + let now = started.elapsed(); + let person = packet.people.first(); + let bbox = person.map(|person| person.bbox); + let mut pose_ms = 0.0; + let mut posed = None; + let smoothed_shape = if let Some(person) = person { + previous_bbox = Some(expand_bbox( + person.bbox, + frame.width, + frame.height, + 0.15, + )); + let (mhr, global_rot) = pose_smoother.observe(person.mhr, person.global_rot); + let pose_started = Instant::now(); + posed = Some(Arc::new(posed_vertices( + model, + &person.shape, + &person.expr, + mhr, + global_rot, + )?)); + pose_ms = pose_started.elapsed().as_secs_f32() * 1000.0; + Some(smoother.observe_person(person.shape, now)) + } else { + previous_bbox = None; + smoother.observe_miss(now); + pose_smoother.reset(); + None + }; + let current_fps = fps.tick(now); + if !emit( + messages, + PipelineMessage::LiveFrame { + fps: current_fps, + model_ms, + pose_ms, + person: person.is_some(), + bbox, + }, + ) { + return Ok(()); + } + if stop.load(Ordering::Acquire) { + return Ok(()); + } + + let Some(shape) = smoothed_shape else { + continue; + }; + let expression = [0.0f32; 72]; + let vertices = model.rig().rest_vertices(&shape, &expression); + let mesh = Arc::new(body_mesh_from_flat(&vertices, &face_indices)?); + let measured = measure( + &mesh, + &MeasureOptions { + height_cm: request.height_cm, + }, + ) + .map_err(|error| error.to_string())?; + let pose_mapping = map_measurements_to_vertices(&mesh, &measured); + if !emit( + messages, + PipelineMessage::Done { + measured: Box::new(measured), + mesh, + posed, + pose_mapping, + reset_pose, + }, + ) { + return Ok(()); + } + reset_pose = false; + } + Ok(()) +} + +#[derive(Default)] +struct PoseSmoother { + mhr: Option<[f32; 204]>, + global_rot: Option<[f32; 3]>, +} + +impl PoseSmoother { + fn observe( + &mut self, + mhr: [f32; 204], + global_rot: [f32; 3], + ) -> ([f32; 204], [f32; 3]) { + let global_rot = match self.global_rot { + Some(previous) => std::array::from_fn(|index| { + previous[index] + POSE_ALPHA * (global_rot[index] - previous[index]) + }), + None => global_rot, + }; + let mut mhr = match self.mhr { + Some(previous) => std::array::from_fn(|index| { + previous[index] + POSE_ALPHA * (mhr[index] - previous[index]) + }), + None => mhr, + }; + // The packet's 204 values are exactly the rig's [pose 136 | scales 68] + // input. Global rotation is pose slots 3..6; keep the separately + // smoothed copy authoritative before MhrRig::forward pads to 249. + mhr[3..6].copy_from_slice(&global_rot); + self.mhr = Some(mhr); + self.global_rot = Some(global_rot); + (mhr, global_rot) + } + + fn reset(&mut self) { + self.mhr = None; + self.global_rot = None; + } +} + +#[derive(Default)] +struct ShapeSmoother { + shape: Option<[f32; 45]>, + last_person: Option, +} + +impl ShapeSmoother { + fn observe_person(&mut self, shape: [f32; 45], now: Duration) -> [f32; 45] { + if self + .last_person + .is_some_and(|last| now.saturating_sub(last) > SHAPE_RESET_GAP) + { + self.shape = None; + } + self.last_person = Some(now); + let smoothed = match self.shape { + Some(previous) => std::array::from_fn(|index| { + previous[index] + SHAPE_ALPHA * (shape[index] - previous[index]) + }), + None => shape, + }; + self.shape = Some(smoothed); + smoothed + } + + fn observe_miss(&mut self, now: Duration) { + if self + .last_person + .is_some_and(|last| now.saturating_sub(last) > SHAPE_RESET_GAP) + { + self.shape = None; + self.last_person = None; + } + } +} + +#[derive(Default)] +struct FpsCounter { + samples: VecDeque, +} + +impl FpsCounter { + fn tick(&mut self, now: Duration) -> f32 { + self.samples.push_back(now); + while self.samples.len() > 10 { + self.samples.pop_front(); + } + let Some(first) = self.samples.front().copied() else { + return 0.0; + }; + let seconds = now.saturating_sub(first).as_secs_f32(); + if seconds <= f32::EPSILON { + 0.0 + } else { + (self.samples.len().saturating_sub(1)) as f32 / seconds + } + } +} + +pub(crate) fn expand_bbox( + bbox: [f32; 4], + width: u32, + height: u32, + amount: f32, +) -> [f32; 4] { + let box_width = (bbox[2] - bbox[0]).max(0.0); + let box_height = (bbox[3] - bbox[1]).max(0.0); + [ + (bbox[0] - box_width * amount).clamp(0.0, width as f32), + (bbox[1] - box_height * amount).clamp(0.0, height as f32), + (bbox[2] + box_width * amount).clamp(0.0, width as f32), + (bbox[3] + box_height * amount).clamp(0.0, height as f32), + ] +} + +fn posed_vertices( + model: &BodyModel, + shape: &[f32; 45], + expression: &[f32; 72], + mut mhr: [f32; 204], + global_rot: [f32; 3], +) -> Result, String> { + // BodyPerson::mhr is already model_params(): pose 0..136 followed by + // scales 136..204. The root translation remains zero and the model's + // global rotation occupies 3..6. forward() pads the 45 identity slots + // to the rig's 249-wide internal vector, then returns rig-space cm. + mhr[3..6].copy_from_slice(&global_rot); + let output = model.rig().forward(shape, &mhr, expression, true); + vertices_from_flat(&output.verts) +} + +fn decode_rgb(path: &Path) -> Result<(Vec, u32, u32), String> { + let bytes = std::fs::read(path) + .map_err(|error| format!("could not read {}: {error}", path.display()))?; + let extension = path + .extension() + .and_then(|extension| extension.to_str()) + .unwrap_or_default() + .to_ascii_lowercase(); + let image = match extension.as_str() { + "jpg" | "jpeg" => ImageBuffer::from_jpg(&bytes), + "png" => ImageBuffer::from_png(&bytes), + _ => return Err("choose a JPG or PNG photo".to_string()), + } + .map_err(|error| format!("could not decode {}: {error}", path.display()))?; + let pixel_count = image + .width + .checked_mul(image.height) + .ok_or_else(|| "photo dimensions are too large".to_string())?; + if image.data.len() < pixel_count { + return Err("decoded photo has too few pixels".to_string()); + } + let width = u32::try_from(image.width).map_err(|_| "photo is too wide".to_string())?; + let height = u32::try_from(image.height).map_err(|_| "photo is too tall".to_string())?; + Ok((argb_to_rgb(&image.data[..pixel_count]), width, height)) +} + +pub(crate) fn argb_to_rgb(pixels: &[u32]) -> Vec { + let mut rgb = Vec::with_capacity(pixels.len() * 3); + for pixel in pixels { + rgb.push((pixel >> 16) as u8); + rgb.push((pixel >> 8) as u8); + rgb.push(*pixel as u8); + } + rgb +} + +pub(crate) fn faces_i64_to_u32( + values: &[i64], + vertex_count: usize, +) -> Result, String> { + if values.len() % 3 != 0 { + return Err("body face index buffer is not made of triangles".to_string()); + } + values + .chunks_exact(3) + .enumerate() + .map(|(face_index, triangle)| { + let mut face = [0; 3]; + for corner in 0..3 { + let index = usize::try_from(triangle[corner]).map_err(|_| { + format!("body face {face_index} contains a negative vertex index") + })?; + if index >= vertex_count { + return Err(format!( + "body face {face_index} references vertex {index}, but there are {vertex_count} vertices" + )); + } + face[corner] = u32::try_from(index) + .map_err(|_| format!("body vertex index {index} exceeds u32"))?; + } + Ok(face) + }) + .collect() +} + +pub(crate) fn body_mesh_from_flat( + vertices: &[f32], + face_indices: &[i64], +) -> Result { + let vertices = vertices_from_flat(vertices)?; + let faces = faces_i64_to_u32(face_indices, vertices.len())?; + Ok(BodyMesh { + vertices, + faces, + landmarks: None, + }) +} + +fn vertices_from_flat(vertices: &[f32]) -> Result, String> { + if vertices.is_empty() || vertices.len() % 3 != 0 { + return Err("body vertex buffer is empty or malformed".to_string()); + } + Ok(vertices + .chunks_exact(3) + .map(|point| [point[0], point[1], point[2]]) + .collect()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn converts_aarrggbb_to_rgb() { + assert_eq!( + argb_to_rgb(&[0xff_12_34_56, 0x00_ab_cd_ef]), + vec![0x12, 0x34, 0x56, 0xab, 0xcd, 0xef] + ); + } + + #[test] + fn builds_a_tiny_checked_mesh() { + let mesh = body_mesh_from_flat( + &[0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0], + &[0, 1, 2], + ) + .unwrap(); + assert_eq!(mesh.vertices.len(), 3); + assert_eq!(mesh.faces, vec![[0, 1, 2]]); + assert!(faces_i64_to_u32(&[0, 1, 3], 3).is_err()); + assert!(faces_i64_to_u32(&[-1, 1, 2], 3).is_err()); + } + + #[test] + fn live_shape_ema_converges_and_resets_after_a_gap() { + let mut smoother = ShapeSmoother::default(); + assert_eq!( + smoother.observe_person([0.0; 45], Duration::ZERO), + [0.0; 45] + ); + let first = smoother.observe_person([10.0; 45], Duration::from_millis(250)); + assert!((first[0] - 3.5).abs() < 0.0001); + let second = smoother.observe_person([10.0; 45], Duration::from_millis(500)); + assert!((second[0] - 5.775).abs() < 0.0001); + + smoother.observe_miss(Duration::from_millis(1_501)); + let reset = smoother.observe_person([8.0; 45], Duration::from_millis(1_750)); + assert_eq!(reset, [8.0; 45]); + } + + #[test] + fn live_pose_ema_smooths_parameters_and_keeps_global_slots_in_sync() { + let mut smoother = PoseSmoother::default(); + let mut initial_mhr = [0.0; 204]; + initial_mhr[20] = 2.0; + let (initial, initial_rot) = smoother.observe(initial_mhr, [1.0, 2.0, 3.0]); + assert_eq!(initial[3..6], initial_rot); + + let mut next_mhr = [10.0; 204]; + next_mhr[20] = 12.0; + let (smoothed, smoothed_rot) = smoother.observe(next_mhr, [3.0, 4.0, 5.0]); + assert!((smoothed[20] - 8.0).abs() < 0.0001); + assert_eq!(smoothed_rot, [2.2, 3.2, 4.2]); + assert_eq!(smoothed[3..6], smoothed_rot); + + smoother.reset(); + let (reset, _) = smoother.observe([7.0; 204], [0.5, 1.0, 1.5]); + assert_eq!(reset[20], 7.0); + } + + #[test] + fn bbox_expansion_is_fifteen_percent_and_clamped() { + let expanded = expand_bbox([100.0, 50.0, 300.0, 250.0], 640, 360, 0.15); + for (actual, expected) in expanded.into_iter().zip([70.0, 20.0, 330.0, 280.0]) { + assert!((actual - expected).abs() < 0.0001, "{expanded:?}"); + } + assert_eq!( + expand_bbox([5.0, 10.0, 635.0, 350.0], 640, 360, 0.15), + [0.0, 0.0, 640.0, 360.0] + ); + } + + #[test] + fn fps_counter_tracks_recent_frame_cadence() { + let mut counter = FpsCounter::default(); + assert_eq!(counter.tick(Duration::ZERO), 0.0); + for quarter in 1..=4 { + let fps = counter.tick(Duration::from_millis(quarter * 250)); + assert!((fps - 4.0).abs() < 0.0001, "{fps}"); + } + } +} diff --git a/libs/fabric/draft/Cargo.toml b/libs/fabric/draft/Cargo.toml new file mode 100644 index 000000000..26c1a6345 --- /dev/null +++ b/libs/fabric/draft/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "makepad-fabric-draft" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" +description = "Parametric sewing-pattern drafting from body measurements, with SVG and tiled-PDF output" + +[dependencies] +makepad-fabric-measure = { path = "../measure" } diff --git a/libs/fabric/draft/src/designs/aline_skirt.rs b/libs/fabric/draft/src/designs/aline_skirt.rs new file mode 100644 index 000000000..134677415 --- /dev/null +++ b/libs/fabric/draft/src/designs/aline_skirt.rs @@ -0,0 +1,149 @@ +use super::{append_only_segment, labels, line_path, measurement}; +use crate::{curve_through, Design, DraftError, Measurements, OptionSpec, Options, Part, Path, Pattern, Point}; + +pub(crate) struct AlineSkirt; + +impl AlineSkirt { + fn specs(default_length: f64) -> Vec { + vec![ + OptionSpec { key: "waist_ease", label: "Waist ease", min: 0.0, max: 40.0, default: 10.0, unit: "mm" }, + OptionSpec { key: "hip_ease", label: "Hip ease", min: 0.0, max: 80.0, default: 30.0, unit: "mm" }, + OptionSpec { key: "flare", label: "Flare", min: 0.0, max: 250.0, default: 80.0, unit: "mm" }, + OptionSpec { key: "length", label: "Length", min: 300.0, max: 1000.0, default: default_length.clamp(300.0, 1000.0), unit: "mm" }, + OptionSpec { key: "dart_length", label: "Front dart length", min: 50.0, max: 200.0, default: 90.0, unit: "mm" }, + ] + } +} + +fn option(options: &Options, spec: &OptionSpec) -> Result { + let value = options.get(spec); + if !value.is_finite() || value < spec.min || value > spec.max { + Err(DraftError::Invalid(format!("option {} must be between {} and {}", spec.key, spec.min, spec.max))) + } else { + Ok(value) + } +} + +fn waist_point(side_x: f64, x: f64) -> Point { + let t = (x / side_x).clamp(0.0, 1.0); + let y = 10.0 * ((1.0 - t).powi(3) + 3.0 * (1.0 - t).powi(2) * t); + Point::new(x, y) +} + +#[allow(clippy::too_many_arguments)] +fn skirt_piece( + name: &str, + design: &str, + on_fold: bool, + cut_count: u8, + waist_quarter: f64, + hip_quarter: f64, + hip_line: f64, + length: f64, + flare: f64, + dart_length: f64, + keys: [(&str, f64); 3], +) -> Part { + let dart_intake = (hip_quarter - waist_quarter).max(0.0) * 0.6; + let side_waist = Point::new(waist_quarter + dart_intake, 0.0); + let hip = Point::new(hip_quarter, hip_line); + let side_hem = Point::new(hip_quarter + flare, length); + let center_waist = Point::new(0.0, 10.0); + let center_hem = Point::new(0.0, length); + let mut outline = Path { start: center_waist, ..Path::default() }; + outline.curve_to( + Point::new(side_waist.x / 3.0, 10.0), + Point::new(side_waist.x * 2.0 / 3.0, 0.0), + side_waist, + ); + append_only_segment(&mut outline, curve_through(side_waist, Point::new(0.12, 1.0), hip, Point::new(0.0, 1.0), 0.30)); + outline.line_to(side_hem); + let side_vector = Point::new(side_hem.x - hip.x, side_hem.y - hip.y); + append_only_segment( + &mut outline, + curve_through(side_hem, Point::new(-side_vector.y, side_vector.x), center_hem, Point::new(-1.0, 0.0), 0.18), + ); + outline.close(); + + let dart_center = waist_quarter * 0.5; + let left = waist_point(side_waist.x, dart_center - dart_intake * 0.5); + let right = waist_point(side_waist.x, dart_center + dart_intake * 0.5); + let tip = Point::new(dart_center, waist_point(side_waist.x, dart_center).y + dart_length); + let mut dart = Path { start: left, ..Path::default() }; + dart.line_to(tip); + dart.line_to(right); + let mut notches = vec![left, right]; + if !on_fold { + notches.push(Point::new(0.0, center_waist.y + 180.0)); + } + Part { + name: name.to_owned(), + cut_count, + on_fold, + outline, + seam_allowance_mm: 10.0, + notches, + grainline: (Point::new(waist_quarter * 0.28, hip_line + 40.0), Point::new(waist_quarter * 0.28, length - 70.0)), + internal: vec![dart, line_path(Point::new(0.0, length - 25.0), Point::new(side_hem.x, length - 25.0))], + labels: labels(design, name, cut_count, on_fold, Point::new(waist_quarter * 0.18, length * 0.44), keys), + } +} + +impl Design for AlineSkirt { + fn id(&self) -> &'static str { "aline_skirt" } + fn name(&self) -> &'static str { "A-line skirt" } + fn options(&self) -> Vec { Self::specs(630.0) } + + fn draft(&self, m: &Measurements, options: &Options) -> Result { + let waist = measurement(m.waist, "waist")?; + let hip = measurement(m.hip, "hip")?; + let waist_to_hip = measurement(m.waist_to_hip, "waist_to_hip")?; + let waist_to_knee = measurement(m.waist_to_knee, "waist_to_knee")?; + + let specs = Self::specs(waist_to_knee + 50.0); + let waist_ease = option(options, &specs[0])?; + let hip_ease = option(options, &specs[1])?; + let flare = option(options, &specs[2])?; + let length = option(options, &specs[3])?; + let front_dart_length = option(options, &specs[4])?; + let back_dart_length = (front_dart_length + 30.0).min(200.0); + let waist_quarter = (waist + waist_ease) / 4.0; + let hip_quarter = (hip + hip_ease) / 4.0; + let keys = [("waist", waist), ("hip", hip), ("waist-to-hip", waist_to_hip)]; + + let front = skirt_piece( + "Front", self.name(), true, 1, waist_quarter, hip_quarter, waist_to_hip, length, flare, front_dart_length, keys, + ); + let back = skirt_piece( + "Back", self.name(), false, 2, waist_quarter, hip_quarter, waist_to_hip, length, flare, back_dart_length, keys, + ); + let band_length = waist + waist_ease + 30.0; + let mut band_outline = Path { start: Point::new(0.0, 0.0), ..Path::default() }; + band_outline.line_to(Point::new(80.0, 0.0)); + band_outline.line_to(Point::new(80.0, band_length)); + band_outline.line_to(Point::new(0.0, band_length)); + band_outline.close(); + let waistband = Part { + name: "Waistband".to_owned(), + cut_count: 1, + on_fold: false, + outline: band_outline, + seam_allowance_mm: 10.0, + notches: vec![ + Point::new(0.0, 15.0), + Point::new(0.0, 15.0 + waist_quarter), + Point::new(0.0, 15.0 + 3.0 * waist_quarter), + ], + grainline: (Point::new(40.0, 25.0), Point::new(40.0, band_length - 25.0)), + internal: vec![line_path(Point::new(40.0, 0.0), Point::new(40.0, band_length))], + labels: labels(self.name(), "Waistband", 1, false, Point::new(12.0, band_length * 0.38), keys), + }; + + Ok(Pattern { + design_id: self.id().to_owned(), + design_name: self.name().to_owned(), + parts: vec![front, back, waistband], + measurements_used: vec!["waist", "hip", "waist_to_hip", "waist_to_knee"], + }) + } +} diff --git a/libs/fabric/draft/src/designs/easy_trousers.rs b/libs/fabric/draft/src/designs/easy_trousers.rs new file mode 100644 index 000000000..d4ff26c4a --- /dev/null +++ b/libs/fabric/draft/src/designs/easy_trousers.rs @@ -0,0 +1,124 @@ +use super::{append_only_segment, labels, line_path, measurement}; +use crate::{curve_through, Design, DraftError, Measurements, OptionSpec, Options, Part, Path, Pattern, Point}; + +pub(crate) struct EasyTrousers; + +impl EasyTrousers { + fn specs(default_length: f64, default_hem: f64) -> Vec { + vec![ + OptionSpec { key: "hip_ease", label: "Hip ease", min: 20.0, max: 160.0, default: 60.0, unit: "mm" }, + OptionSpec { key: "length", label: "Length", min: 500.0, max: 1200.0, default: default_length.clamp(500.0, 1200.0), unit: "mm" }, + OptionSpec { key: "hem_width", label: "Hem width", min: 250.0, max: 600.0, default: default_hem.clamp(250.0, 600.0), unit: "mm" }, + ] + } +} + +fn option(options: &Options, spec: &OptionSpec) -> Result { + let value = options.get(spec); + if !value.is_finite() || value < spec.min || value > spec.max { + Err(DraftError::Invalid(format!("option {} must be between {} and {}", spec.key, spec.min, spec.max))) + } else { + Ok(value) + } +} + +fn interpolate_y(a: Point, b: Point, y: f64) -> Point { + let t = if (b.y - a.y).abs() < 1.0e-9 { 0.0 } else { (y - a.y) / (b.y - a.y) }; + Point::new(a.x + (b.x - a.x) * t, y) +} + +#[allow(clippy::too_many_arguments)] +fn trouser_piece( + name: &str, + design: &str, + is_back: bool, + quarter_hip: f64, + hip_line: f64, + crotch_line: f64, + knee_line: f64, + length: f64, + extension: f64, + hem_piece_width: f64, + outer_hem_x: f64, + keys: [(&str, f64); 3], +) -> Part { + let center_waist = Point::new(0.0, if is_back { -25.0 } else { 0.0 }); + let side_waist = Point::new(quarter_hip + 15.0, 0.0); + let hip_side = Point::new(quarter_hip, hip_line); + let outer_hem = Point::new(outer_hem_x, length); + let inner_hem = Point::new(outer_hem_x - hem_piece_width, length); + let crotch_tip = Point::new(-extension, crotch_line); + let curve_start_y = if is_back { crotch_line * 0.5 } else { crotch_line * (2.0 / 3.0) }; + let curve_start = Point::new(0.0, curve_start_y); + + let mut outline = Path { start: center_waist, ..Path::default() }; + outline.line_to(side_waist); + append_only_segment(&mut outline, curve_through(side_waist, Point::new(-0.06, 1.0), hip_side, Point::new(0.0, 1.0), 0.22)); + outline.line_to(outer_hem); + outline.line_to(inner_hem); + outline.line_to(crotch_tip); + append_only_segment(&mut outline, curve_through(crotch_tip, Point::new(1.0, 0.0), curve_start, Point::new(0.0, -1.0), 0.42)); + outline.line_to(center_waist); + outline.close(); + + let outer_knee = interpolate_y(hip_side, outer_hem, knee_line); + let inner_knee = interpolate_y(crotch_tip, inner_hem, knee_line); + let casing_center = Point::new(0.0, center_waist.y + 35.0); + let casing_side = Point::new(side_waist.x, side_waist.y + 35.0); + Part { + name: name.to_owned(), + cut_count: 2, + on_fold: false, + outline, + seam_allowance_mm: 10.0, + notches: vec![outer_knee, inner_knee], + grainline: (Point::new((outer_knee.x + inner_knee.x) * 0.5, hip_line + 60.0), Point::new((outer_knee.x + inner_knee.x) * 0.5, length - 70.0)), + internal: vec![line_path(casing_center, casing_side)], + labels: labels(design, name, 2, false, Point::new(-extension * 0.25, length * 0.43), keys), + } +} + +impl Design for EasyTrousers { + fn id(&self) -> &'static str { "easy_trousers" } + fn name(&self) -> &'static str { "Easy trousers" } + fn options(&self) -> Vec { Self::specs(1020.0, 450.0) } + + fn draft(&self, m: &Measurements, options: &Options) -> Result { + let hip = measurement(m.hip, "hip")?; + let crotch_depth = measurement(m.crotch_depth, "crotch_depth")?; + let outseam = measurement(m.outseam, "outseam")?; + let knee = measurement(m.knee, "knee")?; + let waist_to_hip = measurement(m.waist_to_hip, "waist_to_hip")?; + let waist_to_knee = measurement(m.waist_to_knee, "waist_to_knee")?; + + let specs = Self::specs(outseam - 20.0, knee + 60.0); + let hip_ease = option(options, &specs[0])?; + let length = option(options, &specs[1])?; + let hem_width = option(options, &specs[2])?; + let quarter_hip = (hip + hip_ease) / 4.0; + let crotch_line = crotch_depth + 20.0; + let front_extension = hip / 16.0 - 5.0; + let back_extension = hip / 8.0 + 10.0; + let front_hem = hem_width * 0.5 * 0.47; + let back_hem = hem_width * 0.5 * 0.53; + // This center makes the straight front and back inseams exactly equal while + // retaining the requested 47/53 hem split and a shared outseam endpoint. + let outer_hem_x = (front_hem + back_hem - front_extension - back_extension) * 0.5; + let keys = [("hip", hip), ("crotch depth", crotch_depth), ("knee", knee)]; + + let front = trouser_piece( + "Front", self.name(), false, quarter_hip, waist_to_hip, crotch_line, waist_to_knee, + length, front_extension, front_hem, outer_hem_x, keys, + ); + let back = trouser_piece( + "Back", self.name(), true, quarter_hip, waist_to_hip, crotch_line, waist_to_knee, + length, back_extension, back_hem, outer_hem_x, keys, + ); + Ok(Pattern { + design_id: self.id().to_owned(), + design_name: self.name().to_owned(), + parts: vec![front, back], + measurements_used: vec!["hip", "crotch_depth", "outseam", "knee", "waist_to_hip", "waist_to_knee"], + }) + } +} diff --git a/libs/fabric/draft/src/designs/mod.rs b/libs/fabric/draft/src/designs/mod.rs new file mode 100644 index 000000000..9c22dc8ed --- /dev/null +++ b/libs/fabric/draft/src/designs/mod.rs @@ -0,0 +1,234 @@ +mod aline_skirt; +mod easy_trousers; +mod tshirt; + +use crate::geom::distance_to_polyline; +use crate::{flatten, Design, DraftError, Label, Measurements, Part, Path, Point, Segment}; + +pub(crate) fn all() -> Vec> { + vec![ + Box::new(tshirt::Tshirt), + Box::new(aline_skirt::AlineSkirt), + Box::new(easy_trousers::EasyTrousers), + ] +} + +pub(super) fn measurement(value_cm: f32, key: &'static str) -> Result { + if !value_cm.is_finite() || value_cm <= 0.0 { + Err(DraftError::MissingMeasurement(key)) + } else { + Ok(value_cm as f64 * 10.0) + } +} + +pub(super) fn labels( + design: &str, + part: &str, + cut_count: u8, + on_fold: bool, + at: Point, + measurements: [(&str, f64); 3], +) -> Vec