Skip to main content

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    #[allow(dead_code)]
64    pub fn set_source(&self, x: f64, y: f64, width: f64, height: f64) {
65        self.viewport.set_source(x, y, width, height);
66    }
67
68    #[allow(dead_code)]
69    pub fn set_destination(&self, width: i32, height: i32) {
70        self.viewport.set_destination(width, height);
71    }
72}
73
74impl Drop for Viewport {
75    fn drop(&mut self) {
76        self.viewport.destroy();
77    }
78}
79
80impl<D> Dispatch<WpViewporter, GlobalData, D> for ViewporterState
81where
82    D: Dispatch<WpViewporter, GlobalData> + 'static,
83{
84    fn event(
85        _: &mut D,
86        _: &WpViewporter,
87        _: <WpViewporter as Proxy>::Event,
88        _: &GlobalData,
89        _: &Connection,
90        _: &QueueHandle<D>,
91    ) {
92        unreachable!("WpViewporter has no events")
93    }
94}
95
96impl<D> Dispatch<WpViewport, GlobalData, D> for ViewporterState
97where
98    D: Dispatch<WpViewport, GlobalData> + 'static,
99{
100    fn event(
101        _: &mut D,
102        _: &WpViewport,
103        _: <WpViewport as Proxy>::Event,
104        _: &GlobalData,
105        _: &Connection,
106        _: &QueueHandle<D>,
107    ) {
108        unreachable!("WpViewport has no events")
109    }
110}
111
112#[macro_export]
113macro_rules! delegate_viewporter {
114    ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
115        smithay_client_toolkit::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
116            smithay_client_toolkit::reexports::protocols::wp::viewporter::client::wp_viewport::WpViewport: smithay_client_toolkit::globals::GlobalData
117        ] => $crate::wayland_adapter::viewporter::ViewporterState);
118        smithay_client_toolkit::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
119            smithay_client_toolkit::reexports::protocols::wp::viewporter::client::wp_viewporter::WpViewporter: smithay_client_toolkit::globals::GlobalData
120        ] => $crate::wayland_adapter::viewporter::ViewporterState);
121    };
122}