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 | |
47 | impl<D> Dispatch<WlSubsurface, SubsurfaceData, D> for SubcompositorState |
48 | where |
49 | D: Dispatch<WlSubsurface, SubsurfaceData>, |
50 | { |
51 | fn event( |
52 | _: &mut D, |
53 | _: &WlSubsurface, |
54 | _: <WlSubsurface as Proxy>::Event, |
55 | _: &SubsurfaceData, |
56 | _: &Connection, |
57 | _: &QueueHandle<D>, |
58 | ) { |
59 | unreachable!("wl_subsurface has no events" ) |
60 | } |
61 | } |
62 | |
63 | impl<D> Dispatch<WlSubcompositor, GlobalData, D> for SubcompositorState |
64 | where |
65 | D: Dispatch<WlSubcompositor, GlobalData>, |
66 | { |
67 | fn event( |
68 | _: &mut D, |
69 | _: &WlSubcompositor, |
70 | _: <WlSubcompositor as Proxy>::Event, |
71 | _: &GlobalData, |
72 | _: &Connection, |
73 | _: &QueueHandle<D>, |
74 | ) { |
75 | unreachable!("wl_subcompositor has no events" ) |
76 | } |
77 | } |
78 | |
79 | /// The data assoctiated with the subsurface. |
80 | #[derive (Debug)] |
81 | pub struct SubsurfaceData { |
82 | /// The surface used when creating this subsurface. |
83 | surface: WlSurface, |
84 | } |
85 | |
86 | impl SubsurfaceData { |
87 | pub(crate) fn new(surface: WlSurface) -> Self { |
88 | Self { surface } |
89 | } |
90 | |
91 | /// Get the surface used when creating the given subsurface. |
92 | pub fn surface(&self) -> &WlSurface { |
93 | &self.surface |
94 | } |
95 | } |
96 | |
97 | #[macro_export ] |
98 | macro_rules! delegate_subcompositor { |
99 | ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { |
100 | $crate::delegate_subcompositor!(@{ $(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty }; subsurface: []); |
101 | $crate::delegate_subcompositor!(@{ $(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty }; subsurface-only: $crate::subcompositor::SubsurfaceData); |
102 | }; |
103 | ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty, subsurface: [$($subsurface: ty),*$(,)?]) => { |
104 | $crate::delegate_subcompositor!(@{ $(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty }; subsurface: [ $($subsurface),* ]); |
105 | }; |
106 | (@{$($ty:tt)*}; subsurface: []) => { |
107 | $crate::reexports::client::delegate_dispatch!($($ty)*: |
108 | [ |
109 | $crate::reexports::client::protocol::wl_subcompositor::WlSubcompositor: $crate::globals::GlobalData |
110 | ] => $crate::subcompositor::SubcompositorState |
111 | ); |
112 | }; |
113 | (@{$($ty:tt)*}; subsurface-only: $subsurface:ty) => { |
114 | $crate::reexports::client::delegate_dispatch!($($ty)*: |
115 | [ |
116 | $crate::reexports::client::protocol::wl_subsurface::WlSubsurface: $subsurface |
117 | ] => $crate::subcompositor::SubcompositorState |
118 | ); |
119 | }; |
120 | (@$ty:tt; subsurface: [ $($subsurface:ty),+ ]) => { |
121 | $crate::delegate_subcompositor!(@$ty; subsurface: []); |
122 | $( $crate::delegate_subcompositor!(@$ty; subsurface-only: $subsurface); )* |
123 | }; |
124 | } |
125 | |