| 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 | |