simple_window/common/protocols_data/wayland/
wl_subcompositor.rs

1//! sub-surface compositing
2//!
3//! The global interface exposing sub-surface compositing capabilities.
4//! A wl_surface, that has sub-surfaces associated, is called the
5//! parent surface. Sub-surfaces can be arbitrarily nested and create
6//! a tree of sub-surfaces.
7//!
8//! The root surface in a tree of sub-surfaces is the main
9//! surface. The main surface cannot be a sub-surface, because
10//! sub-surfaces must always have a parent.
11//!
12//! A main surface with its sub-surfaces forms a (compound) window.
13//! For window management purposes, this set of wl_surface objects is
14//! to be considered as a single window, and it should also behave as
15//! such.
16//!
17//! The aim of sub-surfaces is to offload some of the compositing work
18//! within a window from clients to the compositor. A prime example is
19//! a video player with decorations and video in separate wl_surface
20//! objects. This should allow the compositor to pass YUV video buffer
21//! processing to dedicated overlay hardware when possible.
22
23use {super::super::all_types::*, ::wl_client::builder::prelude::*};
24
25static INTERFACE: wl_interface = wl_interface {
26    name: c"wl_subcompositor".as_ptr(),
27    version: 1,
28    method_count: 2,
29    methods: {
30        static MESSAGES: [wl_message; 2] = [
31            wl_message {
32                name: c"destroy".as_ptr(),
33                signature: c"".as_ptr(),
34                types: {
35                    static TYPES: [Option<&'static wl_interface>; 0] = [];
36                    TYPES.as_ptr().cast()
37                },
38            },
39            wl_message {
40                name: c"get_subsurface".as_ptr(),
41                signature: c"noo".as_ptr(),
42                types: {
43                    static TYPES: [Option<&'static wl_interface>; 3] = [
44                        Some(WlSubsurface::WL_INTERFACE),
45                        Some(WlSurface::WL_INTERFACE),
46                        Some(WlSurface::WL_INTERFACE),
47                    ];
48                    TYPES.as_ptr().cast()
49                },
50            },
51        ];
52        MESSAGES.as_ptr()
53    },
54    event_count: 0,
55    events: ptr::null(),
56};
57
58/// An owned wl_subcompositor proxy.
59///
60/// See the documentation of [the module][self] for the interface description.
61#[derive(Clone, Eq, PartialEq)]
62#[repr(transparent)]
63pub struct WlSubcompositor {
64    /// This proxy has the interface INTERFACE.
65    proxy: UntypedOwnedProxy,
66}
67
68/// A borrowed wl_subcompositor proxy.
69///
70/// See the documentation of [the module][self] for the interface description.
71#[derive(Eq, PartialEq)]
72#[repr(transparent)]
73pub struct WlSubcompositorRef {
74    /// This proxy has the interface INTERFACE.
75    proxy: UntypedBorrowedProxy,
76}
77
78// SAFETY: WlSubcompositor is a transparent wrapper around UntypedOwnedProxy
79unsafe impl UntypedOwnedProxyWrapper for WlSubcompositor {}
80
81// SAFETY: - INTERFACE is a valid wl_interface
82//         - The only invariant is that self.proxy has a compatible interface
83unsafe impl OwnedProxy for WlSubcompositor {
84    const INTERFACE: &'static str = "wl_subcompositor";
85    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
86    const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
87        private::EventHandler(private::NoOpEventHandler);
88    const MAX_VERSION: u32 = 1;
89
90    type Borrowed = WlSubcompositorRef;
91    type Api = private::ProxyApi;
92    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
93}
94
95// SAFETY: WlSubcompositorRef is a transparent wrapper around UntypedBorrowedProxy
96unsafe impl UntypedBorrowedProxyWrapper for WlSubcompositorRef {}
97
98// SAFETY: - The only invariant is that self.proxy has a compatible interface
99unsafe impl BorrowedProxy for WlSubcompositorRef {
100    type Owned = WlSubcompositor;
101}
102
103impl Deref for WlSubcompositor {
104    type Target = WlSubcompositorRef;
105
106    fn deref(&self) -> &Self::Target {
107        proxy::low_level::deref(self)
108    }
109}
110
111mod private {
112    pub struct ProxyApi;
113
114    #[allow(dead_code)]
115    pub struct EventHandler<H>(pub(super) H);
116
117    #[allow(dead_code)]
118    pub struct NoOpEventHandler;
119}
120
121impl Debug for WlSubcompositor {
122    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
123        write!(f, "wl_subcompositor#{}", self.proxy.id())
124    }
125}
126
127impl Debug for WlSubcompositorRef {
128    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
129        write!(f, "wl_subcompositor#{}", self.proxy.id())
130    }
131}
132
133impl PartialEq<WlSubcompositorRef> for WlSubcompositor {
134    fn eq(&self, other: &WlSubcompositorRef) -> bool {
135        self.proxy == other.proxy
136    }
137}
138
139impl PartialEq<WlSubcompositor> for WlSubcompositorRef {
140    fn eq(&self, other: &WlSubcompositor) -> bool {
141        self.proxy == other.proxy
142    }
143}
144
145#[allow(dead_code)]
146impl WlSubcompositor {
147    /// Since when the destroy request is available.
148    #[allow(dead_code)]
149    pub const REQ__DESTROY__SINCE: u32 = 1;
150
151    /// unbind from the subcompositor interface
152    ///
153    /// Informs the server that the client will not be using this
154    /// protocol object anymore. This does not affect any other
155    /// objects, wl_subsurface objects included.
156    #[inline]
157    pub fn destroy(&self) {
158        let mut args = [];
159        // SAFETY: - self.proxy has the interface INTERFACE
160        //         - 0 < INTERFACE.method_count = 2
161        //         - the request signature is ``
162        unsafe {
163            self.proxy.send_destructor(0, &mut args);
164        }
165    }
166
167    /// Since when the get_subsurface request is available.
168    #[allow(dead_code)]
169    pub const REQ__GET_SUBSURFACE__SINCE: u32 = 1;
170
171    /// give a surface the role sub-surface
172    ///
173    /// Create a sub-surface interface for the given surface, and
174    /// associate it with the given parent surface. This turns a
175    /// plain wl_surface into a sub-surface.
176    ///
177    /// The to-be sub-surface must not already have another role, and it
178    /// must not have an existing wl_subsurface object. Otherwise the
179    /// bad_surface protocol error is raised.
180    ///
181    /// Adding sub-surfaces to a parent is a double-buffered operation on the
182    /// parent (see wl_surface.commit). The effect of adding a sub-surface
183    /// becomes visible on the next time the state of the parent surface is
184    /// applied.
185    ///
186    /// The parent surface must not be one of the child surface's descendants,
187    /// and the parent must be different from the child surface, otherwise the
188    /// bad_parent protocol error is raised.
189    ///
190    /// This request modifies the behaviour of wl_surface.commit request on
191    /// the sub-surface, see the documentation on wl_subsurface interface.
192    ///
193    /// # Arguments
194    ///
195    /// - `surface`: the surface to be turned into a sub-surface
196    /// - `parent`: the parent surface
197    #[inline]
198    pub fn get_subsurface(&self, surface: &WlSurfaceRef, parent: &WlSurfaceRef) -> WlSubsurface {
199        let (arg1, arg2) = (surface, parent);
200        let obj1_lock = proxy::lock(arg1);
201        let obj1 = check_argument_proxy("surface", obj1_lock.wl_proxy());
202        let obj2_lock = proxy::lock(arg2);
203        let obj2 = check_argument_proxy("parent", obj2_lock.wl_proxy());
204        let mut args = [
205            wl_argument { n: 0 },
206            wl_argument { o: obj1 },
207            wl_argument { o: obj2 },
208        ];
209        // SAFETY: - self.proxy has the interface INTERFACE
210        //         - 1 < INTERFACE.method_count = 2
211        //         - the request signature is `noo`
212        //         - OwnedProxy::WL_INTERFACE is always a valid interface
213        let data = unsafe {
214            self.proxy
215                .send_constructor::<false>(1, &mut args, WlSubsurface::WL_INTERFACE, None)
216        };
217        // SAFETY: data has the interface WlSubsurface::WL_INTERFACE
218        unsafe { proxy::low_level::from_untyped_owned(data) }
219    }
220}
221
222#[allow(dead_code)]
223impl WlSubcompositorRef {
224    /// give a surface the role sub-surface
225    ///
226    /// Create a sub-surface interface for the given surface, and
227    /// associate it with the given parent surface. This turns a
228    /// plain wl_surface into a sub-surface.
229    ///
230    /// The to-be sub-surface must not already have another role, and it
231    /// must not have an existing wl_subsurface object. Otherwise the
232    /// bad_surface protocol error is raised.
233    ///
234    /// Adding sub-surfaces to a parent is a double-buffered operation on the
235    /// parent (see wl_surface.commit). The effect of adding a sub-surface
236    /// becomes visible on the next time the state of the parent surface is
237    /// applied.
238    ///
239    /// The parent surface must not be one of the child surface's descendants,
240    /// and the parent must be different from the child surface, otherwise the
241    /// bad_parent protocol error is raised.
242    ///
243    /// This request modifies the behaviour of wl_surface.commit request on
244    /// the sub-surface, see the documentation on wl_subsurface interface.
245    ///
246    /// # Arguments
247    ///
248    /// - `_queue`: The queue that the returned proxy is assigned to.
249    /// - `surface`: the surface to be turned into a sub-surface
250    /// - `parent`: the parent surface
251    #[inline]
252    pub fn get_subsurface(
253        &self,
254        _queue: &Queue,
255        surface: &WlSurfaceRef,
256        parent: &WlSurfaceRef,
257    ) -> WlSubsurface {
258        let (arg1, arg2) = (surface, parent);
259        let obj1_lock = proxy::lock(arg1);
260        let obj1 = check_argument_proxy("surface", obj1_lock.wl_proxy());
261        let obj2_lock = proxy::lock(arg2);
262        let obj2 = check_argument_proxy("parent", obj2_lock.wl_proxy());
263        let mut args = [
264            wl_argument { n: 0 },
265            wl_argument { o: obj1 },
266            wl_argument { o: obj2 },
267        ];
268        // SAFETY: - self.proxy has the interface INTERFACE
269        //         - 1 < INTERFACE.method_count = 2
270        //         - the request signature is `noo`
271        //         - OwnedProxy::WL_INTERFACE is always a valid interface
272        let data = unsafe {
273            self.proxy
274                .send_constructor(_queue, 1, &mut args, WlSubsurface::WL_INTERFACE, None)
275        };
276        // SAFETY: data has the interface WlSubsurface::WL_INTERFACE
277        unsafe { proxy::low_level::from_untyped_owned(data) }
278    }
279}
280
281/// An event handler for [WlSubcompositor] proxies.
282#[allow(dead_code)]
283pub trait WlSubcompositorEventHandler {
284    type Data: 'static;
285}
286
287impl WlSubcompositorEventHandler for private::NoOpEventHandler {
288    type Data = ();
289}
290
291// SAFETY: - INTERFACE is a valid wl_interface
292//         - mutable_type always returns the same value
293unsafe impl<H> EventHandler for private::EventHandler<H>
294where
295    H: WlSubcompositorEventHandler,
296{
297    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
298
299    #[inline]
300    fn mutable_type() -> Option<(TypeId, &'static str)> {
301        let id = TypeId::of::<H::Data>();
302        let name = std::any::type_name::<H::Data>();
303        Some((id, name))
304    }
305
306    #[allow(unused_variables)]
307    unsafe fn handle_event(
308        &self,
309        queue: &Queue,
310        data: *mut u8,
311        slf: &UntypedBorrowedProxy,
312        opcode: u32,
313        args: *mut wl_argument,
314    ) {
315        invalid_opcode("wl_subcompositor", opcode);
316    }
317}
318
319impl<H> CreateEventHandler<H> for private::ProxyApi
320where
321    H: WlSubcompositorEventHandler,
322{
323    type EventHandler = private::EventHandler<H>;
324
325    #[inline]
326    fn create_event_handler(handler: H) -> Self::EventHandler {
327        private::EventHandler(handler)
328    }
329}
330
331impl WlSubcompositor {
332    /// Since when the error.bad_surface enum variant is available.
333    #[allow(dead_code)]
334    pub const ENM__ERROR_BAD_SURFACE__SINCE: u32 = 1;
335    /// Since when the error.bad_parent enum variant is available.
336    #[allow(dead_code)]
337    pub const ENM__ERROR_BAD_PARENT__SINCE: u32 = 1;
338}
339
340#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
341#[allow(dead_code)]
342pub struct WlSubcompositorError(pub u32);
343
344impl WlSubcompositorError {
345    /// the to-be sub-surface is invalid
346    #[allow(dead_code)]
347    pub const BAD_SURFACE: Self = Self(0);
348
349    /// the to-be sub-surface parent is invalid
350    #[allow(dead_code)]
351    pub const BAD_PARENT: Self = Self(1);
352}
353
354impl Debug for WlSubcompositorError {
355    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
356        let name = match *self {
357            Self::BAD_SURFACE => "BAD_SURFACE",
358            Self::BAD_PARENT => "BAD_PARENT",
359            _ => return Debug::fmt(&self.0, f),
360        };
361        f.write_str(name)
362    }
363}
364
365/// Functional event handlers.
366pub mod event_handlers {
367    use super::*;
368
369    impl WlSubcompositor {}
370}