#[cfg(unix)]
mod imp;
#[cfg(unix)]
pub use imp::*;
#[cfg(not(unix))]
mod stub {
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::mpsc;
pub mod drm_fourcc {
pub const ARGB8888: u32 = u32::from_le_bytes(*b"AR24");
pub const XRGB8888: u32 = u32::from_le_bytes(*b"XR24");
pub const ABGR8888: u32 = u32::from_le_bytes(*b"AB24");
pub const XBGR8888: u32 = u32::from_le_bytes(*b"XB24");
pub const NV12: u32 = u32::from_le_bytes(*b"NV12");
}
#[derive(Debug)]
pub struct OwnedFd(());
#[derive(Clone)]
pub enum PixelData {
Bgra(Arc<Vec<u8>>),
Rgba(Arc<Vec<u8>>),
Nv12 {
data: Arc<Vec<u8>>,
y_stride: usize,
uv_stride: usize,
},
DmaBuf {
fd: Arc<OwnedFd>,
fourcc: u32,
modifier: u64,
stride: u32,
offset: u32,
},
}
impl PixelData {
pub fn to_rgba(&self, _width: u32, _height: u32) -> Vec<u8> {
match self {
PixelData::Rgba(data) => data.as_ref().clone(),
PixelData::Bgra(data) => {
let mut rgba = Vec::with_capacity(data.len());
for px in data.chunks_exact(4) {
rgba.extend_from_slice(&[px[2], px[1], px[0], px[3]]);
}
rgba
}
PixelData::Nv12 { .. } | PixelData::DmaBuf { .. } => Vec::new(),
}
}
pub fn is_empty(&self) -> bool {
match self {
PixelData::Bgra(v) | PixelData::Rgba(v) => v.is_empty(),
PixelData::Nv12 { data, .. } => data.is_empty(),
PixelData::DmaBuf { .. } => false,
}
}
pub fn is_dmabuf(&self) -> bool {
matches!(self, PixelData::DmaBuf { .. })
}
}
pub enum CompositorEvent {
SurfaceCreated {
surface_id: u16,
title: String,
app_id: String,
parent_id: u16,
width: u16,
height: u16,
},
SurfaceDestroyed {
surface_id: u16,
},
SurfaceCommit {
surface_id: u16,
width: u32,
height: u32,
pixels: PixelData,
},
SurfaceTitle {
surface_id: u16,
title: String,
},
SurfaceAppId {
surface_id: u16,
app_id: String,
},
SurfaceResized {
surface_id: u16,
width: u16,
height: u16,
},
ClipboardContent {
surface_id: u16,
mime_type: String,
data: Vec<u8>,
},
}
pub enum CompositorCommand {
KeyInput {
surface_id: u16,
keycode: u32,
pressed: bool,
},
PointerMotion {
surface_id: u16,
x: f64,
y: f64,
},
PointerButton {
surface_id: u16,
button: u32,
pressed: bool,
},
PointerAxis {
surface_id: u16,
axis: u8,
value: f64,
},
SurfaceResize {
surface_id: u16,
width: u16,
height: u16,
scale_120: u16,
},
SurfaceFocus {
surface_id: u16,
},
SurfaceClose {
surface_id: u16,
},
ClipboardOffer {
surface_id: u16,
mime_type: String,
data: Vec<u8>,
},
ReleaseKeys {
keycodes: Vec<u32>,
},
Capture {
surface_id: u16,
reply: mpsc::SyncSender<Option<(u32, u32, Vec<u8>)>>,
},
RequestFrame {
surface_id: u16,
},
Shutdown,
}
pub struct CompositorHandle {
pub event_rx: mpsc::Receiver<CompositorEvent>,
pub command_tx: mpsc::Sender<CompositorCommand>,
pub socket_name: String,
pub thread: std::thread::JoinHandle<()>,
pub shutdown: Arc<AtomicBool>,
}
impl CompositorHandle {
pub fn wake(&self) {}
}
pub fn spawn_compositor(
_verbose: bool,
_event_notify: Arc<dyn Fn() + Send + Sync>,
) -> CompositorHandle {
unimplemented!("compositor is only supported on Unix")
}
}
#[cfg(not(unix))]
pub use stub::*;