Skip to main content

prism_sys/
lib.rs

1//! Raw FFI bindings to prism (<https://github.com/ethindp/prism>), a
2//! platform-agnostic speech and screen reader output library.
3#![no_std]
4#![allow(non_camel_case_types)]
5
6use core::ffi::{c_char, c_int, c_void};
7
8/// An opaque prism context, holding a backend registry.
9#[repr(C)]
10#[derive(Debug)]
11pub struct PrismContext {
12	_opaque: [u8; 0],
13}
14
15/// An opaque backend instance obtained from a registry.
16#[repr(C)]
17#[derive(Debug)]
18pub struct PrismBackend {
19	_opaque: [u8; 0],
20}
21
22/// An opaque, immutable set of backend registrations.
23#[repr(C)]
24#[derive(Debug)]
25pub struct PrismRegistry {
26	_opaque: [u8; 0],
27}
28
29/// An opaque, mutable collection of backend registrations.
30#[repr(C)]
31#[derive(Debug)]
32pub struct PrismRegistryBuilder {
33	_opaque: [u8; 0],
34}
35
36/// A backend's identifier, derived from its name.
37pub type PrismBackendId = u64;
38/// An error code. `PRISM_OK` means success; every other value is a failure.
39pub type PrismError = c_int;
40/// The severity of a log message, or a threshold for delivering them.
41pub type PrismLogLevel = c_int;
42
43/// Channel count was retrieved.
44pub const PRISM_OK: PrismError = 0;
45/// The backend has not been initialized.
46pub const PRISM_ERROR_NOT_INITIALIZED: PrismError = 1;
47/// The vtable's `size` member was zero, the declared feature set was inconsistent with the vtable, or the priority value was negative.
48pub const PRISM_ERROR_INVALID_PARAM: PrismError = 2;
49/// The backend does not support audio format queries.
50pub const PRISM_ERROR_NOT_IMPLEMENTED: PrismError = 3;
51/// No voices are available for this backend
52pub const PRISM_ERROR_NO_VOICES: PrismError = 4;
53/// The specified voice was not found
54pub const PRISM_ERROR_VOICE_NOT_FOUND: PrismError = 5;
55/// Speech synthesis failed.
56pub const PRISM_ERROR_SPEAK_FAILURE: PrismError = 6;
57/// Memory allocation failed during initialization.
58pub const PRISM_ERROR_MEMORY_FAILURE: PrismError = 7;
59/// A parameter value exceeded its valid range
60pub const PRISM_ERROR_RANGE_OUT_OF_BOUNDS: PrismError = 8;
61/// An internal error occurred during initialization.
62pub const PRISM_ERROR_INTERNAL: PrismError = 9;
63/// No speech is currently playing.
64pub const PRISM_ERROR_NOT_SPEAKING: PrismError = 10;
65/// Speech is not currently paused.
66pub const PRISM_ERROR_NOT_PAUSED: PrismError = 11;
67/// Speech is already paused.
68pub const PRISM_ERROR_ALREADY_PAUSED: PrismError = 12;
69/// `text` contains invalid UTF-8 sequences.
70pub const PRISM_ERROR_INVALID_UTF8: PrismError = 13;
71/// The builder is spent, or a backend with the same name or the same identifier is already present in the builder.
72pub const PRISM_ERROR_INVALID_OPERATION: PrismError = 14;
73/// The backend was already initialized.
74pub const PRISM_ERROR_ALREADY_INITIALIZED: PrismError = 15;
75/// The backend's underlying system component is unavailable.
76pub const PRISM_ERROR_BACKEND_NOT_AVAILABLE: PrismError = 16;
77/// An unspecified error occurred.
78pub const PRISM_ERROR_UNKNOWN: PrismError = 17;
79/// The audio format which the underlying engine returned to Prism cannot be understood by Prism, or it's parameters are nonsensical.
80pub const PRISM_ERROR_INVALID_AUDIO_FORMAT: PrismError = 18;
81/// The backend possesses an internal hard ceiling as to how many instances may be instantiated at any given time, and this limit would be exceeded were another to be initialized.
82pub const PRISM_ERROR_INTERNAL_BACKEND_LIMIT_EXCEEDED: PrismError = 19;
83/// An error occured when the backend was executing a function which has caused the backend to enter an undefined state. The caller should re-initialize the backend from scratch.
84pub const PRISM_ERROR_BACKEND_ENTERED_UNDEFINED_STATE: PrismError = 20;
85/// A shared library could not be opened, because no file exists at the given path, it is not a loadable image, it was built for a different architecture, or its initialization code failed
86pub const PRISM_ERROR_LIBRARY_LOAD_FAILED: PrismError = 21;
87/// A shared library was opened but does not export the plugin entry point
88pub const PRISM_ERROR_LIBRARY_INVALID: PrismError = 22;
89/// A plugin declined the host, or a backend descriptor declared an ABI generation this build of Prism does not accept
90pub const PRISM_ERROR_INCOMPATIBLE_ABI: PrismError = 23;
91/// The number of defined error codes. Not itself an error.
92pub const PRISM_ERROR_COUNT: PrismError = 24;
93
94/// The most verbose level, used for fine-grained tracing of internal operations.
95pub const PRISM_LOG_LEVEL_TRACE: PrismLogLevel = 0;
96/// Diagnostic information useful during development.
97pub const PRISM_LOG_LEVEL_DEBUG: PrismLogLevel = 1;
98/// Informational messages describing normal operation.
99pub const PRISM_LOG_LEVEL_INFO: PrismLogLevel = 2;
100/// Conditions that are not errors but MAY indicate a problem.
101pub const PRISM_LOG_LEVEL_WARN: PrismLogLevel = 3;
102/// Error conditions.
103pub const PRISM_LOG_LEVEL_ERROR: PrismLogLevel = 4;
104/// Not a message severity. When supplied to `prism_set_log_level`, it suppresses all messages, since no message has a severity greater than or equal to it.
105pub const PRISM_LOG_LEVEL_NONE: PrismLogLevel = 5;
106
107/// The underlying engine or service is available. This determination is advisory; `prism_backend_initialize` MAY still fail.
108pub const PRISM_BACKEND_IS_SUPPORTED_AT_RUNTIME: u64 = 1 << 0;
109/// `prism_backend_speak` is implemented.
110pub const PRISM_BACKEND_SUPPORTS_SPEAK: u64 = 1 << 2;
111/// `prism_backend_speak_to_memory` is implemented.
112pub const PRISM_BACKEND_SUPPORTS_SPEAK_TO_MEMORY: u64 = 1 << 3;
113/// `prism_backend_braille` is implemented.
114pub const PRISM_BACKEND_SUPPORTS_BRAILLE: u64 = 1 << 4;
115/// `prism_backend_output` is implemented.
116pub const PRISM_BACKEND_SUPPORTS_OUTPUT: u64 = 1 << 5;
117/// `prism_backend_is_speaking` is implemented.
118pub const PRISM_BACKEND_SUPPORTS_IS_SPEAKING: u64 = 1 << 6;
119/// `prism_backend_stop` is implemented.
120pub const PRISM_BACKEND_SUPPORTS_STOP: u64 = 1 << 7;
121/// `prism_backend_pause` is implemented.
122pub const PRISM_BACKEND_SUPPORTS_PAUSE: u64 = 1 << 8;
123/// `prism_backend_resume` is implemented.
124pub const PRISM_BACKEND_SUPPORTS_RESUME: u64 = 1 << 9;
125/// `prism_backend_set_volume` is implemented.
126pub const PRISM_BACKEND_SUPPORTS_SET_VOLUME: u64 = 1 << 10;
127/// `prism_backend_get_volume` is implemented.
128pub const PRISM_BACKEND_SUPPORTS_GET_VOLUME: u64 = 1 << 11;
129/// `prism_backend_set_rate` is implemented.
130pub const PRISM_BACKEND_SUPPORTS_SET_RATE: u64 = 1 << 12;
131/// `prism_backend_get_rate` is implemented.
132pub const PRISM_BACKEND_SUPPORTS_GET_RATE: u64 = 1 << 13;
133/// `prism_backend_set_pitch` is implemented.
134pub const PRISM_BACKEND_SUPPORTS_SET_PITCH: u64 = 1 << 14;
135/// `prism_backend_get_pitch` is implemented.
136pub const PRISM_BACKEND_SUPPORTS_GET_PITCH: u64 = 1 << 15;
137/// `prism_backend_refresh_voices` is implemented.
138pub const PRISM_BACKEND_SUPPORTS_REFRESH_VOICES: u64 = 1 << 16;
139/// `prism_backend_count_voices` is implemented.
140pub const PRISM_BACKEND_SUPPORTS_COUNT_VOICES: u64 = 1 << 17;
141/// `prism_backend_get_voice_name` is implemented.
142pub const PRISM_BACKEND_SUPPORTS_GET_VOICE_NAME: u64 = 1 << 18;
143/// `prism_backend_get_voice_language` is implemented.
144pub const PRISM_BACKEND_SUPPORTS_GET_VOICE_LANGUAGE: u64 = 1 << 19;
145/// `prism_backend_get_voice` is implemented.
146pub const PRISM_BACKEND_SUPPORTS_GET_VOICE: u64 = 1 << 20;
147/// `prism_backend_set_voice` is implemented.
148pub const PRISM_BACKEND_SUPPORTS_SET_VOICE: u64 = 1 << 21;
149/// `prism_backend_get_channels` is implemented.
150pub const PRISM_BACKEND_SUPPORTS_GET_CHANNELS: u64 = 1 << 22;
151/// `prism_backend_get_sample_rate` is implemented.
152pub const PRISM_BACKEND_SUPPORTS_GET_SAMPLE_RATE: u64 = 1 << 23;
153/// `prism_backend_get_bit_depth` is implemented.
154pub const PRISM_BACKEND_SUPPORTS_GET_BIT_DEPTH: u64 = 1 << 24;
155/// Reserved.
156pub const PRISM_BACKEND_PERFORMS_SILENCE_TRIMMING_ON_SPEAK: u64 = 1 << 25;
157/// The backend trims leading and trailing silence from the audio stream before delivering it to the audio callback.
158pub const PRISM_BACKEND_PERFORMS_SILENCE_TRIMMING_ON_SPEAK_TO_MEMORY: u64 = 1 << 26;
159/// Reserved.
160pub const PRISM_BACKEND_SUPPORTS_SPEAK_SSML: u64 = 1 << 27;
161/// Reserved.
162pub const PRISM_BACKEND_SUPPORTS_SPEAK_TO_MEMORY_SSML: u64 = 1 << 28;
163/// The highest bit reserved for feature flags.
164pub const PRISM_BACKEND_FEATURE_MAX_BIT: u64 = 1 << 63;
165
166/// Invalid/sentinel value (always 0)
167pub const PRISM_BACKEND_INVALID: PrismBackendId = 0;
168/// Microsoft SAPI (Windows)
169pub const PRISM_BACKEND_SAPI: PrismBackendId = 0x1D6D_F724_22CE_EE66;
170/// `AVSpeechSynthesizer` (macOS, iOS, tvOS, `WatchOS`, `VisionOS`)
171pub const PRISM_BACKEND_AV_SPEECH: PrismBackendId = 0x28E3_4295_7780_5C24;
172/// `VoiceOver` screen reader (macOS, `MacCatalyst`, iOS, `WatchOS`, tvOS, `VisionOS`)
173pub const PRISM_BACKEND_VOICE_OVER: PrismBackendId = 0xCB48_9796_1A75_4BCB;
174/// Speech Dispatcher (Linux/BSD, win32 via Wine)
175pub const PRISM_BACKEND_SPEECH_DISPATCHER: PrismBackendId = 0xE3D6_F895_D949_EBFE;
176/// NVDA screen reader (Windows)
177pub const PRISM_BACKEND_NVDA: PrismBackendId = 0x89CC_19C5_C4AC_1A56;
178/// JAWS screen reader (Windows)
179pub const PRISM_BACKEND_JAWS: PrismBackendId = 0xAC3D_60E9_BD84_B53E;
180/// Windows `OneCore` speech API (Windows 10+)
181pub const PRISM_BACKEND_ONE_CORE: PrismBackendId = 0x6797_D32F_0D99_4CB4;
182/// Orca screen reader (Linux/BSD, win32 via Wine)
183pub const PRISM_BACKEND_ORCA: PrismBackendId = 0x10AA_1FC0_5A17_F96C;
184/// Android screen readers (Android)
185pub const PRISM_BACKEND_ANDROID_SCREEN_READER: PrismBackendId = 0xD199_C175_AEEC_494B;
186/// Android TTS engine (Android)
187pub const PRISM_BACKEND_ANDROID_TTS: PrismBackendId = 0xBC17_5831_BFE4_E5CC;
188/// Web `SpeechSynthesis` API (web)
189pub const PRISM_BACKEND_WEB_SPEECH: PrismBackendId = 0x3572_538D_44D4_4A8F;
190/// `UIAutomation` backend (Windows only)
191pub const PRISM_BACKEND_UIA: PrismBackendId = 0x6238_F019_DB67_8F8E;
192/// Zhengdu Screen Reader (Windows)
193pub const PRISM_BACKEND_ZDSR: PrismBackendId = 0x3D93_C56C_9E7F_2A2E;
194/// `ZoomText` (Windows)
195pub const PRISM_BACKEND_ZOOM_TEXT: PrismBackendId = 0xAE43_9D62_DC7B_1479;
196/// `BoyPCReader` (windows only)
197pub const PRISM_BACKEND_BOY_PC_READER: PrismBackendId = 0x285A_BA1C_16F3_300F;
198/// `PCTalker` (windows only)
199pub const PRISM_BACKEND_PC_TALKER: PrismBackendId = 0x344B_9519_62E3_B835;
200/// Sense Reader screen reader (Windows)
201pub const PRISM_BACKEND_SENSE_READER: PrismBackendId = 0xED47_6089_0B55_C2F2;
202/// `SystemAccess` screen reader (windows) (only available if explicitly enabled at build time)
203pub const PRISM_BACKEND_SYSTEM_ACCESS: PrismBackendId = 0x8380_F2A3_7B2C_3EB6;
204/// `WindowEyes` screen reader (windows) (only available if explicitly enabled at build time)
205pub const PRISM_BACKEND_WINDOW_EYES: PrismBackendId = 0x9120_D899_0878_5C13;
206/// Spiel (Linux and BSDs only)
207pub const PRISM_BACKEND_SPIEL: PrismBackendId = 0x478B_44F1_4AD3_D89C;
208
209/// The `PrismConfig` layout version this binding describes.
210pub const PRISM_CONFIG_VERSION: u8 = 3;
211/// The plugin ABI generation this binding describes.
212pub const PRISM_PLUGIN_ABI_VERSION: u64 = 1;
213
214/// The type of a function invoked when a backend's runtime availability changes.
215pub type PrismAvailabilityCallback =
216	Option<unsafe extern "C" fn(userdata: *mut c_void, backend: PrismBackendId, name: *const c_char, available: bool)>;
217
218/// Receives audio samples from `prism_backend_speak_to_memory`.
219pub type PrismAudioCallback = Option<
220	unsafe extern "C" fn(
221		userdata: *mut c_void,
222		samples: *const f32,
223		sample_count: usize,
224		channels: usize,
225		sample_rate: usize,
226	),
227>;
228
229/// The type of a function invoked to deliver a single log message.
230pub type PrismLogCallback = Option<
231	unsafe extern "C" fn(userdata: *mut c_void, level: PrismLogLevel, source: *const c_char, message: *const c_char),
232>;
233
234/// A struct containing configuration parameters for Prism or it's back-ends to use.
235#[repr(C)]
236#[derive(Debug, Clone, Copy)]
237pub struct PrismConfig {
238	/// The version of this structure. This field MUST NOT be modified.
239	pub version: u8,
240	/// The registry the created context will be bound to. This MAY be `NULL`, in which case the context uses the global registry. If non-null, it MUST be a registry obtained from `prism_registry_freeze`. This field was added in version 3 of this structure.
241	pub registry: *mut PrismRegistry,
242	/// A function invoked when a backend's runtime availability changes, or `NULL`. When this field is `NULL`, the context performs no background availability polling and creates no poll thread. When it is non-null, the context runs an internal thread that samples backend availability and invokes this callback on each confirmed transition. The behavior of this callback and the polling model are described in the chapter on background availability enumeration. This field was added in version 3 of this structure.
243	pub availability_callback: PrismAvailabilityCallback,
244	/// An opaque pointer passed unmodified to `availability_callback` on each invocation. Prism does not interpret or take ownership of this value. It is ignored when `availability_callback` is `NULL`. This field was added in version 3 of this structure.
245	pub availability_userdata: *mut c_void,
246	/// The base interval, in milliseconds, between availability scans. A value of `0` selects the default of 1000 milliseconds. It is ignored when `availability_callback` is `NULL`. This field was added in version 3 of this structure.
247	pub availability_poll_interval_ms: u32,
248	/// The number of consecutive agreeing samples required before a change in a backend's availability is confirmed and reported. A value of `0` selects the default of 2. A value of `1` confirms every observed change immediately, without debouncing. It is ignored when `availability_callback` is `NULL`. This field was added in version 3 of this structure.
249	pub availability_debounce_samples: u32,
250	/// The upper bound, in milliseconds, for adaptive backoff of the sampling interval. While availability is unchanging, the interval doubles from `availability_poll_interval_ms` toward this bound, and returns to the base interval as soon as any change is observed. A value of `0`, or any value not greater than the base interval, disables backoff and holds the interval constant. It is ignored when `availability_callback` is `NULL`. This field was added in version 3 of this structure.
251	pub availability_backoff_max_ms: u32,
252	/// When `true`, and when the library was built with power-management support, the poll thread is paused automatically when the operating system suspends and resumed when it wakes. When `false`, or on builds and platforms without power-management support, this field has no effect and the application MAY drive pausing itself. Use `prism_availability_auto_power_supported` to determine whether this field is honored. It is ignored when `availability_callback` is `NULL`. This field was added in version 3 of this structure.
253	pub availability_auto_power_manage: bool,
254}
255
256/// A table of function pointers implementing a custom backend.
257#[repr(C)]
258#[derive(Debug, Clone, Copy)]
259pub struct PrismBackendVTable {
260	/// The size of this structure as known to the application. This member MUST be set to `sizeof(PrismBackendVTable)`. Prism reads at most `size` bytes from the structure. If `size` is smaller than the size of the structure as this version of Prism defines it, the members beyond `size` are treated as null; if it is larger, the additional bytes are ignored. This scheme permits the structure to grow in later library versions without invalidating applications compiled against earlier ones.
261	pub size: usize,
262	/// An optional function producing a per-instance state pointer. If non-null, Prism invokes it exactly once for each backend instance constructed from the registration, passing the registration's `userdata`, and thereafter passes the returned pointer as the `instance` argument to every other member invoked for that instance. Should `create` return `NULL`, construction of the instance fails. If `create` is null, the registration's `userdata` pointer is passed as the `instance` argument directly, and all instances of the backend consequently share it.
263	pub create: Option<unsafe extern "C" fn(userdata: *mut c_void) -> *mut c_void>,
264	/// An optional function releasing a state pointer previously returned by `create`. If both `create` and `destroy` are non-null, Prism invokes `destroy` exactly once for each backend instance, at the time the instance is freed. `destroy` is never invoked if `create` is null.
265	pub destroy: Option<unsafe extern "C" fn(instance: *mut c_void)>,
266	/// An optional runtime availability probe. If non-null, Prism invokes it to determine the `PRISM_BACKEND_IS_SUPPORTED_AT_RUNTIME` bit reported by `prism_backend_get_features`; if null, the bit declared at registration is reported unchanged. Because `prism_backend_get_features` MAY be called before initialization, `is_supported` MAY be invoked before `initialize` has succeeded, and an implementation of it MUST NOT assume the instance has been initialized. This member designates no operation and is therefore exempt from the feature consistency requirement of `prism_registry_builder_add_backend`.
267	pub is_supported: Option<unsafe extern "C" fn(instance: *mut c_void) -> bool>,
268	/// Implements `prism_backend_initialize`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
269	pub initialize: Option<unsafe extern "C" fn(instance: *mut c_void) -> PrismError>,
270	/// Implements `prism_backend_speak`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
271	pub speak: Option<unsafe extern "C" fn(instance: *mut c_void, text: *const c_char, interrupt: bool) -> PrismError>,
272	/// Implements `prism_backend_speak_to_memory`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
273	pub speak_to_memory: Option<
274		unsafe extern "C" fn(
275			instance: *mut c_void,
276			text: *const c_char,
277			callback: PrismAudioCallback,
278			callback_userdata: *mut c_void,
279		) -> PrismError,
280	>,
281	/// Implements `prism_backend_braille`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
282	pub braille: Option<unsafe extern "C" fn(instance: *mut c_void, text: *const c_char) -> PrismError>,
283	/// Implements `prism_backend_output`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
284	pub output: Option<unsafe extern "C" fn(instance: *mut c_void, text: *const c_char, interrupt: bool) -> PrismError>,
285	/// Implements `prism_backend_stop`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
286	pub stop: Option<unsafe extern "C" fn(instance: *mut c_void) -> PrismError>,
287	/// Implements `prism_backend_pause`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
288	pub pause: Option<unsafe extern "C" fn(instance: *mut c_void) -> PrismError>,
289	/// Implements `prism_backend_resume`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
290	pub resume: Option<unsafe extern "C" fn(instance: *mut c_void) -> PrismError>,
291	/// Implements `prism_backend_is_speaking`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
292	pub is_speaking: Option<unsafe extern "C" fn(instance: *mut c_void, out_speaking: *mut bool) -> PrismError>,
293	/// Implements `prism_backend_set_volume`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
294	pub set_volume: Option<unsafe extern "C" fn(instance: *mut c_void, volume: f32) -> PrismError>,
295	/// Implements `prism_backend_get_volume`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
296	pub get_volume: Option<unsafe extern "C" fn(instance: *mut c_void, out_volume: *mut f32) -> PrismError>,
297	/// Implements `prism_backend_set_rate`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
298	pub set_rate: Option<unsafe extern "C" fn(instance: *mut c_void, rate: f32) -> PrismError>,
299	/// Implements `prism_backend_get_rate`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
300	pub get_rate: Option<unsafe extern "C" fn(instance: *mut c_void, out_rate: *mut f32) -> PrismError>,
301	/// Implements `prism_backend_set_pitch`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
302	pub set_pitch: Option<unsafe extern "C" fn(instance: *mut c_void, pitch: f32) -> PrismError>,
303	/// Implements `prism_backend_get_pitch`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
304	pub get_pitch: Option<unsafe extern "C" fn(instance: *mut c_void, out_pitch: *mut f32) -> PrismError>,
305	/// Implements `prism_backend_refresh_voices`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
306	pub refresh_voices: Option<unsafe extern "C" fn(instance: *mut c_void) -> PrismError>,
307	/// Implements `prism_backend_count_voices`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
308	pub count_voices: Option<unsafe extern "C" fn(instance: *mut c_void, out_count: *mut usize) -> PrismError>,
309	/// Implements `prism_backend_get_voice_name`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
310	pub get_voice_name: Option<
311		unsafe extern "C" fn(instance: *mut c_void, voice_id: usize, out_name: *mut *const c_char) -> PrismError,
312	>,
313	/// Implements `prism_backend_get_voice_language`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
314	pub get_voice_language: Option<
315		unsafe extern "C" fn(instance: *mut c_void, voice_id: usize, out_language: *mut *const c_char) -> PrismError,
316	>,
317	/// Implements `prism_backend_set_voice`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
318	pub set_voice: Option<unsafe extern "C" fn(instance: *mut c_void, voice_id: usize) -> PrismError>,
319	/// Implements `prism_backend_get_voice`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
320	pub get_voice: Option<unsafe extern "C" fn(instance: *mut c_void, out_voice_id: *mut usize) -> PrismError>,
321	/// Implements `prism_backend_get_channels`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
322	pub get_channels: Option<unsafe extern "C" fn(instance: *mut c_void, out_channels: *mut usize) -> PrismError>,
323	/// Implements `prism_backend_get_sample_rate`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
324	pub get_sample_rate: Option<unsafe extern "C" fn(instance: *mut c_void, out_sample_rate: *mut usize) -> PrismError>,
325	/// Implements `prism_backend_get_bit_depth`, taking the instance pointer in place of the backend. Null means the operation is unimplemented.
326	pub get_bit_depth: Option<unsafe extern "C" fn(instance: *mut c_void, out_bit_depth: *mut usize) -> PrismError>,
327}
328
329/// A structure pairing a log callback with an opaque user pointer.
330#[repr(C)]
331#[derive(Debug, Clone, Copy)]
332pub struct PrismLogHandler {
333	/// The callback invoked to deliver messages, or `NULL` to install no handler. When `fn` is `NULL`, messages are discarded.
334	pub fn_: PrismLogCallback,
335	/// An opaque pointer passed unmodified to `fn` on each invocation. Prism does not interpret or take ownership of this value. The lifetime of this value is the lifetime of the handler function, and therefore this value must be valid for as long as the handler is alive.
336	pub userdata: *mut c_void,
337}
338
339/// A structure through which a backend supplied by a plugin reaches the facilities Prism makes available to it. Prism provides one to each backend it registers from a plugin, as described under Host services.
340#[repr(C)]
341#[derive(Debug)]
342pub struct PrismPluginServices {
343	/// The size of this structure as Prism understands it. A backend MUST consult at most this many bytes and MUST treat any member beyond it as absent. A later generation MAY append members after those defined here.
344	pub struct_size: u32,
345	/// Reserved for future use. Prism sets this member to zero, and a backend MUST ignore it.
346	pub reserved: u32,
347	/// A function through which the backend records diagnostics. Its first argument MUST be the services object Prism supplied. Prism records the diagnostic under the name of the backend to which the services object belongs; the backend does not supply a source. This member is never `NULL`.
348	pub log: Option<unsafe extern "C" fn(self_: *const Self, level: PrismLogLevel, message: *const c_char)>,
349}
350
351/// The structure Prism passes as the `userdata` argument to the `create` member of a backend supplied by a plugin. The context is valid only for the duration of the `create` call; the services object it names is valid for the longer period given under Host services.
352#[repr(C)]
353#[derive(Debug)]
354pub struct PrismPluginInstanceContext {
355	/// The size of this structure as Prism understands it. A backend MUST consult at most this many bytes and MUST treat any member beyond it as absent.
356	pub struct_size: u32,
357	/// Reserved for future use. Prism sets this member to zero, and a backend MUST ignore it.
358	pub reserved: u32,
359	/// The backend's services object. A backend MAY retain it for the period given under Host services. This member is never `NULL`.
360	pub services: *const PrismPluginServices,
361	/// The value of the `userdata` member of the descriptor from which the backend was registered.
362	pub userdata: *mut c_void,
363}
364
365/// A structure describing the loading Prism library, passed to a plugin's entry point.
366#[repr(C)]
367#[derive(Debug)]
368pub struct PrismPluginHost {
369	/// The plugin ABI generation this implementation provides, equal to the `PRISM_PLUGIN_ABI_VERSION` against which Prism was compiled. A plugin MAY compare this value against its own requirements and decline to supply backends if it requires a newer host.
370	pub abi_version: u64,
371	/// The size of this structure as Prism understands it. A plugin MUST consult at most this many bytes and MUST treat any member beyond it as absent.
372	pub struct_size: u32,
373	/// Reserved for future use. Prism sets this member to zero, and a plugin MUST ignore it.
374	pub reserved: u32,
375	/// A function through which the plugin MAY record diagnostics during the entry point call. Its first argument MUST be the host descriptor Prism supplied; the plugin does not supply a source, and Prism records the diagnostic under a source that names the library being loaded. This member is never `NULL`. A plugin SHOULD use it to state the reason for declining a host, and MUST NOT retain the pointer beyond the entry point call.
376	pub log: Option<unsafe extern "C" fn(self_: *const Self, level: PrismLogLevel, message: *const c_char)>,
377}
378
379/// A descriptor supplied by a plugin to describe a single backend.
380#[repr(C)]
381#[derive(Debug)]
382pub struct PrismPluginBackend {
383	/// The plugin ABI generation this descriptor was built against. A plugin MUST set this member to the `PRISM_PLUGIN_ABI_VERSION` against which it was compiled. Prism rejects a descriptor whose generation it does not accept, as described under ABI compatibility.
384	pub abi_version: u64,
385	/// The size of this structure as the plugin understands it. A plugin MUST set this member to `sizeof(PrismPluginBackend)`. Prism consults at most this many bytes.
386	pub struct_size: u32,
387	/// Reserved for future use. A plugin MUST set this member to zero.
388	pub reserved: u32,
389	/// The backend's name, as a null-terminated UTF-8 string, subject to the same requirements and consequences as the `name` parameter of `prism_registry_builder_add_backend`. The backend's identifier is derived from it by the hash function described in the chapter on backend identifiers. The string is copied during loading.
390	pub name: *const c_char,
391	/// The backend's priority. Higher values indicate higher priority. This value MUST be non-negative unless the loading call supplies a priority override, in which case it is ignored.
392	pub priority: c_int,
393	/// The feature set the backend declares, formed by `ORing` `PRISM_BACKEND_*` feature constants together. It MUST be consistent with the vtable in the sense required of any custom backend.
394	pub features: u64,
395	/// The vtable implementing the backend, subject to every requirement placed on a vtable by the chapter on custom backends. This member MUST NOT be `NULL`, and its `size` member MUST be set as that chapter requires. The vtable MUST provide a `create` member, as described under Host services. The vtable is copied during loading; the code it names remains valid while the library remains loaded.
396	pub vtable: *const PrismBackendVTable,
397	/// An opaque pointer that Prism delivers to the backend's `create` member as the `userdata` member of a `PrismPluginInstanceContext` (see `PrismPluginInstanceContext`). It has the meaning the `userdata` parameter of `prism_registry_builder_add_backend` would have, and permits several descriptors that share one vtable to be distinguished at instance creation. This member MAY be `NULL`. Prism does not free it.
398	pub userdata: *mut c_void,
399	/// An informational version identifying the plugin's own release, distinct from the ABI generation and used for no compatibility decision. The value is three 16-bit components, major, minor, and patch, packed most-significant first, with the least-significant 16 bits reserved and set to zero. A plugin MAY set it to zero if it has no version to report.
400	pub plugin_version: u64,
401}
402
403/// The entry point a prism plugin shared library exports.
404pub type PrismPluginQueryFn =
405	Option<unsafe extern "C" fn(host: *const PrismPluginHost, index: usize) -> *const PrismPluginBackend>;
406
407unsafe extern "C" {
408	/// Creates a new configuration structure which can be passed to `prism_init`.
409	///
410	/// # Safety
411	///
412	/// Safe to call at any time; this is `unsafe` only because it crosses the FFI boundary.
413	pub fn prism_config_init() -> PrismConfig;
414	/// Creates a new Prism context.
415	///
416	/// # Safety
417	///
418	/// `cfg` must be null, or point to a writable, initialized `PrismConfig`.
419	pub fn prism_init(cfg: *mut PrismConfig) -> *mut PrismContext;
420	/// Destroys a Prism context and releases associated resources.
421	///
422	/// # Safety
423	///
424	/// `ctx` must be a live context from `prism_init` that has not been passed to `prism_shutdown`.
425	/// The context is invalid once this returns.
426	pub fn prism_shutdown(ctx: *mut PrismContext);
427	/// Pauses the availability poll thread.
428	///
429	/// # Safety
430	///
431	/// `ctx` must be a live context from `prism_init` that has not been passed to `prism_shutdown`.
432	pub fn prism_availability_poll_pause(ctx: *mut PrismContext);
433	/// Resumes the availability poll thread.
434	///
435	/// # Safety
436	///
437	/// `ctx` must be a live context from `prism_init` that has not been passed to `prism_shutdown`.
438	pub fn prism_availability_poll_resume(ctx: *mut PrismContext);
439	/// Reports whether this build can pause and resume polling automatically in response to operating-system power transitions.
440	///
441	/// # Safety
442	///
443	/// Safe to call at any time; this is `unsafe` only because it crosses the FFI boundary.
444	pub fn prism_availability_auto_power_supported() -> bool;
445	/// Returns the number of backends registered in the registry.
446	///
447	/// # Safety
448	///
449	/// `ctx` must be a live context from `prism_init` that has not been passed to `prism_shutdown`.
450	pub fn prism_registry_count(ctx: *mut PrismContext) -> usize;
451	/// Returns the backend ID at the specified index in the registry.
452	///
453	/// # Safety
454	///
455	/// `ctx` must be a live context from `prism_init` that has not been passed to `prism_shutdown`.
456	pub fn prism_registry_id_at(ctx: *mut PrismContext, index: usize) -> PrismBackendId;
457	/// Looks up a backend by name and returns its ID.
458	///
459	/// # Safety
460	///
461	/// `ctx` must be a live context from `prism_init` that has not been passed to `prism_shutdown`.
462	/// `name` must be a non-null, NUL-terminated UTF-8 string valid for the call.
463	pub fn prism_registry_id(ctx: *mut PrismContext, name: *const c_char) -> PrismBackendId;
464	/// Returns the human-readable name of a backend given its ID.
465	///
466	/// # Safety
467	///
468	/// `ctx` must be a live context from `prism_init` that has not been passed to `prism_shutdown`.
469	pub fn prism_registry_name(ctx: *mut PrismContext, id: PrismBackendId) -> *const c_char;
470	/// Returns the priority value of a backend.
471	///
472	/// # Safety
473	///
474	/// `ctx` must be a live context from `prism_init` that has not been passed to `prism_shutdown`.
475	pub fn prism_registry_priority(ctx: *mut PrismContext, id: PrismBackendId) -> c_int;
476	/// Checks whether a backend with the given ID exists in the registry.
477	///
478	/// # Safety
479	///
480	/// `ctx` must be a live context from `prism_init` that has not been passed to `prism_shutdown`.
481	pub fn prism_registry_exists(ctx: *mut PrismContext, id: PrismBackendId) -> bool;
482	/// Retrieves a cached backend instance if one exists.
483	///
484	/// # Safety
485	///
486	/// `ctx` must be a live context from `prism_init` that has not been passed to `prism_shutdown`.
487	pub fn prism_registry_get(ctx: *mut PrismContext, id: PrismBackendId) -> *mut PrismBackend;
488	/// Creates a new backend instance.
489	///
490	/// # Safety
491	///
492	/// `ctx` must be a live context from `prism_init` that has not been passed to `prism_shutdown`.
493	pub fn prism_registry_create(ctx: *mut PrismContext, id: PrismBackendId) -> *mut PrismBackend;
494	/// Creates a new instance of the highest-priority backend that successfully initializes.
495	///
496	/// # Safety
497	///
498	/// `ctx` must be a live context from `prism_init` that has not been passed to `prism_shutdown`.
499	pub fn prism_registry_create_best(ctx: *mut PrismContext) -> *mut PrismBackend;
500	/// Acquires a backend instance, reusing a cached instance if available or creating a new one otherwise.
501	///
502	/// # Safety
503	///
504	/// `ctx` must be a live context from `prism_init` that has not been passed to `prism_shutdown`.
505	pub fn prism_registry_acquire(ctx: *mut PrismContext, id: PrismBackendId) -> *mut PrismBackend;
506	/// Acquires the highest-priority backend that successfully initializes, reusing a cached instance if available.
507	///
508	/// # Safety
509	///
510	/// `ctx` must be a live context from `prism_init` that has not been passed to `prism_shutdown`.
511	pub fn prism_registry_acquire_best(ctx: *mut PrismContext) -> *mut PrismBackend;
512	/// Releases a backend instance.
513	///
514	/// # Safety
515	///
516	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
517	/// The pointer is invalid once this returns.
518	pub fn prism_backend_free(backend: *mut PrismBackend);
519	/// Returns the human-readable name of a backend.
520	///
521	/// # Safety
522	///
523	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
524	pub fn prism_backend_name(backend: *mut PrismBackend) -> *const c_char;
525	/// Returns a bitmask of all features supported by this backend, as well as other information.
526	///
527	/// # Safety
528	///
529	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
530	pub fn prism_backend_get_features(backend: *mut PrismBackend) -> u64;
531	/// Initializes a backend instance.
532	///
533	/// # Safety
534	///
535	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
536	pub fn prism_backend_initialize(backend: *mut PrismBackend) -> PrismError;
537	/// Synthesizes speech from the given text and plays it through the default audio output.
538	///
539	/// # Safety
540	///
541	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
542	/// `text` must be a non-null, NUL-terminated UTF-8 string valid for the call.
543	pub fn prism_backend_speak(backend: *mut PrismBackend, text: *const c_char, interrupt: bool) -> PrismError;
544	/// Synthesizes speech from the given text and delivers the audio samples to a callback function.
545	///
546	/// # Safety
547	///
548	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
549	/// `text` must be a non-null, NUL-terminated UTF-8 string valid for the call.
550	/// `userdata` is passed through untouched; it must satisfy whatever the paired callback expects and stay alive as long as that callback can run.
551	pub fn prism_backend_speak_to_memory(
552		backend: *mut PrismBackend,
553		text: *const c_char,
554		callback: PrismAudioCallback,
555		userdata: *mut c_void,
556	) -> PrismError;
557	/// Outputs text to a connected braille display.
558	///
559	/// # Safety
560	///
561	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
562	/// `text` must be a non-null, NUL-terminated UTF-8 string valid for the call.
563	pub fn prism_backend_braille(backend: *mut PrismBackend, text: *const c_char) -> PrismError;
564	/// Outputs text using all available modalities supported by the backend.
565	///
566	/// # Safety
567	///
568	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
569	/// `text` must be a non-null, NUL-terminated UTF-8 string valid for the call.
570	pub fn prism_backend_output(backend: *mut PrismBackend, text: *const c_char, interrupt: bool) -> PrismError;
571	/// Immediately stops any currently playing speech.
572	///
573	/// # Safety
574	///
575	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
576	pub fn prism_backend_stop(backend: *mut PrismBackend) -> PrismError;
577	/// Pauses currently playing speech.
578	///
579	/// # Safety
580	///
581	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
582	pub fn prism_backend_pause(backend: *mut PrismBackend) -> PrismError;
583	/// Resumes previously paused speech.
584	///
585	/// # Safety
586	///
587	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
588	pub fn prism_backend_resume(backend: *mut PrismBackend) -> PrismError;
589	/// Queries whether the backend is currently producing speech output.
590	///
591	/// # Safety
592	///
593	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
594	/// `out_speaking` must be null, or a writable pointer to a `bool`.
595	pub fn prism_backend_is_speaking(backend: *mut PrismBackend, out_speaking: *mut bool) -> PrismError;
596	/// Sets the speech volume.
597	///
598	/// # Safety
599	///
600	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
601	pub fn prism_backend_set_volume(backend: *mut PrismBackend, volume: f32) -> PrismError;
602	/// Retrieves the current speech volume.
603	///
604	/// # Safety
605	///
606	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
607	/// `out_volume` must be null, or a writable pointer to a `f32`.
608	pub fn prism_backend_get_volume(backend: *mut PrismBackend, out_volume: *mut f32) -> PrismError;
609	/// Sets the speech rate (speed).
610	///
611	/// # Safety
612	///
613	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
614	pub fn prism_backend_set_rate(backend: *mut PrismBackend, rate: f32) -> PrismError;
615	/// Retrieves the current speech rate.
616	///
617	/// # Safety
618	///
619	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
620	/// `out_rate` must be null, or a writable pointer to a `f32`.
621	pub fn prism_backend_get_rate(backend: *mut PrismBackend, out_rate: *mut f32) -> PrismError;
622	/// Sets the speech pitch.
623	///
624	/// # Safety
625	///
626	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
627	pub fn prism_backend_set_pitch(backend: *mut PrismBackend, pitch: f32) -> PrismError;
628	/// Retrieves the current speech pitch.
629	///
630	/// # Safety
631	///
632	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
633	/// `out_pitch` must be null, or a writable pointer to a `f32`.
634	pub fn prism_backend_get_pitch(backend: *mut PrismBackend, out_pitch: *mut f32) -> PrismError;
635	/// Refreshes the backend's internal voice list.
636	///
637	/// # Safety
638	///
639	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
640	pub fn prism_backend_refresh_voices(backend: *mut PrismBackend) -> PrismError;
641	/// Returns the number of voices available from the backend.
642	///
643	/// # Safety
644	///
645	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
646	/// `out_count` must be null, or a writable pointer to a `usize`.
647	pub fn prism_backend_count_voices(backend: *mut PrismBackend, out_count: *mut usize) -> PrismError;
648	/// Retrieves the human-readable name of a voice.
649	///
650	/// # Safety
651	///
652	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
653	/// `out_name` must be null, or a writable pointer to a `*const c_char`.
654	pub fn prism_backend_get_voice_name(
655		backend: *mut PrismBackend,
656		voice_id: usize,
657		out_name: *mut *const c_char,
658	) -> PrismError;
659	/// Retrieves the language code or language string of a voice.
660	///
661	/// # Safety
662	///
663	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
664	/// `out_language` must be null, or a writable pointer to a `*const c_char`.
665	pub fn prism_backend_get_voice_language(
666		backend: *mut PrismBackend,
667		voice_id: usize,
668		out_language: *mut *const c_char,
669	) -> PrismError;
670	/// Selects a voice to use for subsequent speech synthesis.
671	///
672	/// # Safety
673	///
674	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
675	pub fn prism_backend_set_voice(backend: *mut PrismBackend, voice_id: usize) -> PrismError;
676	/// Retrieves the index of the currently selected voice.
677	///
678	/// # Safety
679	///
680	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
681	/// `out_voice_id` must be null, or a writable pointer to a `usize`.
682	pub fn prism_backend_get_voice(backend: *mut PrismBackend, out_voice_id: *mut usize) -> PrismError;
683	/// Retrieves the number of audio channels produced by the backend.
684	///
685	/// # Safety
686	///
687	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
688	/// `out_channels` must be null, or a writable pointer to a `usize`.
689	pub fn prism_backend_get_channels(backend: *mut PrismBackend, out_channels: *mut usize) -> PrismError;
690	/// Retrieves the sample rate of audio produced by the backend.
691	///
692	/// # Safety
693	///
694	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
695	/// `out_sample_rate` must be null, or a writable pointer to a `usize`.
696	pub fn prism_backend_get_sample_rate(backend: *mut PrismBackend, out_sample_rate: *mut usize) -> PrismError;
697	/// Retrieves the native bit depth of audio produced by the backend.
698	///
699	/// # Safety
700	///
701	/// `backend` must be a live backend that has not been passed to `prism_backend_free`.
702	/// `out_bit_depth` must be null, or a writable pointer to a `usize`.
703	pub fn prism_backend_get_bit_depth(backend: *mut PrismBackend, out_bit_depth: *mut usize) -> PrismError;
704	/// Returns a human-readable description of an error code.
705	///
706	/// # Safety
707	///
708	/// Safe to call at any time; this is `unsafe` only because it crosses the FFI boundary.
709	pub fn prism_error_string(error: PrismError) -> *const c_char;
710	/// Creates a new registry builder seeded with the compiled-in backends.
711	///
712	/// # Safety
713	///
714	/// Safe to call at any time; this is `unsafe` only because it crosses the FFI boundary.
715	pub fn prism_registry_builder_new() -> *mut PrismRegistryBuilder;
716	/// Adds a custom backend to a registry builder.
717	///
718	/// # Safety
719	///
720	/// `builder` must be a live builder that has not been freed.
721	/// `vtable` must point to an initialized `PrismBackendVTable` whose `size` member is set, valid for the call.
722	/// `name` must be a non-null, NUL-terminated UTF-8 string valid for the call.
723	/// `out_id` must be null, or a writable pointer to a `PrismBackendId`.
724	/// `userdata` is passed through untouched; it must satisfy whatever the paired callback expects and stay alive as long as that callback can run.
725	pub fn prism_registry_builder_add_backend(
726		builder: *mut PrismRegistryBuilder,
727		name: *const c_char,
728		priority: c_int,
729		features: u64,
730		vtable: *const PrismBackendVTable,
731		userdata: *mut c_void,
732		userdata_free: Option<unsafe extern "C" fn(*mut c_void)>,
733		out_id: *mut PrismBackendId,
734	) -> PrismError;
735	/// Loads a plugin from a shared library and adds each backend it supplies to a registry builder.
736	///
737	/// # Safety
738	///
739	/// `builder` must be a live builder that has not been freed.
740	/// `path` must be a non-null, NUL-terminated UTF-8 string valid for the call.
741	/// `out_count` must be null, or a writable pointer to a `usize`.
742	pub fn prism_registry_builder_add_library(
743		builder: *mut PrismRegistryBuilder,
744		path: *const c_char,
745		priority_override: c_int,
746		out_count: *mut usize,
747	) -> PrismError;
748	/// Freezes a builder, producing an immutable registry.
749	///
750	/// # Safety
751	///
752	/// `builder` must be a live builder that has not been freed.
753	pub fn prism_registry_freeze(builder: *mut PrismRegistryBuilder) -> *mut PrismRegistry;
754	/// Releases a registry builder.
755	///
756	/// # Safety
757	///
758	/// `builder` must be a live builder that has not been freed.
759	/// The builder is invalid once this returns.
760	pub fn prism_registry_builder_free(builder: *mut PrismRegistryBuilder);
761	/// Increments the reference count of a registry.
762	///
763	/// # Safety
764	///
765	/// `registry` must be null, or a live registry the caller holds a reference to.
766	pub fn prism_registry_retain(registry: *mut PrismRegistry) -> *mut PrismRegistry;
767	/// Decrements the reference count of a registry, finalizing it when the count reaches zero.
768	///
769	/// # Safety
770	///
771	/// `registry` must be null, or a live registry the caller holds a reference to.
772	/// The caller must not release more references than it holds.
773	pub fn prism_registry_release(registry: *mut PrismRegistry);
774	/// Installs the handler that receives log messages, replacing any previously installed handler.
775	///
776	/// # Safety
777	///
778	/// `handler.fn_`, if set, must be safe to call with `handler.userdata` from prism's logging thread, and that userdata must outlive the handler.
779	pub fn prism_set_log_handler(handler: PrismLogHandler) -> PrismLogHandler;
780	/// Sets the minimum severity of messages that will be delivered.
781	///
782	/// # Safety
783	///
784	/// Safe to call at any time; this is `unsafe` only because it crosses the FFI boundary.
785	pub fn prism_set_log_level(level: PrismLogLevel) -> PrismLogLevel;
786	/// Emits a log message.
787	///
788	/// # Safety
789	///
790	/// `source` must be a non-null, NUL-terminated UTF-8 string valid for the call.
791	/// `message` must be a non-null, NUL-terminated UTF-8 string valid for the call.
792	pub fn prism_log(level: PrismLogLevel, source: *const c_char, message: *const c_char);
793	/// Blocks until all messages queued before the call have been delivered.
794	///
795	/// # Safety
796	///
797	/// Safe to call at any time; this is `unsafe` only because it crosses the FFI boundary.
798	pub fn prism_log_flush();
799	/// Stops the logging thread and releases the resources associated with the logger.
800	///
801	/// # Safety
802	///
803	/// Safe to call at any time; this is `unsafe` only because it crosses the FFI boundary.
804	pub fn prism_log_shutdown();
805	/// Returns the version of the loaded Prism library as an encoded integer.
806	///
807	/// # Safety
808	///
809	/// Safe to call at any time; this is `unsafe` only because it crosses the FFI boundary.
810	pub fn prism_version() -> u32;
811	/// Returns the version of the loaded Prism library as a human-readable string.
812	///
813	/// # Safety
814	///
815	/// Safe to call at any time; this is `unsafe` only because it crosses the FFI boundary.
816	pub fn prism_version_string() -> *const c_char;
817}