Skip to main content

simple_render/wayland/
api.rs

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    /// Surface width in logical pixels.
328    pub width: u32,
329    /// Surface height in logical pixels.
330    pub height: u32,
331    /// Integer Wayland buffer scale used for the current frame.
332    pub scale: u32,
333    /// Backing buffer width in physical pixels.
334    pub buffer_width: u32,
335    /// Backing buffer height in physical pixels.
336    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}