1mod positioner;
2
3#[cfg(target_os = "linux")]
4mod imp;
5#[cfg(target_os = "linux")]
6mod render;
7#[cfg(target_os = "linux")]
8mod vulkan_render;
9#[cfg(target_os = "linux")]
10pub use imp::*;
11
12#[cfg(not(target_os = "linux"))]
13mod stub {
14 use std::sync::Arc;
15 use std::sync::atomic::AtomicBool;
16 use std::sync::mpsc;
17
18 pub mod drm_fourcc {
19 pub const ARGB8888: u32 = u32::from_le_bytes(*b"AR24");
20 pub const XRGB8888: u32 = u32::from_le_bytes(*b"XR24");
21 pub const ABGR8888: u32 = u32::from_le_bytes(*b"AB24");
22 pub const XBGR8888: u32 = u32::from_le_bytes(*b"XB24");
23 pub const NV12: u32 = u32::from_le_bytes(*b"NV12");
24 }
25
26 #[derive(Debug)]
28 pub struct OwnedFd(());
29
30 #[derive(Clone)]
31 pub enum PixelData {
32 Bgra(Arc<Vec<u8>>),
33 Rgba(Arc<Vec<u8>>),
34 Nv12 {
35 data: Arc<Vec<u8>>,
36 y_stride: usize,
37 uv_stride: usize,
38 },
39 DmaBuf {
40 fd: Arc<OwnedFd>,
41 fourcc: u32,
42 modifier: u64,
43 stride: u32,
44 offset: u32,
45 },
46 VaSurface {
47 surface_id: u32,
48 va_display: usize,
49 _fd: Arc<OwnedFd>,
50 },
51 }
52
53 #[derive(Clone)]
54 pub struct PixelLayer {
55 pub x: i32,
56 pub y: i32,
57 pub width: u32,
58 pub height: u32,
59 pub pixels: PixelData,
60 }
61
62 impl PixelData {
63 pub fn to_rgba(&self, _width: u32, _height: u32) -> Vec<u8> {
64 match self {
65 PixelData::Rgba(data) => data.as_ref().clone(),
66 PixelData::Bgra(data) => {
67 let mut rgba = Vec::with_capacity(data.len());
68 for px in data.chunks_exact(4) {
69 rgba.extend_from_slice(&[px[2], px[1], px[0], px[3]]);
70 }
71 rgba
72 }
73 _ => Vec::new(),
74 }
75 }
76
77 pub fn is_empty(&self) -> bool {
78 match self {
79 PixelData::Bgra(v) | PixelData::Rgba(v) => v.is_empty(),
80 PixelData::Nv12 { data, .. } => data.is_empty(),
81 PixelData::DmaBuf { .. } | PixelData::VaSurface { .. } => false,
82 }
83 }
84
85 pub fn is_dmabuf(&self) -> bool {
86 matches!(self, PixelData::DmaBuf { .. })
87 }
88
89 pub fn is_va_surface(&self) -> bool {
90 matches!(self, PixelData::VaSurface { .. })
91 }
92 }
93
94 #[derive(Clone)]
95 pub enum CursorImage {
96 Named(String),
97 Custom {
98 hotspot_x: u16,
99 hotspot_y: u16,
100 width: u16,
101 height: u16,
102 rgba: Vec<u8>,
103 },
104 Hidden,
105 }
106
107 pub enum CompositorEvent {
108 SurfaceCreated {
109 surface_id: u16,
110 title: String,
111 app_id: String,
112 parent_id: u16,
113 width: u16,
114 height: u16,
115 },
116 SurfaceDestroyed {
117 surface_id: u16,
118 },
119 SurfaceCommit {
120 surface_id: u16,
121 width: u32,
122 height: u32,
123 pixels: PixelData,
124 },
125 SurfaceTitle {
126 surface_id: u16,
127 title: String,
128 },
129 SurfaceAppId {
130 surface_id: u16,
131 app_id: String,
132 },
133 SurfaceResized {
134 surface_id: u16,
135 width: u16,
136 height: u16,
137 },
138 ClipboardContent {
139 surface_id: u16,
140 mime_type: String,
141 data: Vec<u8>,
142 },
143 SurfaceCursor {
144 surface_id: u16,
145 cursor: CursorImage,
146 },
147 }
148
149 pub enum CompositorCommand {
150 KeyInput {
151 surface_id: u16,
152 keycode: u32,
153 pressed: bool,
154 },
155 PointerMotion {
156 surface_id: u16,
157 x: f64,
158 y: f64,
159 },
160 PointerButton {
161 surface_id: u16,
162 button: u32,
163 pressed: bool,
164 },
165 PointerAxis {
166 surface_id: u16,
167 axis: u8,
168 value: f64,
169 },
170 SurfaceResize {
171 surface_id: u16,
172 width: u16,
173 height: u16,
174 scale_120: u16,
175 },
176 SurfaceFocus {
177 surface_id: u16,
178 },
179 SurfaceClose {
180 surface_id: u16,
181 },
182 ClipboardOffer {
183 mime_type: String,
184 data: Vec<u8>,
185 },
186 ClipboardListMimes {
188 reply: mpsc::SyncSender<Vec<String>>,
189 },
190 ClipboardGet {
192 mime_type: String,
193 reply: mpsc::SyncSender<Option<Vec<u8>>>,
194 },
195 TextInput {
200 text: String,
201 },
202 ReleaseKeys {
203 keycodes: Vec<u32>,
204 },
205 Capture {
206 surface_id: u16,
207 scale_120: u16,
209 reply: mpsc::SyncSender<Option<(u32, u32, Vec<u8>)>>,
210 },
211 RequestFrame {
215 surface_id: u16,
216 },
217 SetExternalOutputBuffers {
218 buffers: Vec<ExternalOutputBuffer>,
219 },
220 Shutdown,
221 }
222
223 pub struct ExternalOutputBuffer {
224 pub fd: Arc<OwnedFd>,
225 pub fourcc: u32,
226 pub modifier: u64,
227 pub stride: u32,
228 pub offset: u32,
229 pub width: u32,
230 pub height: u32,
231 pub va_surface_id: u32,
232 pub va_display: usize,
233 }
234
235 pub struct CompositorHandle {
236 pub event_rx: mpsc::Receiver<CompositorEvent>,
237 pub command_tx: mpsc::Sender<CompositorCommand>,
238 pub socket_name: String,
239 pub thread: std::thread::JoinHandle<()>,
240 pub shutdown: Arc<AtomicBool>,
241 }
242
243 impl CompositorHandle {
244 pub fn wake(&self) {}
246 }
247
248 pub fn spawn_compositor(
249 _verbose: bool,
250 _event_notify: Arc<dyn Fn() + Send + Sync>,
251 _gpu_device: &str,
252 ) -> CompositorHandle {
253 let (event_tx, event_rx) = mpsc::channel();
254 let (command_tx, _command_rx) = mpsc::channel();
255 let shutdown = Arc::new(AtomicBool::new(false));
256 drop(event_tx);
258 CompositorHandle {
259 event_rx,
260 command_tx,
261 socket_name: String::new(),
262 thread: std::thread::spawn(|| {}),
263 shutdown,
264 }
265 }
266}
267
268#[cfg(not(target_os = "linux"))]
269pub use stub::*;