1use super::*;
2use crate::animation::Animation;
3use std::sync::mpsc::{self, Receiver, SendError, Sender};
4
5pub type Result<T> = std::result::Result<T, Box<dyn Error>>;
6
7pub type RenderSender = calloop_channel::Sender<RenderCommand>;
8pub type RenderReceiver = calloop_channel::Channel<RenderCommand>;
9pub type RenderSendError = SendError<RenderCommand>;
10
11pub fn channel() -> (RenderSender, RenderReceiver) {
12 calloop_channel::channel()
13}
14
15pub fn controller() -> (RenderController, RenderReceiver) {
16 let (sender, receiver) = channel();
17 (RenderController::new(sender), receiver)
18}
19
20#[derive(Clone)]
21pub struct RenderController {
22 sender: RenderSender,
23}
24
25impl RenderController {
26 pub fn new(sender: RenderSender) -> Self {
27 Self { sender }
28 }
29
30 pub fn sender(&self) -> &RenderSender {
31 &self.sender
32 }
33
34 pub fn into_sender(self) -> RenderSender {
35 self.sender
36 }
37
38 pub fn send(&self, command: RenderCommand) -> std::result::Result<(), RenderSendError> {
39 self.sender.send(command)
40 }
41
42 pub fn redraw(&self) -> std::result::Result<(), RenderSendError> {
43 self.send(RenderCommand::Redraw)
44 }
45
46 pub fn resize(&self, width: u32, height: u32) -> std::result::Result<(), RenderSendError> {
47 self.send(RenderCommand::Resize { width, height })
48 }
49
50 pub fn set_margins(&self, margins: Margins) -> std::result::Result<(), RenderSendError> {
51 self.send(RenderCommand::SetMargins(margins))
52 }
53
54 pub fn set_anchor(&self, anchor: Anchor) -> std::result::Result<(), RenderSendError> {
55 self.send(RenderCommand::SetAnchor(anchor))
56 }
57
58 pub fn create_surface(
59 &self,
60 id: SurfaceId,
61 options: LayerOptions,
62 ) -> std::result::Result<(), RenderSendError> {
63 self.send(RenderCommand::CreateSurface { id, options })
64 }
65
66 pub fn destroy_surface(&self, id: SurfaceId) -> std::result::Result<(), RenderSendError> {
67 self.send(RenderCommand::DestroySurface { id })
68 }
69
70 pub fn redraw_surface(&self, id: SurfaceId) -> std::result::Result<(), RenderSendError> {
71 self.send(RenderCommand::RedrawSurface { id })
72 }
73
74 pub fn resize_surface(
75 &self,
76 id: SurfaceId,
77 width: u32,
78 height: u32,
79 ) -> std::result::Result<(), RenderSendError> {
80 self.send(RenderCommand::ResizeSurface { id, width, height })
81 }
82
83 pub fn set_surface_margins(
84 &self,
85 id: SurfaceId,
86 margins: Margins,
87 ) -> std::result::Result<(), RenderSendError> {
88 self.send(RenderCommand::SetSurfaceMargins { id, margins })
89 }
90
91 pub fn set_surface_anchor(
92 &self,
93 id: SurfaceId,
94 anchor: Anchor,
95 ) -> std::result::Result<(), RenderSendError> {
96 self.send(RenderCommand::SetSurfaceAnchor { id, anchor })
97 }
98
99 pub fn set_surface_layer(
100 &self,
101 id: SurfaceId,
102 layer: Layer,
103 ) -> std::result::Result<(), RenderSendError> {
104 self.send(RenderCommand::SetSurfaceLayer { id, layer })
105 }
106
107 pub fn animate_surface_margins(
108 &self,
109 id: SurfaceId,
110 to: Margins,
111 animation: Animation,
112 destroy_on_complete: bool,
113 ) -> std::result::Result<(), RenderSendError> {
114 self.send(RenderCommand::AnimateSurfaceMargins {
115 id,
116 to,
117 animation,
118 destroy_on_complete,
119 })
120 }
121
122 pub fn animate_surface_size(
123 &self,
124 id: SurfaceId,
125 width: u32,
126 height: u32,
127 animation: Animation,
128 destroy_on_complete: bool,
129 ) -> std::result::Result<(), RenderSendError> {
130 self.send(RenderCommand::AnimateSurfaceSize {
131 id,
132 width,
133 height,
134 animation,
135 destroy_on_complete,
136 })
137 }
138
139 pub fn cancel_surface_animation(
140 &self,
141 id: SurfaceId,
142 ) -> std::result::Result<(), RenderSendError> {
143 self.send(RenderCommand::CancelSurfaceAnimation { id })
144 }
145
146 pub fn request_outputs(
147 &self,
148 ) -> std::result::Result<Receiver<Vec<RenderOutput>>, RenderSendError> {
149 let (reply, receiver) = mpsc::channel();
150 self.send(RenderCommand::RequestOutputs { reply })?;
151 Ok(receiver)
152 }
153
154 pub fn request_surface_state(
155 &self,
156 id: SurfaceId,
157 ) -> std::result::Result<Receiver<Option<RenderSurfaceState>>, RenderSendError> {
158 let (reply, receiver) = mpsc::channel();
159 self.send(RenderCommand::RequestSurfaceState { id, reply })?;
160 Ok(receiver)
161 }
162
163 pub fn exit(&self) -> std::result::Result<(), RenderSendError> {
164 self.send(RenderCommand::Exit)
165 }
166}
167
168#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
169pub struct SurfaceId(pub u64);
170
171pub const DEFAULT_SURFACE_ID: SurfaceId = SurfaceId(0);
172
173#[derive(Debug, Clone, PartialEq, Eq)]
174pub struct RenderOutput {
175 pub id: u32,
176 pub name: Option<String>,
177 pub description: Option<String>,
178 pub make: String,
179 pub model: String,
180 pub logical_position: Option<(i32, i32)>,
181 pub logical_size: Option<(i32, i32)>,
182 pub scale_factor: i32,
183}
184
185#[derive(Debug, Clone, PartialEq, Eq)]
186pub struct RenderSurfaceState {
187 pub id: SurfaceId,
188 pub configured: bool,
189 pub width: u32,
190 pub height: u32,
191 pub output: Option<OutputTarget>,
192 pub layer: Layer,
193 pub anchor: Anchor,
194 pub margins: Margins,
195 pub scale: u32,
196 pub animating: bool,
197 pub frame_pending: bool,
198}
199
200#[derive(Debug, Clone)]
201pub enum RenderCommand {
202 Redraw,
203 Resize {
204 width: u32,
205 height: u32,
206 },
207 SetMargins(Margins),
208 SetAnchor(Anchor),
209 CreateSurface {
210 id: SurfaceId,
211 options: LayerOptions,
212 },
213 DestroySurface {
214 id: SurfaceId,
215 },
216 RedrawSurface {
217 id: SurfaceId,
218 },
219 ResizeSurface {
220 id: SurfaceId,
221 width: u32,
222 height: u32,
223 },
224 SetSurfaceMargins {
225 id: SurfaceId,
226 margins: Margins,
227 },
228 SetSurfaceAnchor {
229 id: SurfaceId,
230 anchor: Anchor,
231 },
232 SetSurfaceLayer {
233 id: SurfaceId,
234 layer: Layer,
235 },
236 AnimateSurfaceMargins {
237 id: SurfaceId,
238 to: Margins,
239 animation: Animation,
240 destroy_on_complete: bool,
241 },
242 AnimateSurfaceSize {
243 id: SurfaceId,
244 width: u32,
245 height: u32,
246 animation: Animation,
247 destroy_on_complete: bool,
248 },
249 CancelSurfaceAnimation {
250 id: SurfaceId,
251 },
252 RequestOutputs {
253 reply: Sender<Vec<RenderOutput>>,
254 },
255 RequestSurfaceState {
256 id: SurfaceId,
257 reply: Sender<Option<RenderSurfaceState>>,
258 },
259 Exit,
260}
261
262#[derive(Debug, Clone, Copy, PartialEq, Eq)]
263pub enum InputAction {
264 Ignore,
265 Redraw,
266 Animate,
267 Exit,
268}
269
270#[derive(Debug, Clone, Copy, PartialEq, Eq)]
271pub enum PointerButtonState {
272 Pressed,
273 Released,
274}
275
276#[derive(Debug, Clone, Copy, PartialEq)]
277pub enum PointerEventKind {
278 Enter,
279 Leave,
280 Motion,
281 Button {
282 button: u32,
283 state: PointerButtonState,
284 },
285 Axis {
286 horizontal: PointerAxis,
287 vertical: PointerAxis,
288 source: Option<PointerAxisSource>,
289 },
290}
291
292#[derive(Debug, Clone, Copy, PartialEq)]
293pub struct PointerAxis {
294 pub absolute: f64,
295 pub discrete: i32,
296 pub stopped: bool,
297}
298
299#[derive(Debug, Clone, Copy, PartialEq, Eq)]
300pub enum PointerAxisSource {
301 Wheel,
302 Finger,
303 Continuous,
304 WheelTilt,
305 Unknown,
306}
307
308#[derive(Debug, Clone, Copy, PartialEq)]
309pub struct PointerEvent {
310 pub surface: SurfaceId,
311 pub x: f64,
312 pub y: f64,
313 pub time: Option<u32>,
314 pub serial: Option<u32>,
315 pub kind: PointerEventKind,
316}
317
318#[derive(Debug, Clone, Copy, PartialEq, Eq)]
319pub enum FrameAction {
320 Wait,
321 Animate,
322 Exit,
323}
324
325#[derive(Debug, Clone, Copy, PartialEq, Eq)]
326pub struct RenderContext {
327 pub width: u32,
329 pub height: u32,
331 pub scale: u32,
333 pub buffer_width: u32,
335 pub buffer_height: u32,
337 pub frame_time: Option<u32>,
338}
339
340pub trait Renderer: 'static {
341 fn draw(&mut self, canvas: &mut Canvas<'_>, context: RenderContext) -> FrameAction;
342
343 fn draw_surface(
344 &mut self,
345 _: SurfaceId,
346 canvas: &mut Canvas<'_>,
347 context: RenderContext,
348 ) -> FrameAction {
349 self.draw(canvas, context)
350 }
351
352 fn closed(&mut self) {}
353
354 fn closed_surface(&mut self, _: SurfaceId) {
355 self.closed();
356 }
357
358 fn configured_surface(&mut self, _: SurfaceId, _: u32, _: u32) {}
359
360 fn output_added(&mut self, _: RenderOutput) {}
361
362 fn output_updated(&mut self, _: RenderOutput) {}
363
364 fn output_removed(&mut self, _: RenderOutput) {}
365
366 fn pointer_event(&mut self, _: PointerEvent) -> InputAction {
367 InputAction::Ignore
368 }
369}
370
371impl<F> Renderer for F
372where
373 F: for<'borrow, 'canvas> FnMut(&'borrow mut Canvas<'canvas>, RenderContext) -> FrameAction
374 + 'static,
375{
376 fn draw(&mut self, canvas: &mut Canvas<'_>, context: RenderContext) -> FrameAction {
377 self(canvas, context)
378 }
379}