1 | use crate::reexports::client::globals::{BindError, GlobalList}; |
2 | use crate::reexports::client::protocol::wl_compositor::WlCompositor; |
3 | use crate::reexports::client::protocol::wl_subcompositor::WlSubcompositor; |
4 | use crate::reexports::client::protocol::wl_subsurface::WlSubsurface; |
5 | use crate::reexports::client::protocol::wl_surface::WlSurface; |
6 | use crate::reexports::client::{Connection, Dispatch, Proxy, QueueHandle}; |
7 | |
8 | use crate::compositor::SurfaceData; |
9 | use crate::globals::GlobalData; |
10 | |
11 | #[derive (Debug)] |
12 | pub struct SubcompositorState { |
13 | compositor: WlCompositor, |
14 | subcompositor: WlSubcompositor, |
15 | } |
16 | |
17 | impl SubcompositorState { |
18 | pub fn bind<State>( |
19 | compositor: WlCompositor, |
20 | globals: &GlobalList, |
21 | queue_handle: &QueueHandle<State>, |
22 | ) -> Result<Self, BindError> |
23 | where |
24 | State: Dispatch<WlSubcompositor, GlobalData, State> + 'static, |
25 | { |
26 | let subcompositor = globals.bind(queue_handle, 1..=1, GlobalData)?; |
27 | Ok(SubcompositorState { compositor, subcompositor }) |
28 | } |
29 | |
30 | pub fn create_subsurface<State>( |
31 | &self, |
32 | parent: WlSurface, |
33 | queue_handle: &QueueHandle<State>, |
34 | ) -> (WlSubsurface, WlSurface) |
35 | where |
36 | State: Dispatch<WlSurface, SurfaceData> + Dispatch<WlSubsurface, SubsurfaceData> + 'static, |
37 | { |
38 | let surface_data = SurfaceData::new(Some(parent.clone()), 1); |
39 | let surface = self.compositor.create_surface(queue_handle, surface_data); |
40 | let subsurface_data = SubsurfaceData::new(surface.clone()); |
41 | let subsurface = |
42 | self.subcompositor.get_subsurface(&surface, &parent, queue_handle, subsurface_data); |
43 | (subsurface, surface) |
44 | } |
45 | |
46 | pub fn subsurface_from_surface<State>( |
47 | &self, |
48 | surface: &WlSurface, |
49 | queue_handle: &QueueHandle<State>, |
50 | ) -> Option<WlSubsurface> |
51 | where |
52 | State: Dispatch<WlSurface, SurfaceData> + Dispatch<WlSubsurface, SubsurfaceData> + 'static, |
53 | { |
54 | let parent = surface.data::<SurfaceData>().unwrap().parent_surface(); |
55 | let subsurface_data = SubsurfaceData::new(surface.clone()); |
56 | parent.map(|parent| { |
57 | self.subcompositor.get_subsurface(surface, parent, queue_handle, subsurface_data) |
58 | }) |
59 | } |
60 | } |
61 | |
62 | impl<D> Dispatch<WlSubsurface, SubsurfaceData, D> for SubcompositorState |
63 | where |
64 | D: Dispatch<WlSubsurface, SubsurfaceData>, |
65 | { |
66 | fn event( |
67 | _: &mut D, |
68 | _: &WlSubsurface, |
69 | _: <WlSubsurface as Proxy>::Event, |
70 | _: &SubsurfaceData, |
71 | _: &Connection, |
72 | _: &QueueHandle<D>, |
73 | ) { |
74 | unreachable!("wl_subsurface has no events" ) |
75 | } |
76 | } |
77 | |
78 | impl<D> Dispatch<WlSubcompositor, GlobalData, D> for SubcompositorState |
79 | where |
80 | D: Dispatch<WlSubcompositor, GlobalData>, |
81 | { |
82 | fn event( |
83 | _: &mut D, |
84 | _: &WlSubcompositor, |
85 | _: <WlSubcompositor as Proxy>::Event, |
86 | _: &GlobalData, |
87 | _: &Connection, |
88 | _: &QueueHandle<D>, |
89 | ) { |
90 | unreachable!("wl_subcompositor has no events" ) |
91 | } |
92 | } |
93 | |
94 | /// The data assoctiated with the subsurface. |
95 | #[derive (Debug)] |
96 | pub struct SubsurfaceData { |
97 | /// The surface used when creating this subsurface. |
98 | surface: WlSurface, |
99 | } |
100 | |
101 | impl SubsurfaceData { |
102 | pub(crate) fn new(surface: WlSurface) -> Self { |
103 | Self { surface } |
104 | } |
105 | |
106 | /// Get the surface used when creating the given subsurface. |
107 | pub fn surface(&self) -> &WlSurface { |
108 | &self.surface |
109 | } |
110 | } |
111 | |
112 | #[macro_export ] |
113 | macro_rules! delegate_subcompositor { |
114 | ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { |
115 | $crate::delegate_subcompositor!(@{ $(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty }; subsurface: []); |
116 | $crate::delegate_subcompositor!(@{ $(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty }; subsurface-only: $crate::subcompositor::SubsurfaceData); |
117 | }; |
118 | ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty, subsurface: [$($subsurface: ty),*$(,)?]) => { |
119 | $crate::delegate_subcompositor!(@{ $(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty }; subsurface: [ $($subsurface),* ]); |
120 | }; |
121 | (@{$($ty:tt)*}; subsurface: []) => { |
122 | $crate::reexports::client::delegate_dispatch!($($ty)*: |
123 | [ |
124 | $crate::reexports::client::protocol::wl_subcompositor::WlSubcompositor: $crate::globals::GlobalData |
125 | ] => $crate::subcompositor::SubcompositorState |
126 | ); |
127 | }; |
128 | (@{$($ty:tt)*}; subsurface-only: $subsurface:ty) => { |
129 | $crate::reexports::client::delegate_dispatch!($($ty)*: |
130 | [ |
131 | $crate::reexports::client::protocol::wl_subsurface::WlSubsurface: $subsurface |
132 | ] => $crate::subcompositor::SubcompositorState |
133 | ); |
134 | }; |
135 | (@$ty:tt; subsurface: [ $($subsurface:ty),+ ]) => { |
136 | $crate::delegate_subcompositor!(@$ty; subsurface: []); |
137 | $( $crate::delegate_subcompositor!(@$ty; subsurface-only: $subsurface); )* |
138 | }; |
139 | } |
140 | |