From 0286b5b6f3356e111af484cc99981397fb42458b Mon Sep 17 00:00:00 2001 From: Quin Gillespie Date: Mon, 9 Nov 2026 19:49:01 -0700 Subject: [PATCH 1/2] move prism to upstream master, and add the GDK speech, clipboard and no speech backends and the screen reader, speech engine and explicit selection flags --- crates/prism-sys/prism | 2 +- crates/prism-sys/src/lib.rs | 12 ++++++++++++ crates/prismer/src/features.rs | 6 ++++++ crates/prismer/src/id.rs | 6 ++++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/crates/prism-sys/prism b/crates/prism-sys/prism index 94329eb..291db9f 160000 --- a/crates/prism-sys/prism +++ b/crates/prism-sys/prism @@ -1 +1 @@ -Subproject commit 94329ebeccbaee7f70b3494a290c9dfaac0184ee +Subproject commit 291db9fe04ea9f5642266cbebfeb909db4f38553 diff --git a/crates/prism-sys/src/lib.rs b/crates/prism-sys/src/lib.rs index c595869..ba9c993 100644 --- a/crates/prism-sys/src/lib.rs +++ b/crates/prism-sys/src/lib.rs @@ -160,6 +160,12 @@ pub const PRISM_BACKEND_PERFORMS_SILENCE_TRIMMING_ON_SPEAK_TO_MEMORY: u64 = 1 << pub const PRISM_BACKEND_SUPPORTS_SPEAK_SSML: u64 = 1 << 27; /// Reserved. pub const PRISM_BACKEND_SUPPORTS_SPEAK_TO_MEMORY_SSML: u64 = 1 << 28; +/// The backend presents text through a screen reader. +pub const PRISM_BACKEND_IS_SCREEN_READER: u64 = 1 << 56; +/// The backend synthesizes speech without a screen reader. +pub const PRISM_BACKEND_IS_SPEECH_ENGINE: u64 = 1 << 57; +/// The backend is never selected by `prism_registry_create_best` or `prism_registry_acquire_best`, and is obtained only by requesting it by identifier or name. +pub const PRISM_BACKEND_REQUIRES_EXPLICIT_SELECTION: u64 = 1 << 58; /// The highest bit reserved for feature flags. pub const PRISM_BACKEND_FEATURE_MAX_BIT: u64 = 1 << 63; @@ -205,6 +211,12 @@ pub const PRISM_BACKEND_SYSTEM_ACCESS: PrismBackendId = 0x8380_F2A3_7B2C_3EB6; pub const PRISM_BACKEND_WINDOW_EYES: PrismBackendId = 0x9120_D899_0878_5C13; /// Spiel (Linux and BSDs only) pub const PRISM_BACKEND_SPIEL: PrismBackendId = 0x478B_44F1_4AD3_D89C; +/// Microsoft GDK speech synthesis (Windows, Xbox) (only built when the GDK's headers are present) +pub const PRISM_BACKEND_GDK_SPEECH: PrismBackendId = 0xD39D_8723_4941_6B11; +/// Places text on the system clipboard instead of presenting it (only used when requested by identifier or name) +pub const PRISM_BACKEND_CLIPBOARD: PrismBackendId = 0x7056_908D_E8F9_F991; +/// Produces no output, for testing (only used when requested by identifier or name) +pub const PRISM_BACKEND_NO_SPEECH: PrismBackendId = 0xC2C0_EAB0_BF97_A5F0; /// The `PrismConfig` layout version this binding describes. pub const PRISM_CONFIG_VERSION: u8 = 4; diff --git a/crates/prismer/src/features.rs b/crates/prismer/src/features.rs index bb30534..491563c 100644 --- a/crates/prismer/src/features.rs +++ b/crates/prismer/src/features.rs @@ -67,6 +67,12 @@ impl Features { pub const SPEAK_SSML: Self = Self(sys::PRISM_BACKEND_SUPPORTS_SPEAK_SSML); /// [`Backend::speak_to_memory`] accepts SSML markup. pub const SPEAK_TO_MEMORY_SSML: Self = Self(sys::PRISM_BACKEND_SUPPORTS_SPEAK_TO_MEMORY_SSML); + /// The backend presents text through a screen reader. At most one of this and [`Self::IS_SPEECH_ENGINE`] is set. + pub const IS_SCREEN_READER: Self = Self(sys::PRISM_BACKEND_IS_SCREEN_READER); + /// The backend synthesizes speech without a screen reader. + pub const IS_SPEECH_ENGINE: Self = Self(sys::PRISM_BACKEND_IS_SPEECH_ENGINE); + /// The best-backend choice never picks this backend; it's used only when asked for by ID or name. + pub const REQUIRES_EXPLICIT_SELECTION: Self = Self(sys::PRISM_BACKEND_REQUIRES_EXPLICIT_SELECTION); /// Returns `true` if every feature in `other` is present in `self`. #[must_use] diff --git a/crates/prismer/src/id.rs b/crates/prismer/src/id.rs index 2da0deb..e87f29e 100644 --- a/crates/prismer/src/id.rs +++ b/crates/prismer/src/id.rs @@ -50,4 +50,10 @@ impl BackendId { pub const WINDOW_EYES: Self = Self(sys::PRISM_BACKEND_WINDOW_EYES); /// Spiel (Linux). pub const SPIEL: Self = Self(sys::PRISM_BACKEND_SPIEL); + /// Microsoft GDK speech synthesis (Windows, Xbox), built only when the GDK's headers are present. + pub const GDK_SPEECH: Self = Self(sys::PRISM_BACKEND_GDK_SPEECH); + /// Places text on the system clipboard instead of presenting it. Used only when asked for by ID or name. + pub const CLIPBOARD: Self = Self(sys::PRISM_BACKEND_CLIPBOARD); + /// Produces no output, for testing. Used only when asked for by ID or name. + pub const NO_SPEECH: Self = Self(sys::PRISM_BACKEND_NO_SPEECH); } From 35a7d1cac0a6881176f6db619501f876007bc294 Mon Sep 17 00:00:00 2001 From: Quin Gillespie Date: Mon, 9 Nov 2026 19:55:49 -0700 Subject: [PATCH 2/2] link CoreServices and Security on macOS too, which the new prism's code signing checks call --- README.md | 2 +- crates/prism-sys/build.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0edef14..dd35074 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ cargo build By default prism is built and linked as a shared library; note that your application must be able to find it (next to the executable on Windows, or on the loader path elsewhere) at runtime. Enable the `static` feature to build and link it statically instead. The build script links the C++ runtime and the system libraries prism needs for you. -On Apple platforms that only holds when cargo does the final link. If you build a Rust `staticlib` and link it from Xcode, add the system frameworks to your Xcode target yourself: Foundation and AVFoundation everywhere, plus AppKit, IOKit and CoreFoundation on macOS, UIKit on iOS, tvOS and visionOS, or WatchKit on watchOS. prism's Objective-C++ also needs `libobjc`, which Xcode links for any target with Objective-C or Swift code of its own. +On Apple platforms that only holds when cargo does the final link. If you build a Rust `staticlib` and link it from Xcode, add the system frameworks to your Xcode target yourself: Foundation and AVFoundation everywhere, plus AppKit, CoreServices, Security, IOKit and CoreFoundation on macOS, UIKit on iOS, tvOS and visionOS, or WatchKit on watchOS. prism's Objective-C++ also needs `libobjc`, which Xcode links for any target with Objective-C or Swift code of its own. ## Custom backends diff --git a/crates/prism-sys/build.rs b/crates/prism-sys/build.rs index 5e5667b..c9ff9fc 100644 --- a/crates/prism-sys/build.rs +++ b/crates/prism-sys/build.rs @@ -75,7 +75,7 @@ fn link_pkg_config_deps(dst: &Path) { /// Links the frameworks prism links on Apple platforms, in `PrismPlatformApple.cmake`, which a static prism leaves to the final link too. fn link_apple_frameworks() { let platform: &[&str] = match env::var("CARGO_CFG_TARGET_OS").as_deref() { - Ok("macos") => &["AppKit", "IOKit", "CoreFoundation"], + Ok("macos") => &["AppKit", "CoreServices", "Security", "IOKit", "CoreFoundation"], Ok("ios" | "tvos" | "visionos") => &["UIKit"], Ok("watchos") => &["WatchKit"], _ => return,