mod frame;
mod screenshot;
mod stream;
mod sys;
pub use frame::ScreenFrame;
pub use screenshot::{ImageFormat, Screenshot, screenshot, screenshot_primary};
pub use stream::{ScreenStream, StreamConfig};
pub use waterkit_core::{Brightness, RefreshRate};
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error("Platform error: {0}")]
Platform(String),
#[error("Unsupported platform or feature")]
Unsupported,
#[error("Monitor not found")]
MonitorNotFound,
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("GPU error: {0}")]
Gpu(String),
#[error("Stream stopped")]
StreamStopped,
#[error("Permission denied")]
PermissionDenied,
#[error("Encoding error: {0}")]
Encoding(String),
}
#[cfg(target_os = "android")]
impl From<jni::errors::Error> for Error {
fn from(error: jni::errors::Error) -> Self {
Self::Platform(error.to_string())
}
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct ScreenInfo {
id: u32,
name: String,
width: u32,
height: u32,
scale_factor: f32,
is_primary: bool,
}
impl ScreenInfo {
#[cfg_attr(
target_arch = "wasm32",
expect(
dead_code,
reason = "the browser screen adapter does not synthesize ScreenInfo"
)
)]
pub(crate) const fn new(
id: u32,
name: String,
width: u32,
height: u32,
scale_factor: f32,
is_primary: bool,
) -> Self {
Self {
id,
name,
width,
height,
scale_factor,
is_primary,
}
}
#[must_use]
pub const fn id(&self) -> u32 {
self.id
}
#[must_use]
pub fn name(&self) -> &str {
&self.name
}
#[must_use]
pub const fn width(&self) -> u32 {
self.width
}
#[must_use]
pub const fn height(&self) -> u32 {
self.height
}
#[must_use]
pub const fn scale_factor(&self) -> f32 {
self.scale_factor
}
#[must_use]
pub const fn is_primary(&self) -> bool {
self.is_primary
}
}
pub fn screens() -> Result<Vec<ScreenInfo>, Error> {
sys::screens()
}
pub fn max_refresh_rate() -> Result<RefreshRate, Error> {
let raw = sys::max_refresh_rate_hz()?;
RefreshRate::new(raw).map_err(|error| Error::Platform(error.to_string()))
}
pub async fn brightness() -> Result<Brightness, Error> {
let raw = sys::get_brightness().await?;
Brightness::new(raw).map_err(|error| Error::Platform(error.to_string()))
}
pub async fn set_brightness(value: Brightness) -> Result<(), Error> {
sys::set_brightness(value.get()).await
}
#[cfg(target_os = "android")]
pub fn init(env: &mut jni::Env<'_>, context: &jni::objects::JObject) -> Result<(), Error> {
sys::android::init(env, context)
}