Skip to main content

blit_compositor/
lib.rs

1#[cfg(unix)]
2mod imp;
3#[cfg(unix)]
4pub use imp::*;
5
6#[cfg(not(unix))]
7mod stub {
8    use std::sync::Arc;
9    use std::sync::atomic::AtomicBool;
10    use std::sync::mpsc;
11
12    pub mod drm_fourcc {
13        pub const ARGB8888: u32 = u32::from_le_bytes(*b"AR24");
14        pub const XRGB8888: u32 = u32::from_le_bytes(*b"XR24");
15        pub const ABGR8888: u32 = u32::from_le_bytes(*b"AB24");
16        pub const XBGR8888: u32 = u32::from_le_bytes(*b"XB24");
17        pub const NV12: u32 = u32::from_le_bytes(*b"NV12");
18    }
19
20    /// Placeholder for `std::os::fd::OwnedFd` on non-Unix platforms.
21    #[derive(Debug)]
22    pub struct OwnedFd(());
23
24    #[derive(Clone)]
25    pub enum PixelData {
26        Bgra(Arc<Vec<u8>>),
27        Rgba(Arc<Vec<u8>>),
28        Nv12 {
29            data: Arc<Vec<u8>>,
30            y_stride: usize,
31            uv_stride: usize,
32        },
33        DmaBuf {
34            fd: Arc<OwnedFd>,
35            fourcc: u32,
36            modifier: u64,
37            stride: u32,
38            offset: u32,
39        },
40    }
41
42    impl PixelData {
43        pub fn to_rgba(&self, _width: u32, _height: u32) -> Vec<u8> {
44            match self {
45                PixelData::Rgba(data) => data.as_ref().clone(),
46                PixelData::Bgra(data) => {
47                    let mut rgba = Vec::with_capacity(data.len());
48                    for px in data.chunks_exact(4) {
49                        rgba.extend_from_slice(&[px[2], px[1], px[0], px[3]]);
50                    }
51                    rgba
52                }
53                PixelData::Nv12 { .. } | PixelData::DmaBuf { .. } => Vec::new(),
54            }
55        }
56
57        pub fn is_empty(&self) -> bool {
58            match self {
59                PixelData::Bgra(v) | PixelData::Rgba(v) => v.is_empty(),
60                PixelData::Nv12 { data, .. } => data.is_empty(),
61                PixelData::DmaBuf { .. } => false,
62            }
63        }
64
65        pub fn is_dmabuf(&self) -> bool {
66            matches!(self, PixelData::DmaBuf { .. })
67        }
68    }
69
70    pub enum CompositorEvent {
71        SurfaceCreated {
72            surface_id: u16,
73            title: String,
74            app_id: String,
75            parent_id: u16,
76            width: u16,
77            height: u16,
78        },
79        SurfaceDestroyed {
80            surface_id: u16,
81        },
82        SurfaceCommit {
83            surface_id: u16,
84            width: u32,
85            height: u32,
86            pixels: PixelData,
87        },
88        SurfaceTitle {
89            surface_id: u16,
90            title: String,
91        },
92        SurfaceAppId {
93            surface_id: u16,
94            app_id: String,
95        },
96        SurfaceResized {
97            surface_id: u16,
98            width: u16,
99            height: u16,
100        },
101        ClipboardContent {
102            surface_id: u16,
103            mime_type: String,
104            data: Vec<u8>,
105        },
106    }
107
108    pub enum CompositorCommand {
109        KeyInput {
110            surface_id: u16,
111            keycode: u32,
112            pressed: bool,
113        },
114        PointerMotion {
115            surface_id: u16,
116            x: f64,
117            y: f64,
118        },
119        PointerButton {
120            surface_id: u16,
121            button: u32,
122            pressed: bool,
123        },
124        PointerAxis {
125            surface_id: u16,
126            axis: u8,
127            value: f64,
128        },
129        SurfaceResize {
130            surface_id: u16,
131            width: u16,
132            height: u16,
133            scale_120: u16,
134        },
135        SurfaceFocus {
136            surface_id: u16,
137        },
138        SurfaceClose {
139            surface_id: u16,
140        },
141        ClipboardOffer {
142            surface_id: u16,
143            mime_type: String,
144            data: Vec<u8>,
145        },
146        ReleaseKeys {
147            keycodes: Vec<u32>,
148        },
149        Capture {
150            surface_id: u16,
151            reply: mpsc::SyncSender<Option<(u32, u32, Vec<u8>)>>,
152        },
153        /// Fire pending wl_surface.frame callbacks for a surface so the
154        /// client will paint and commit its next frame.  Send this when
155        /// the server is ready to consume a new frame (streaming or capture).
156        RequestFrame {
157            surface_id: u16,
158        },
159        Shutdown,
160    }
161
162    pub struct CompositorHandle {
163        pub event_rx: mpsc::Receiver<CompositorEvent>,
164        pub command_tx: mpsc::Sender<CompositorCommand>,
165        pub socket_name: String,
166        pub thread: std::thread::JoinHandle<()>,
167        pub shutdown: Arc<AtomicBool>,
168    }
169
170    impl CompositorHandle {
171        /// Wake the compositor event loop immediately.
172        pub fn wake(&self) {}
173    }
174
175    pub fn spawn_compositor(
176        _verbose: bool,
177        _event_notify: Arc<dyn Fn() + Send + Sync>,
178    ) -> CompositorHandle {
179        unimplemented!("compositor is only supported on Unix")
180    }
181}
182
183#[cfg(not(unix))]
184pub use stub::*;