spell_framework/wayland_adapter/
viewporter.rs

1// Courtesy DrepDays
2// Implementaion is taken and modified from here.
3// https://github.com/DerpDays/draw/blob/main/platform%2Fwayland%2Fsrc%2Fviewporter.rs
4use crate::wayland_adapter::fractional_scaling::FractionalScale;
5use smithay_client_toolkit::{
6    globals::GlobalData,
7    reexports::{
8        client::{
9            Connection, Dispatch, Proxy, QueueHandle,
10            globals::{BindError, GlobalList},
11            protocol::wl_surface::WlSurface,
12        },
13        protocols::wp::viewporter::client::{wp_viewport::WpViewport, wp_viewporter::WpViewporter},
14    },
15};
16
17#[derive(Debug)]
18pub struct ViewporterState {
19    viewporter: WpViewporter,
20}
21
22/// An owned instance of WpViewport, when this is dropped, the underlying interface is
23/// destroyed.
24#[derive(Debug)]
25pub struct Viewport {
26    viewport: WpViewport,
27    // This is not required but yet stored so that it doesn't get distroyed.
28    #[allow(dead_code)]
29    fractional_scale: FractionalScale,
30}
31
32impl ViewporterState {
33    pub fn bind<State>(
34        globals: &GlobalList,
35        queue_handle: &QueueHandle<State>,
36    ) -> Result<Self, BindError>
37    where
38        State: Dispatch<WpViewporter, GlobalData, State> + 'static,
39    {
40        let viewporter = globals.bind(queue_handle, 1..=1, GlobalData)?;
41        Ok(ViewporterState { viewporter })
42    }
43
44    pub fn get_viewport<State>(
45        &self,
46        surface: &WlSurface,
47        queue_handle: &QueueHandle<State>,
48        fractional_scale: FractionalScale,
49    ) -> Viewport
50    where
51        State: Dispatch<WpViewport, GlobalData> + 'static,
52    {
53        Viewport {
54            viewport: self
55                .viewporter
56                .get_viewport(surface, queue_handle, GlobalData),
57            fractional_scale,
58        }
59    }
60}
61
62impl Viewport {
63    pub fn set_source(&self, x: f64, y: f64, width: f64, height: f64) {
64        self.viewport.set_source(x, y, width, height);
65    }
66    pub fn set_destination(&self, width: i32, height: i32) {
67        self.viewport.set_destination(width, height);
68    }
69}
70
71impl Drop for Viewport {
72    fn drop(&mut self) {
73        self.viewport.destroy();
74    }
75}
76
77impl<D> Dispatch<WpViewporter, GlobalData, D> for ViewporterState
78where
79    D: Dispatch<WpViewporter, GlobalData> + 'static,
80{
81    fn event(
82        _: &mut D,
83        _: &WpViewporter,
84        _: <WpViewporter as Proxy>::Event,
85        _: &GlobalData,
86        _: &Connection,
87        _: &QueueHandle<D>,
88    ) {
89        unreachable!("WpViewporter has no events")
90    }
91}
92
93impl<D> Dispatch<WpViewport, GlobalData, D> for ViewporterState
94where
95    D: Dispatch<WpViewport, GlobalData> + 'static,
96{
97    fn event(
98        _: &mut D,
99        _: &WpViewport,
100        _: <WpViewport as Proxy>::Event,
101        _: &GlobalData,
102        _: &Connection,
103        _: &QueueHandle<D>,
104    ) {
105        unreachable!("WpViewport has no events")
106    }
107}
108
109#[macro_export]
110macro_rules! delegate_viewporter {
111    ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
112        smithay_client_toolkit::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
113            smithay_client_toolkit::reexports::protocols::wp::viewporter::client::wp_viewport::WpViewport: smithay_client_toolkit::globals::GlobalData
114        ] => $crate::wayland_adapter::viewporter::ViewporterState);
115        smithay_client_toolkit::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
116            smithay_client_toolkit::reexports::protocols::wp::viewporter::client::wp_viewporter::WpViewporter: smithay_client_toolkit::globals::GlobalData
117        ] => $crate::wayland_adapter::viewporter::ViewporterState);
118    };
119}