simple_window/common/protocols_data/wayland/
wl_registry.rs

1//! global registry object
2//!
3//! The singleton global registry object.  The server has a number of
4//! global objects that are available to all clients.  These objects
5//! typically represent an actual object in the server (for example,
6//! an input device) or they are singleton objects that provide
7//! extension functionality.
8//!
9//! When a client creates a registry object, the registry object
10//! will emit a global event for each global currently in the
11//! registry.  Globals come and go as a result of device or
12//! monitor hotplugs, reconfiguration or other events, and the
13//! registry will send out global and global_remove events to
14//! keep the client up to date with the changes.  To mark the end
15//! of the initial burst of events, the client can use the
16//! wl_display.sync request immediately after calling
17//! wl_display.get_registry.
18//!
19//! A client can bind to a global object by using the bind
20//! request.  This creates a client-side handle that lets the object
21//! emit events to the client and lets the client invoke requests on
22//! the object.
23
24use {super::super::all_types::*, ::wl_client::builder::prelude::*};
25
26static INTERFACE: wl_interface = wl_interface {
27    name: c"wl_registry".as_ptr(),
28    version: 1,
29    method_count: 1,
30    methods: {
31        static MESSAGES: [wl_message; 1] = [wl_message {
32            name: c"bind".as_ptr(),
33            signature: c"usun".as_ptr(),
34            types: {
35                static TYPES: [Option<&'static wl_interface>; 4] = [None, None, None, None];
36                TYPES.as_ptr().cast()
37            },
38        }];
39        MESSAGES.as_ptr()
40    },
41    event_count: 2,
42    events: {
43        static MESSAGES: [wl_message; 2] = [
44            wl_message {
45                name: c"global".as_ptr(),
46                signature: c"usu".as_ptr(),
47                types: {
48                    static TYPES: [Option<&'static wl_interface>; 3] = [None, None, None];
49                    TYPES.as_ptr().cast()
50                },
51            },
52            wl_message {
53                name: c"global_remove".as_ptr(),
54                signature: c"u".as_ptr(),
55                types: {
56                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
57                    TYPES.as_ptr().cast()
58                },
59            },
60        ];
61        MESSAGES.as_ptr()
62    },
63};
64
65/// An owned wl_registry proxy.
66///
67/// See the documentation of [the module][self] for the interface description.
68#[derive(Clone, Eq, PartialEq)]
69#[repr(transparent)]
70pub struct WlRegistry {
71    /// This proxy has the interface INTERFACE.
72    proxy: UntypedOwnedProxy,
73}
74
75/// A borrowed wl_registry proxy.
76///
77/// See the documentation of [the module][self] for the interface description.
78#[derive(Eq, PartialEq)]
79#[repr(transparent)]
80pub struct WlRegistryRef {
81    /// This proxy has the interface INTERFACE.
82    proxy: UntypedBorrowedProxy,
83}
84
85// SAFETY: WlRegistry is a transparent wrapper around UntypedOwnedProxy
86unsafe impl UntypedOwnedProxyWrapper for WlRegistry {}
87
88// SAFETY: - INTERFACE is a valid wl_interface
89//         - The only invariant is that self.proxy has a compatible interface
90unsafe impl OwnedProxy for WlRegistry {
91    const INTERFACE: &'static str = "wl_registry";
92    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
93    const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
94        private::EventHandler(private::NoOpEventHandler);
95    const MAX_VERSION: u32 = 1;
96
97    type Borrowed = WlRegistryRef;
98    type Api = private::ProxyApi;
99    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
100}
101
102// SAFETY: WlRegistryRef is a transparent wrapper around UntypedBorrowedProxy
103unsafe impl UntypedBorrowedProxyWrapper for WlRegistryRef {}
104
105// SAFETY: - The only invariant is that self.proxy has a compatible interface
106unsafe impl BorrowedProxy for WlRegistryRef {
107    type Owned = WlRegistry;
108}
109
110impl Deref for WlRegistry {
111    type Target = WlRegistryRef;
112
113    fn deref(&self) -> &Self::Target {
114        proxy::low_level::deref(self)
115    }
116}
117
118mod private {
119    pub struct ProxyApi;
120
121    #[allow(dead_code)]
122    pub struct EventHandler<H>(pub(super) H);
123
124    #[allow(dead_code)]
125    pub struct NoOpEventHandler;
126}
127
128impl Debug for WlRegistry {
129    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
130        write!(f, "wl_registry#{}", self.proxy.id())
131    }
132}
133
134impl Debug for WlRegistryRef {
135    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
136        write!(f, "wl_registry#{}", self.proxy.id())
137    }
138}
139
140impl PartialEq<WlRegistryRef> for WlRegistry {
141    fn eq(&self, other: &WlRegistryRef) -> bool {
142        self.proxy == other.proxy
143    }
144}
145
146impl PartialEq<WlRegistry> for WlRegistryRef {
147    fn eq(&self, other: &WlRegistry) -> bool {
148        self.proxy == other.proxy
149    }
150}
151
152#[allow(dead_code)]
153impl WlRegistry {
154    /// Since when the bind request is available.
155    #[allow(dead_code)]
156    pub const REQ__BIND__SINCE: u32 = 1;
157
158    /// bind an object to the display
159    ///
160    /// Binds a new, client-created object to the server using the
161    /// specified name as the identifier.
162    ///
163    /// # Arguments
164    ///
165    /// - `name`: unique numeric name of the object
166    #[inline]
167    pub fn bind<P: OwnedProxy>(&self, name: u32, version: u32) -> P {
168        let (arg0, arg1) = (name, version);
169        let mut args = [
170            wl_argument { u: arg0 },
171            wl_argument {
172                s: P::WL_INTERFACE.name,
173            },
174            wl_argument { u: arg1 },
175            wl_argument { n: 0 },
176        ];
177        // SAFETY: - self.proxy has the interface INTERFACE
178        //         - 0 < INTERFACE.method_count = 1
179        //         - the request signature is `usun`
180        //         - OwnedProxy::WL_INTERFACE is always a valid interface
181        let data = unsafe {
182            self.proxy
183                .send_constructor::<false>(0, &mut args, P::WL_INTERFACE, Some(version))
184        };
185        // SAFETY: data has the interface P::WL_INTERFACE
186        unsafe { proxy::low_level::from_untyped_owned(data) }
187    }
188}
189
190#[allow(dead_code)]
191impl WlRegistryRef {
192    /// bind an object to the display
193    ///
194    /// Binds a new, client-created object to the server using the
195    /// specified name as the identifier.
196    ///
197    /// # Arguments
198    ///
199    /// - `_queue`: The queue that the returned proxy is assigned to.
200    /// - `name`: unique numeric name of the object
201    #[inline]
202    pub fn bind<P: OwnedProxy>(&self, _queue: &Queue, name: u32, version: u32) -> P {
203        let (arg0, arg1) = (name, version);
204        let mut args = [
205            wl_argument { u: arg0 },
206            wl_argument {
207                s: P::WL_INTERFACE.name,
208            },
209            wl_argument { u: arg1 },
210            wl_argument { n: 0 },
211        ];
212        // SAFETY: - self.proxy has the interface INTERFACE
213        //         - 0 < INTERFACE.method_count = 1
214        //         - the request signature is `usun`
215        //         - OwnedProxy::WL_INTERFACE is always a valid interface
216        let data = unsafe {
217            self.proxy
218                .send_constructor(_queue, 0, &mut args, P::WL_INTERFACE, Some(version))
219        };
220        // SAFETY: data has the interface P::WL_INTERFACE
221        unsafe { proxy::low_level::from_untyped_owned(data) }
222    }
223}
224
225impl WlRegistry {
226    /// Since when the global event is available.
227    #[allow(dead_code)]
228    pub const EVT__GLOBAL__SINCE: u32 = 1;
229
230    /// Since when the global_remove event is available.
231    #[allow(dead_code)]
232    pub const EVT__GLOBAL_REMOVE__SINCE: u32 = 1;
233}
234
235/// An event handler for [WlRegistry] proxies.
236#[allow(dead_code)]
237pub trait WlRegistryEventHandler {
238    type Data: 'static;
239
240    /// announce global object
241    ///
242    /// Notify the client of global objects.
243    ///
244    /// The event notifies the client that a global object with
245    /// the given name is now available, and it implements the
246    /// given version of the given interface.
247    ///
248    /// # Arguments
249    ///
250    /// - `name`: numeric name of the global object
251    /// - `interface`: interface implemented by the object
252    /// - `version`: interface version
253    #[inline]
254    fn global(
255        &self,
256        _data: &mut Self::Data,
257        _slf: &WlRegistryRef,
258        name: u32,
259        interface: &str,
260        version: u32,
261    ) {
262        let _ = name;
263        let _ = interface;
264        let _ = version;
265    }
266
267    /// announce removal of global object
268    ///
269    /// Notify the client of removed global objects.
270    ///
271    /// This event notifies the client that the global identified
272    /// by name is no longer available.  If the client bound to
273    /// the global using the bind request, the client should now
274    /// destroy that object.
275    ///
276    /// The object remains valid and requests to the object will be
277    /// ignored until the client destroys it, to avoid races between
278    /// the global going away and a client sending a request to it.
279    ///
280    /// # Arguments
281    ///
282    /// - `name`: numeric name of the global object
283    #[inline]
284    fn global_remove(&self, _data: &mut Self::Data, _slf: &WlRegistryRef, name: u32) {
285        let _ = name;
286    }
287}
288
289impl WlRegistryEventHandler for private::NoOpEventHandler {
290    type Data = ();
291}
292
293// SAFETY: - INTERFACE is a valid wl_interface
294//         - mutable_type always returns the same value
295unsafe impl<H> EventHandler for private::EventHandler<H>
296where
297    H: WlRegistryEventHandler,
298{
299    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
300
301    #[inline]
302    fn mutable_type() -> Option<(TypeId, &'static str)> {
303        let id = TypeId::of::<H::Data>();
304        let name = std::any::type_name::<H::Data>();
305        Some((id, name))
306    }
307
308    #[allow(unused_variables)]
309    unsafe fn handle_event(
310        &self,
311        queue: &Queue,
312        data: *mut u8,
313        slf: &UntypedBorrowedProxy,
314        opcode: u32,
315        args: *mut wl_argument,
316    ) {
317        // SAFETY: This function requires that slf has the interface INTERFACE
318        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlRegistryRef>(slf) };
319        // SAFETY: This function requires that data is `&mut T` where `T`
320        //         has the type id returned by `Self::mutable_type`, i.e.,
321        //         `T = H::Data`.
322        let data: &mut H::Data = unsafe { &mut *data.cast() };
323        match opcode {
324            0 => {
325                // SAFETY: INTERFACE requires that there are 3 arguments
326                let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
327                // SAFETY: - INTERFACE requires that args[0] contains a uint
328                let arg0 = unsafe { args[0].u };
329                // SAFETY: - INTERFACE requires that args[1] contains a string
330                //         - if the pointer is not null, then it is a c string
331                let arg1 = unsafe { convert_string_arg("wl_registry", "interface", args[1].s) };
332                // SAFETY: - INTERFACE requires that args[2] contains a uint
333                let arg2 = unsafe { args[2].u };
334                self.0.global(data, slf, arg0, arg1, arg2);
335            }
336            1 => {
337                // SAFETY: INTERFACE requires that there are 1 arguments
338                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
339                // SAFETY: - INTERFACE requires that args[0] contains a uint
340                let arg0 = unsafe { args[0].u };
341                self.0.global_remove(data, slf, arg0);
342            }
343            _ => {
344                invalid_opcode("wl_registry", opcode);
345            }
346        }
347    }
348}
349
350impl<H> CreateEventHandler<H> for private::ProxyApi
351where
352    H: WlRegistryEventHandler,
353{
354    type EventHandler = private::EventHandler<H>;
355
356    #[inline]
357    fn create_event_handler(handler: H) -> Self::EventHandler {
358        private::EventHandler(handler)
359    }
360}
361
362/// Functional event handlers.
363pub mod event_handlers {
364    use super::*;
365
366    /// Event handler for global events.
367    pub struct Global<T, F>(F, PhantomData<fn(&mut T)>);
368    impl<T, F> WlRegistryEventHandler for Global<T, F>
369    where
370        T: 'static,
371        F: Fn(&mut T, &WlRegistryRef, u32, &str, u32),
372    {
373        type Data = T;
374
375        #[inline]
376        fn global(
377            &self,
378            _data: &mut T,
379            _slf: &WlRegistryRef,
380            name: u32,
381            interface: &str,
382            version: u32,
383        ) {
384            self.0(_data, _slf, name, interface, version)
385        }
386    }
387
388    /// Event handler for global_remove events.
389    pub struct GlobalRemove<T, F>(F, PhantomData<fn(&mut T)>);
390    impl<T, F> WlRegistryEventHandler for GlobalRemove<T, F>
391    where
392        T: 'static,
393        F: Fn(&mut T, &WlRegistryRef, u32),
394    {
395        type Data = T;
396
397        #[inline]
398        fn global_remove(&self, _data: &mut T, _slf: &WlRegistryRef, name: u32) {
399            self.0(_data, _slf, name)
400        }
401    }
402
403    impl WlRegistry {
404        /// Creates an event handler for global events.
405        ///
406        /// The event handler ignores all other events.
407        #[allow(dead_code)]
408        pub fn on_global<T, F>(f: F) -> Global<T, F>
409        where
410            T: 'static,
411            F: Fn(&mut T, &WlRegistryRef, u32, &str, u32),
412        {
413            Global(f, PhantomData)
414        }
415
416        /// Creates an event handler for global_remove events.
417        ///
418        /// The event handler ignores all other events.
419        #[allow(dead_code)]
420        pub fn on_global_remove<T, F>(f: F) -> GlobalRemove<T, F>
421        where
422            T: 'static,
423            F: Fn(&mut T, &WlRegistryRef, u32),
424        {
425            GlobalRemove(f, PhantomData)
426        }
427    }
428}