async_roundtrip/common/protocols/wayland/
wl_display.rs

1//! core global object
2//!
3//! The core global object.  This is a special singleton object.  It
4//! is used for internal Wayland protocol features.
5
6use {super::super::all_types::*, ::wl_client::builder::prelude::*};
7
8static INTERFACE: wl_interface = wl_interface {
9    name: c"wl_display".as_ptr(),
10    version: 1,
11    method_count: 2,
12    methods: {
13        static MESSAGES: [wl_message; 2] = [
14            wl_message {
15                name: c"sync".as_ptr(),
16                signature: c"n".as_ptr(),
17                types: {
18                    static TYPES: [Option<&'static wl_interface>; 1] =
19                        [Some(WlCallback::WL_INTERFACE)];
20                    TYPES.as_ptr().cast()
21                },
22            },
23            wl_message {
24                name: c"get_registry".as_ptr(),
25                signature: c"n".as_ptr(),
26                types: {
27                    static TYPES: [Option<&'static wl_interface>; 1] =
28                        [Some(WlRegistry::WL_INTERFACE)];
29                    TYPES.as_ptr().cast()
30                },
31            },
32        ];
33        MESSAGES.as_ptr()
34    },
35    event_count: 2,
36    events: {
37        static MESSAGES: [wl_message; 2] = [
38            wl_message {
39                name: c"error".as_ptr(),
40                signature: c"ous".as_ptr(),
41                types: {
42                    static TYPES: [Option<&'static wl_interface>; 3] = [None, None, None];
43                    TYPES.as_ptr().cast()
44                },
45            },
46            wl_message {
47                name: c"delete_id".as_ptr(),
48                signature: c"u".as_ptr(),
49                types: {
50                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
51                    TYPES.as_ptr().cast()
52                },
53            },
54        ];
55        MESSAGES.as_ptr()
56    },
57};
58
59/// An owned wl_display proxy.
60///
61/// See the documentation of [the module][self] for the interface description.
62#[derive(Clone, Eq, PartialEq)]
63#[repr(transparent)]
64pub struct WlDisplay {
65    /// This proxy has the interface INTERFACE.
66    proxy: UntypedOwnedProxy,
67}
68
69/// A borrowed wl_display proxy.
70///
71/// See the documentation of [the module][self] for the interface description.
72#[derive(Eq, PartialEq)]
73#[repr(transparent)]
74pub struct WlDisplayRef {
75    /// This proxy has the interface INTERFACE.
76    proxy: UntypedBorrowedProxy,
77}
78
79// SAFETY: WlDisplay is a transparent wrapper around UntypedOwnedProxy
80unsafe impl UntypedOwnedProxyWrapper for WlDisplay {}
81
82// SAFETY: - INTERFACE is a valid wl_interface
83//         - The only invariant is that self.proxy has a compatible interface
84unsafe impl OwnedProxy for WlDisplay {
85    const INTERFACE: &'static str = "wl_display";
86    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
87    const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
88        private::EventHandler(private::NoOpEventHandler);
89    const MAX_VERSION: u32 = 1;
90
91    type Borrowed = WlDisplayRef;
92    type Api = private::ProxyApi;
93    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
94}
95
96// SAFETY: WlDisplayRef is a transparent wrapper around UntypedBorrowedProxy
97unsafe impl UntypedBorrowedProxyWrapper for WlDisplayRef {}
98
99// SAFETY: - The only invariant is that self.proxy has a compatible interface
100unsafe impl BorrowedProxy for WlDisplayRef {
101    type Owned = WlDisplay;
102}
103
104impl Deref for WlDisplay {
105    type Target = WlDisplayRef;
106
107    fn deref(&self) -> &Self::Target {
108        proxy::low_level::deref(self)
109    }
110}
111
112mod private {
113    pub struct ProxyApi;
114
115    #[allow(dead_code)]
116    pub struct EventHandler<H>(pub(super) H);
117
118    #[allow(dead_code)]
119    pub struct NoOpEventHandler;
120}
121
122impl Debug for WlDisplay {
123    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
124        write!(f, "wl_display#{}", self.proxy.id())
125    }
126}
127
128impl Debug for WlDisplayRef {
129    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
130        write!(f, "wl_display#{}", self.proxy.id())
131    }
132}
133
134impl PartialEq<WlDisplayRef> for WlDisplay {
135    fn eq(&self, other: &WlDisplayRef) -> bool {
136        self.proxy == other.proxy
137    }
138}
139
140impl PartialEq<WlDisplay> for WlDisplayRef {
141    fn eq(&self, other: &WlDisplay) -> bool {
142        self.proxy == other.proxy
143    }
144}
145
146#[allow(dead_code)]
147impl WlDisplay {
148    /// Since when the sync request is available.
149    #[allow(dead_code)]
150    pub const REQ__SYNC__SINCE: u32 = 1;
151
152    /// asynchronous roundtrip
153    ///
154    /// The sync request asks the server to emit the 'done' event
155    /// on the returned wl_callback object.  Since requests are
156    /// handled in-order and events are delivered in-order, this can
157    /// be used as a barrier to ensure all previous requests and the
158    /// resulting events have been handled.
159    ///
160    /// The object returned by this request will be destroyed by the
161    /// compositor after the callback is fired and as such the client must not
162    /// attempt to use it after that point.
163    ///
164    /// The callback_data passed in the callback is undefined and should be ignored.
165    #[inline]
166    pub fn sync(&self) -> WlCallback {
167        let mut args = [wl_argument { n: 0 }];
168        // SAFETY: - self.proxy has the interface INTERFACE
169        //         - 0 < INTERFACE.method_count = 2
170        //         - the request signature is `n`
171        //         - OwnedProxy::WL_INTERFACE is always a valid interface
172        let data = unsafe {
173            self.proxy
174                .send_constructor::<false>(0, &mut args, WlCallback::WL_INTERFACE, None)
175        };
176        // SAFETY: data has the interface WlCallback::WL_INTERFACE
177        unsafe { proxy::low_level::from_untyped_owned(data) }
178    }
179
180    /// Since when the get_registry request is available.
181    #[allow(dead_code)]
182    pub const REQ__GET_REGISTRY__SINCE: u32 = 1;
183
184    /// get global registry object
185    ///
186    /// This request creates a registry object that allows the client
187    /// to list and bind the global objects available from the
188    /// compositor.
189    ///
190    /// It should be noted that the server side resources consumed in
191    /// response to a get_registry request can only be released when the
192    /// client disconnects, not when the client side proxy is destroyed.
193    /// Therefore, clients should invoke get_registry as infrequently as
194    /// possible to avoid wasting memory.
195    #[inline]
196    pub fn get_registry(&self) -> WlRegistry {
197        let mut args = [wl_argument { n: 0 }];
198        // SAFETY: - self.proxy has the interface INTERFACE
199        //         - 1 < INTERFACE.method_count = 2
200        //         - the request signature is `n`
201        //         - OwnedProxy::WL_INTERFACE is always a valid interface
202        let data = unsafe {
203            self.proxy
204                .send_constructor::<false>(1, &mut args, WlRegistry::WL_INTERFACE, None)
205        };
206        // SAFETY: data has the interface WlRegistry::WL_INTERFACE
207        unsafe { proxy::low_level::from_untyped_owned(data) }
208    }
209}
210
211#[allow(dead_code)]
212impl WlDisplayRef {
213    /// asynchronous roundtrip
214    ///
215    /// The sync request asks the server to emit the 'done' event
216    /// on the returned wl_callback object.  Since requests are
217    /// handled in-order and events are delivered in-order, this can
218    /// be used as a barrier to ensure all previous requests and the
219    /// resulting events have been handled.
220    ///
221    /// The object returned by this request will be destroyed by the
222    /// compositor after the callback is fired and as such the client must not
223    /// attempt to use it after that point.
224    ///
225    /// The callback_data passed in the callback is undefined and should be ignored.
226    ///
227    /// # Arguments
228    ///
229    /// - `_queue`: The queue that the returned proxy is assigned to.
230    #[inline]
231    pub fn sync(&self, _queue: &Queue) -> WlCallback {
232        let mut args = [wl_argument { n: 0 }];
233        // SAFETY: - self.proxy has the interface INTERFACE
234        //         - 0 < INTERFACE.method_count = 2
235        //         - the request signature is `n`
236        //         - OwnedProxy::WL_INTERFACE is always a valid interface
237        let data = unsafe {
238            self.proxy
239                .send_constructor(_queue, 0, &mut args, WlCallback::WL_INTERFACE, None)
240        };
241        // SAFETY: data has the interface WlCallback::WL_INTERFACE
242        unsafe { proxy::low_level::from_untyped_owned(data) }
243    }
244
245    /// get global registry object
246    ///
247    /// This request creates a registry object that allows the client
248    /// to list and bind the global objects available from the
249    /// compositor.
250    ///
251    /// It should be noted that the server side resources consumed in
252    /// response to a get_registry request can only be released when the
253    /// client disconnects, not when the client side proxy is destroyed.
254    /// Therefore, clients should invoke get_registry as infrequently as
255    /// possible to avoid wasting memory.
256    ///
257    /// # Arguments
258    ///
259    /// - `_queue`: The queue that the returned proxy is assigned to.
260    #[inline]
261    pub fn get_registry(&self, _queue: &Queue) -> WlRegistry {
262        let mut args = [wl_argument { n: 0 }];
263        // SAFETY: - self.proxy has the interface INTERFACE
264        //         - 1 < INTERFACE.method_count = 2
265        //         - the request signature is `n`
266        //         - OwnedProxy::WL_INTERFACE is always a valid interface
267        let data = unsafe {
268            self.proxy
269                .send_constructor(_queue, 1, &mut args, WlRegistry::WL_INTERFACE, None)
270        };
271        // SAFETY: data has the interface WlRegistry::WL_INTERFACE
272        unsafe { proxy::low_level::from_untyped_owned(data) }
273    }
274}
275
276impl WlDisplay {
277    /// Since when the error event is available.
278    #[allow(dead_code)]
279    pub const EVT__ERROR__SINCE: u32 = 1;
280
281    /// Since when the delete_id event is available.
282    #[allow(dead_code)]
283    pub const EVT__DELETE_ID__SINCE: u32 = 1;
284}
285
286/// An event handler for [WlDisplay] proxies.
287#[allow(dead_code)]
288pub trait WlDisplayEventHandler {
289    /// fatal error event
290    ///
291    /// The error event is sent out when a fatal (non-recoverable)
292    /// error has occurred.  The object_id argument is the object
293    /// where the error occurred, most often in response to a request
294    /// to that object.  The code identifies the error and is defined
295    /// by the object interface.  As such, each interface defines its
296    /// own set of error codes.  The message is a brief description
297    /// of the error, for (debugging) convenience.
298    ///
299    /// # Arguments
300    ///
301    /// - `object_id`: object where the error occurred
302    /// - `code`: error code
303    /// - `message`: error description
304    ///
305    /// All borrowed proxies passed to this function are guaranteed to be
306    /// immutable and non-null.
307    #[inline]
308    fn error(
309        &self,
310        _slf: &WlDisplayRef,
311        object_id: Option<&UntypedBorrowedProxy>,
312        code: u32,
313        message: &str,
314    ) {
315        let _ = object_id;
316        let _ = code;
317        let _ = message;
318    }
319
320    /// acknowledge object ID deletion
321    ///
322    /// This event is used internally by the object ID management
323    /// logic. When a client deletes an object that it had created,
324    /// the server will send this event to acknowledge that it has
325    /// seen the delete request. When the client receives this event,
326    /// it will know that it can safely reuse the object ID.
327    ///
328    /// # Arguments
329    ///
330    /// - `id`: deleted object ID
331    #[inline]
332    fn delete_id(&self, _slf: &WlDisplayRef, id: u32) {
333        let _ = id;
334    }
335}
336
337impl WlDisplayEventHandler for private::NoOpEventHandler {}
338
339// SAFETY: - INTERFACE is a valid wl_interface
340unsafe impl<H> EventHandler for private::EventHandler<H>
341where
342    H: WlDisplayEventHandler,
343{
344    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
345
346    #[allow(unused_variables)]
347    unsafe fn handle_event(
348        &self,
349        queue: &Queue,
350        data: *mut u8,
351        slf: &UntypedBorrowedProxy,
352        opcode: u32,
353        args: *mut wl_argument,
354    ) {
355        // SAFETY: This function requires that slf has the interface INTERFACE
356        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlDisplayRef>(slf) };
357        match opcode {
358            0 => {
359                // SAFETY: INTERFACE requires that there are 3 arguments
360                let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
361                // SAFETY: - INTERFACE requires that args[0] contains an object
362                let arg0 = unsafe {
363                    if let Some(p) = NonNull::new(args[0].o.cast()) {
364                        Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
365                    } else {
366                        None
367                    }
368                };
369                let arg0 = arg0.as_ref();
370                // SAFETY: - INTERFACE requires that args[1] contains a uint
371                let arg1 = unsafe { args[1].u };
372                // SAFETY: - INTERFACE requires that args[2] contains a string
373                //         - if the pointer is not null, then it is a c string
374                let arg2 = unsafe { convert_string_arg("wl_display", "message", args[2].s) };
375                self.0.error(slf, arg0, arg1, arg2);
376            }
377            1 => {
378                // SAFETY: INTERFACE requires that there are 1 arguments
379                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
380                // SAFETY: - INTERFACE requires that args[0] contains a uint
381                let arg0 = unsafe { args[0].u };
382                self.0.delete_id(slf, arg0);
383            }
384            _ => {
385                invalid_opcode("wl_display", opcode);
386            }
387        }
388    }
389}
390
391impl<H> CreateEventHandler<H> for private::ProxyApi
392where
393    H: WlDisplayEventHandler,
394{
395    type EventHandler = private::EventHandler<H>;
396
397    #[inline]
398    fn create_event_handler(handler: H) -> Self::EventHandler {
399        private::EventHandler(handler)
400    }
401}
402
403impl WlDisplay {
404    /// Since when the error.invalid_object enum variant is available.
405    #[allow(dead_code)]
406    pub const ENM__ERROR_INVALID_OBJECT__SINCE: u32 = 1;
407    /// Since when the error.invalid_method enum variant is available.
408    #[allow(dead_code)]
409    pub const ENM__ERROR_INVALID_METHOD__SINCE: u32 = 1;
410    /// Since when the error.no_memory enum variant is available.
411    #[allow(dead_code)]
412    pub const ENM__ERROR_NO_MEMORY__SINCE: u32 = 1;
413    /// Since when the error.implementation enum variant is available.
414    #[allow(dead_code)]
415    pub const ENM__ERROR_IMPLEMENTATION__SINCE: u32 = 1;
416}
417
418/// global error values
419///
420/// These errors are global and can be emitted in response to any
421/// server request.
422#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
423#[allow(dead_code)]
424pub struct WlDisplayError(pub u32);
425
426impl WlDisplayError {
427    /// server couldn't find object
428    #[allow(dead_code)]
429    pub const INVALID_OBJECT: Self = Self(0);
430
431    /// method doesn't exist on the specified interface or malformed request
432    #[allow(dead_code)]
433    pub const INVALID_METHOD: Self = Self(1);
434
435    /// server is out of memory
436    #[allow(dead_code)]
437    pub const NO_MEMORY: Self = Self(2);
438
439    /// implementation error in compositor
440    #[allow(dead_code)]
441    pub const IMPLEMENTATION: Self = Self(3);
442}
443
444impl Debug for WlDisplayError {
445    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
446        let name = match *self {
447            Self::INVALID_OBJECT => "INVALID_OBJECT",
448            Self::INVALID_METHOD => "INVALID_METHOD",
449            Self::NO_MEMORY => "NO_MEMORY",
450            Self::IMPLEMENTATION => "IMPLEMENTATION",
451            _ => return Debug::fmt(&self.0, f),
452        };
453        f.write_str(name)
454    }
455}
456
457/// Functional event handlers.
458pub mod event_handlers {
459    use super::*;
460
461    /// Event handler for error events.
462    pub struct Error<F>(F);
463    impl<F> WlDisplayEventHandler for Error<F>
464    where
465        F: Fn(&WlDisplayRef, Option<&UntypedBorrowedProxy>, u32, &str),
466    {
467        #[inline]
468        fn error(
469            &self,
470            _slf: &WlDisplayRef,
471            object_id: Option<&UntypedBorrowedProxy>,
472            code: u32,
473            message: &str,
474        ) {
475            self.0(_slf, object_id, code, message)
476        }
477    }
478
479    /// Event handler for delete_id events.
480    pub struct DeleteId<F>(F);
481    impl<F> WlDisplayEventHandler for DeleteId<F>
482    where
483        F: Fn(&WlDisplayRef, u32),
484    {
485        #[inline]
486        fn delete_id(&self, _slf: &WlDisplayRef, id: u32) {
487            self.0(_slf, id)
488        }
489    }
490
491    impl WlDisplay {
492        /// Creates an event handler for error events.
493        ///
494        /// The event handler ignores all other events.
495        #[allow(dead_code)]
496        pub fn on_error<F>(f: F) -> Error<F>
497        where
498            F: Fn(&WlDisplayRef, Option<&UntypedBorrowedProxy>, u32, &str),
499        {
500            Error(f)
501        }
502
503        /// Creates an event handler for delete_id events.
504        ///
505        /// The event handler ignores all other events.
506        #[allow(dead_code)]
507        pub fn on_delete_id<F>(f: F) -> DeleteId<F>
508        where
509            F: Fn(&WlDisplayRef, u32),
510        {
511            DeleteId(f)
512        }
513    }
514}