simple_window/common/protocols_data/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    type Data: 'static;
290
291    /// fatal error event
292    ///
293    /// The error event is sent out when a fatal (non-recoverable)
294    /// error has occurred.  The object_id argument is the object
295    /// where the error occurred, most often in response to a request
296    /// to that object.  The code identifies the error and is defined
297    /// by the object interface.  As such, each interface defines its
298    /// own set of error codes.  The message is a brief description
299    /// of the error, for (debugging) convenience.
300    ///
301    /// # Arguments
302    ///
303    /// - `object_id`: object where the error occurred
304    /// - `code`: error code
305    /// - `message`: error description
306    ///
307    /// All borrowed proxies passed to this function are guaranteed to be
308    /// immutable and non-null.
309    #[inline]
310    fn error(
311        &self,
312        _data: &mut Self::Data,
313        _slf: &WlDisplayRef,
314        object_id: Option<&UntypedBorrowedProxy>,
315        code: u32,
316        message: &str,
317    ) {
318        let _ = object_id;
319        let _ = code;
320        let _ = message;
321    }
322
323    /// acknowledge object ID deletion
324    ///
325    /// This event is used internally by the object ID management
326    /// logic. When a client deletes an object that it had created,
327    /// the server will send this event to acknowledge that it has
328    /// seen the delete request. When the client receives this event,
329    /// it will know that it can safely reuse the object ID.
330    ///
331    /// # Arguments
332    ///
333    /// - `id`: deleted object ID
334    #[inline]
335    fn delete_id(&self, _data: &mut Self::Data, _slf: &WlDisplayRef, id: u32) {
336        let _ = id;
337    }
338}
339
340impl WlDisplayEventHandler for private::NoOpEventHandler {
341    type Data = ();
342}
343
344// SAFETY: - INTERFACE is a valid wl_interface
345//         - mutable_type always returns the same value
346unsafe impl<H> EventHandler for private::EventHandler<H>
347where
348    H: WlDisplayEventHandler,
349{
350    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
351
352    #[inline]
353    fn mutable_type() -> Option<(TypeId, &'static str)> {
354        let id = TypeId::of::<H::Data>();
355        let name = std::any::type_name::<H::Data>();
356        Some((id, name))
357    }
358
359    #[allow(unused_variables)]
360    unsafe fn handle_event(
361        &self,
362        queue: &Queue,
363        data: *mut u8,
364        slf: &UntypedBorrowedProxy,
365        opcode: u32,
366        args: *mut wl_argument,
367    ) {
368        // SAFETY: This function requires that slf has the interface INTERFACE
369        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlDisplayRef>(slf) };
370        // SAFETY: This function requires that data is `&mut T` where `T`
371        //         has the type id returned by `Self::mutable_type`, i.e.,
372        //         `T = H::Data`.
373        let data: &mut H::Data = unsafe { &mut *data.cast() };
374        match opcode {
375            0 => {
376                // SAFETY: INTERFACE requires that there are 3 arguments
377                let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
378                // SAFETY: - INTERFACE requires that args[0] contains an object
379                let arg0 = unsafe {
380                    if let Some(p) = NonNull::new(args[0].o.cast()) {
381                        Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
382                    } else {
383                        None
384                    }
385                };
386                let arg0 = arg0.as_ref();
387                // SAFETY: - INTERFACE requires that args[1] contains a uint
388                let arg1 = unsafe { args[1].u };
389                // SAFETY: - INTERFACE requires that args[2] contains a string
390                //         - if the pointer is not null, then it is a c string
391                let arg2 = unsafe { convert_string_arg("wl_display", "message", args[2].s) };
392                self.0.error(data, slf, arg0, arg1, arg2);
393            }
394            1 => {
395                // SAFETY: INTERFACE requires that there are 1 arguments
396                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
397                // SAFETY: - INTERFACE requires that args[0] contains a uint
398                let arg0 = unsafe { args[0].u };
399                self.0.delete_id(data, slf, arg0);
400            }
401            _ => {
402                invalid_opcode("wl_display", opcode);
403            }
404        }
405    }
406}
407
408impl<H> CreateEventHandler<H> for private::ProxyApi
409where
410    H: WlDisplayEventHandler,
411{
412    type EventHandler = private::EventHandler<H>;
413
414    #[inline]
415    fn create_event_handler(handler: H) -> Self::EventHandler {
416        private::EventHandler(handler)
417    }
418}
419
420impl WlDisplay {
421    /// Since when the error.invalid_object enum variant is available.
422    #[allow(dead_code)]
423    pub const ENM__ERROR_INVALID_OBJECT__SINCE: u32 = 1;
424    /// Since when the error.invalid_method enum variant is available.
425    #[allow(dead_code)]
426    pub const ENM__ERROR_INVALID_METHOD__SINCE: u32 = 1;
427    /// Since when the error.no_memory enum variant is available.
428    #[allow(dead_code)]
429    pub const ENM__ERROR_NO_MEMORY__SINCE: u32 = 1;
430    /// Since when the error.implementation enum variant is available.
431    #[allow(dead_code)]
432    pub const ENM__ERROR_IMPLEMENTATION__SINCE: u32 = 1;
433}
434
435/// global error values
436///
437/// These errors are global and can be emitted in response to any
438/// server request.
439#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
440#[allow(dead_code)]
441pub struct WlDisplayError(pub u32);
442
443impl WlDisplayError {
444    /// server couldn't find object
445    #[allow(dead_code)]
446    pub const INVALID_OBJECT: Self = Self(0);
447
448    /// method doesn't exist on the specified interface or malformed request
449    #[allow(dead_code)]
450    pub const INVALID_METHOD: Self = Self(1);
451
452    /// server is out of memory
453    #[allow(dead_code)]
454    pub const NO_MEMORY: Self = Self(2);
455
456    /// implementation error in compositor
457    #[allow(dead_code)]
458    pub const IMPLEMENTATION: Self = Self(3);
459}
460
461impl Debug for WlDisplayError {
462    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
463        let name = match *self {
464            Self::INVALID_OBJECT => "INVALID_OBJECT",
465            Self::INVALID_METHOD => "INVALID_METHOD",
466            Self::NO_MEMORY => "NO_MEMORY",
467            Self::IMPLEMENTATION => "IMPLEMENTATION",
468            _ => return Debug::fmt(&self.0, f),
469        };
470        f.write_str(name)
471    }
472}
473
474/// Functional event handlers.
475pub mod event_handlers {
476    use super::*;
477
478    /// Event handler for error events.
479    pub struct Error<T, F>(F, PhantomData<fn(&mut T)>);
480    impl<T, F> WlDisplayEventHandler for Error<T, F>
481    where
482        T: 'static,
483        F: Fn(&mut T, &WlDisplayRef, Option<&UntypedBorrowedProxy>, u32, &str),
484    {
485        type Data = T;
486
487        #[inline]
488        fn error(
489            &self,
490            _data: &mut T,
491            _slf: &WlDisplayRef,
492            object_id: Option<&UntypedBorrowedProxy>,
493            code: u32,
494            message: &str,
495        ) {
496            self.0(_data, _slf, object_id, code, message)
497        }
498    }
499
500    /// Event handler for delete_id events.
501    pub struct DeleteId<T, F>(F, PhantomData<fn(&mut T)>);
502    impl<T, F> WlDisplayEventHandler for DeleteId<T, F>
503    where
504        T: 'static,
505        F: Fn(&mut T, &WlDisplayRef, u32),
506    {
507        type Data = T;
508
509        #[inline]
510        fn delete_id(&self, _data: &mut T, _slf: &WlDisplayRef, id: u32) {
511            self.0(_data, _slf, id)
512        }
513    }
514
515    impl WlDisplay {
516        /// Creates an event handler for error events.
517        ///
518        /// The event handler ignores all other events.
519        #[allow(dead_code)]
520        pub fn on_error<T, F>(f: F) -> Error<T, F>
521        where
522            T: 'static,
523            F: Fn(&mut T, &WlDisplayRef, Option<&UntypedBorrowedProxy>, u32, &str),
524        {
525            Error(f, PhantomData)
526        }
527
528        /// Creates an event handler for delete_id events.
529        ///
530        /// The event handler ignores all other events.
531        #[allow(dead_code)]
532        pub fn on_delete_id<T, F>(f: F) -> DeleteId<T, F>
533        where
534            T: 'static,
535            F: Fn(&mut T, &WlDisplayRef, u32),
536        {
537            DeleteId(f, PhantomData)
538        }
539    }
540}