simple_window/common/protocols_data/wayland/
wl_callback.rs

1//! callback object
2//!
3//! Clients can handle the 'done' event to get notified when
4//! the related request is done.
5//!
6//! Note, because wl_callback objects are created from multiple independent
7//! factory interfaces, the wl_callback interface is frozen at version 1.
8
9use {super::super::all_types::*, ::wl_client::builder::prelude::*};
10
11static INTERFACE: wl_interface = wl_interface {
12    name: c"wl_callback".as_ptr(),
13    version: 1,
14    method_count: 0,
15    methods: ptr::null(),
16    event_count: 1,
17    events: {
18        static MESSAGES: [wl_message; 1] = [wl_message {
19            name: c"done".as_ptr(),
20            signature: c"u".as_ptr(),
21            types: {
22                static TYPES: [Option<&'static wl_interface>; 1] = [None];
23                TYPES.as_ptr().cast()
24            },
25        }];
26        MESSAGES.as_ptr()
27    },
28};
29
30/// An owned wl_callback proxy.
31///
32/// See the documentation of [the module][self] for the interface description.
33#[derive(Clone, Eq, PartialEq)]
34#[repr(transparent)]
35pub struct WlCallback {
36    /// This proxy has the interface INTERFACE.
37    proxy: UntypedOwnedProxy,
38}
39
40/// A borrowed wl_callback proxy.
41///
42/// See the documentation of [the module][self] for the interface description.
43#[derive(Eq, PartialEq)]
44#[repr(transparent)]
45pub struct WlCallbackRef {
46    /// This proxy has the interface INTERFACE.
47    proxy: UntypedBorrowedProxy,
48}
49
50// SAFETY: WlCallback is a transparent wrapper around UntypedOwnedProxy
51unsafe impl UntypedOwnedProxyWrapper for WlCallback {}
52
53// SAFETY: - INTERFACE is a valid wl_interface
54//         - The only invariant is that self.proxy has a compatible interface
55unsafe impl OwnedProxy for WlCallback {
56    const INTERFACE: &'static str = "wl_callback";
57    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
58    const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
59        private::EventHandler(private::NoOpEventHandler);
60    const MAX_VERSION: u32 = 1;
61
62    type Borrowed = WlCallbackRef;
63    type Api = private::ProxyApi;
64    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
65}
66
67// SAFETY: WlCallbackRef is a transparent wrapper around UntypedBorrowedProxy
68unsafe impl UntypedBorrowedProxyWrapper for WlCallbackRef {}
69
70// SAFETY: - The only invariant is that self.proxy has a compatible interface
71unsafe impl BorrowedProxy for WlCallbackRef {
72    type Owned = WlCallback;
73}
74
75impl Deref for WlCallback {
76    type Target = WlCallbackRef;
77
78    fn deref(&self) -> &Self::Target {
79        proxy::low_level::deref(self)
80    }
81}
82
83mod private {
84    pub struct ProxyApi;
85
86    #[allow(dead_code)]
87    pub struct EventHandler<H>(pub(super) H);
88
89    #[allow(dead_code)]
90    pub struct NoOpEventHandler;
91}
92
93impl Debug for WlCallback {
94    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
95        write!(f, "wl_callback#{}", self.proxy.id())
96    }
97}
98
99impl Debug for WlCallbackRef {
100    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
101        write!(f, "wl_callback#{}", self.proxy.id())
102    }
103}
104
105impl PartialEq<WlCallbackRef> for WlCallback {
106    fn eq(&self, other: &WlCallbackRef) -> bool {
107        self.proxy == other.proxy
108    }
109}
110
111impl PartialEq<WlCallback> for WlCallbackRef {
112    fn eq(&self, other: &WlCallback) -> bool {
113        self.proxy == other.proxy
114    }
115}
116
117impl WlCallback {
118    /// Since when the done event is available.
119    #[allow(dead_code)]
120    pub const EVT__DONE__SINCE: u32 = 1;
121}
122
123/// An event handler for [WlCallback] proxies.
124#[allow(dead_code)]
125pub trait WlCallbackEventHandler {
126    type Data: 'static;
127
128    /// done event
129    ///
130    /// Notify the client when the related request is done.
131    ///
132    /// # Arguments
133    ///
134    /// - `callback_data`: request-specific data for the callback
135    #[inline]
136    fn done(&self, _data: &mut Self::Data, _slf: &WlCallbackRef, callback_data: u32) {
137        let _ = callback_data;
138    }
139}
140
141impl WlCallbackEventHandler for private::NoOpEventHandler {
142    type Data = ();
143}
144
145// SAFETY: - INTERFACE is a valid wl_interface
146//         - mutable_type always returns the same value
147unsafe impl<H> EventHandler for private::EventHandler<H>
148where
149    H: WlCallbackEventHandler,
150{
151    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
152
153    #[inline]
154    fn mutable_type() -> Option<(TypeId, &'static str)> {
155        let id = TypeId::of::<H::Data>();
156        let name = std::any::type_name::<H::Data>();
157        Some((id, name))
158    }
159
160    #[allow(unused_variables)]
161    unsafe fn handle_event(
162        &self,
163        queue: &Queue,
164        data: *mut u8,
165        slf: &UntypedBorrowedProxy,
166        opcode: u32,
167        args: *mut wl_argument,
168    ) {
169        // SAFETY: This function requires that slf has the interface INTERFACE
170        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlCallbackRef>(slf) };
171        // SAFETY: This function requires that data is `&mut T` where `T`
172        //         has the type id returned by `Self::mutable_type`, i.e.,
173        //         `T = H::Data`.
174        let data: &mut H::Data = unsafe { &mut *data.cast() };
175        match opcode {
176            0 => {
177                // SAFETY: INTERFACE requires that there are 1 arguments
178                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
179                // SAFETY: - INTERFACE requires that args[0] contains a uint
180                let arg0 = unsafe { args[0].u };
181                self.0.done(data, slf, arg0);
182            }
183            _ => {
184                invalid_opcode("wl_callback", opcode);
185            }
186        }
187    }
188}
189
190impl<H> CreateEventHandler<H> for private::ProxyApi
191where
192    H: WlCallbackEventHandler,
193{
194    type EventHandler = private::EventHandler<H>;
195
196    #[inline]
197    fn create_event_handler(handler: H) -> Self::EventHandler {
198        private::EventHandler(handler)
199    }
200}
201
202/// Functional event handlers.
203pub mod event_handlers {
204    use super::*;
205
206    /// Event handler for done events.
207    pub struct Done<T, F>(F, PhantomData<fn(&mut T)>);
208    impl<T, F> WlCallbackEventHandler for Done<T, F>
209    where
210        T: 'static,
211        F: Fn(&mut T, &WlCallbackRef, u32),
212    {
213        type Data = T;
214
215        #[inline]
216        fn done(&self, _data: &mut T, _slf: &WlCallbackRef, callback_data: u32) {
217            self.0(_data, _slf, callback_data)
218        }
219    }
220
221    impl WlCallback {
222        /// Creates an event handler for done events.
223        ///
224        /// The event handler ignores all other events.
225        #[allow(dead_code)]
226        pub fn on_done<T, F>(f: F) -> Done<T, F>
227        where
228            T: 'static,
229            F: Fn(&mut T, &WlCallbackRef, u32),
230        {
231            Done(f, PhantomData)
232        }
233    }
234}