use std::sync::OnceLock;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct DeviceEntry {
pub id: String,
pub name: String,
pub group: String,
pub width: u32,
pub height: u32,
pub current: bool,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct DeviceState {
pub id: String,
pub name: String,
pub group: String,
pub width: u32,
pub height: u32,
pub landscape: bool,
}
pub trait DeviceController: Send + Sync {
fn list(&self) -> Result<Vec<DeviceEntry>, String>;
fn get(&self) -> Result<DeviceState, String>;
fn set(&self, id: &str, landscape: Option<bool>) -> Result<DeviceState, String>;
}
static DEVICE_CONTROLLER: OnceLock<Box<dyn DeviceController>> = OnceLock::new();
pub fn register_device_controller(controller: Box<dyn DeviceController>) {
if DEVICE_CONTROLLER.set(controller).is_err() {
crate::warn!("device controller already registered; ignoring");
}
}
fn device_controller() -> Result<&'static dyn DeviceController, String> {
DEVICE_CONTROLLER
.get()
.map(|c| c.as_ref())
.ok_or_else(|| "device switching is not supported by this host".to_string())
}
pub fn device_list() -> Result<Vec<DeviceEntry>, String> {
device_controller()?.list()
}
pub fn device_get() -> Result<DeviceState, String> {
device_controller()?.get()
}
pub fn device_set(id: &str, landscape: Option<bool>) -> Result<DeviceState, String> {
device_controller()?.set(id, landscape)
}