wl_proxy/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 crate::protocol_helpers::prelude::*;
7use super::super::all_types::*;
8
9/// A wl_display object.
10///
11/// See the documentation of [the module][self] for the interface description.
12pub struct WlDisplay {
13    core: ObjectCore,
14    handler: HandlerHolder<dyn WlDisplayHandler>,
15}
16
17struct DefaultHandler;
18
19impl WlDisplayHandler for DefaultHandler { }
20
21impl ConcreteObject for WlDisplay {
22    const XML_VERSION: u32 = 1;
23    const INTERFACE: ObjectInterface = ObjectInterface::WlDisplay;
24    const INTERFACE_NAME: &str = "wl_display";
25}
26
27impl WlDisplay {
28    /// Sets a new handler.
29    pub fn set_handler(&self, handler: impl WlDisplayHandler) {
30        self.set_boxed_handler(Box::new(handler));
31    }
32
33    /// Sets a new, already boxed handler.
34    pub fn set_boxed_handler(&self, handler: Box<dyn WlDisplayHandler>) {
35        if self.core.state.destroyed.get() {
36            return;
37        }
38        self.handler.set(Some(handler));
39    }
40}
41
42impl Debug for WlDisplay {
43    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
44        f.debug_struct("WlDisplay")
45            .field("server_obj_id", &self.core.server_obj_id.get())
46            .field("client_id", &self.core.client_id.get())
47            .field("client_obj_id", &self.core.client_obj_id.get())
48            .finish()
49    }
50}
51
52impl WlDisplay {
53    /// Since when the sync message is available.
54    pub const MSG__SYNC__SINCE: u32 = 1;
55
56    /// asynchronous roundtrip
57    ///
58    /// The sync request asks the server to emit the 'done' event
59    /// on the returned wl_callback object.  Since requests are
60    /// handled in-order and events are delivered in-order, this can
61    /// be used as a barrier to ensure all previous requests and the
62    /// resulting events have been handled.
63    ///
64    /// The object returned by this request will be destroyed by the
65    /// compositor after the callback is fired and as such the client must not
66    /// attempt to use it after that point.
67    ///
68    /// The callback_data passed in the callback is undefined and should be ignored.
69    ///
70    /// # Arguments
71    ///
72    /// - `callback`: callback object for the sync request
73    #[inline]
74    pub fn try_send_sync(
75        &self,
76        callback: &Rc<WlCallback>,
77    ) -> Result<(), ObjectError> {
78        let (
79            arg0,
80        ) = (
81            callback,
82        );
83        let arg0_obj = arg0;
84        let arg0 = arg0_obj.core();
85        let core = self.core();
86        let Some(id) = core.server_obj_id.get() else {
87            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
88        };
89        arg0.generate_server_id(arg0_obj.clone())
90            .map_err(|e| ObjectError(ObjectErrorKind::GenerateServerId("callback", e)))?;
91        let arg0_id = arg0.server_obj_id.get().unwrap_or(0);
92        #[cfg(feature = "logging")]
93        if self.core.state.log {
94            #[cold]
95            fn log(state: &State, id: u32, arg0: u32) {
96                let (millis, micros) = time_since_epoch();
97                let prefix = &state.log_prefix;
98                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_display#{}.sync(callback: wl_callback#{})\n", id, arg0);
99                state.log(args);
100            }
101            log(&self.core.state, id, arg0_id);
102        }
103        let Some(endpoint) = &self.core.state.server else {
104            return Ok(());
105        };
106        if !endpoint.flush_queued.replace(true) {
107            self.core.state.add_flushable_endpoint(endpoint, None);
108        }
109        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
110        let outgoing = &mut *outgoing_ref;
111        let mut fmt = outgoing.formatter();
112        fmt.words([
113            id,
114            0,
115            arg0_id,
116        ]);
117        Ok(())
118    }
119
120    /// asynchronous roundtrip
121    ///
122    /// The sync request asks the server to emit the 'done' event
123    /// on the returned wl_callback object.  Since requests are
124    /// handled in-order and events are delivered in-order, this can
125    /// be used as a barrier to ensure all previous requests and the
126    /// resulting events have been handled.
127    ///
128    /// The object returned by this request will be destroyed by the
129    /// compositor after the callback is fired and as such the client must not
130    /// attempt to use it after that point.
131    ///
132    /// The callback_data passed in the callback is undefined and should be ignored.
133    ///
134    /// # Arguments
135    ///
136    /// - `callback`: callback object for the sync request
137    #[inline]
138    pub fn send_sync(
139        &self,
140        callback: &Rc<WlCallback>,
141    ) {
142        let res = self.try_send_sync(
143            callback,
144        );
145        if let Err(e) = res {
146            log_send("wl_display.sync", &e);
147        }
148    }
149
150    /// asynchronous roundtrip
151    ///
152    /// The sync request asks the server to emit the 'done' event
153    /// on the returned wl_callback object.  Since requests are
154    /// handled in-order and events are delivered in-order, this can
155    /// be used as a barrier to ensure all previous requests and the
156    /// resulting events have been handled.
157    ///
158    /// The object returned by this request will be destroyed by the
159    /// compositor after the callback is fired and as such the client must not
160    /// attempt to use it after that point.
161    ///
162    /// The callback_data passed in the callback is undefined and should be ignored.
163    #[inline]
164    pub fn new_try_send_sync(
165        &self,
166    ) -> Result<Rc<WlCallback>, ObjectError> {
167        let callback = self.core.create_child();
168        self.try_send_sync(
169            &callback,
170        )?;
171        Ok(callback)
172    }
173
174    /// asynchronous roundtrip
175    ///
176    /// The sync request asks the server to emit the 'done' event
177    /// on the returned wl_callback object.  Since requests are
178    /// handled in-order and events are delivered in-order, this can
179    /// be used as a barrier to ensure all previous requests and the
180    /// resulting events have been handled.
181    ///
182    /// The object returned by this request will be destroyed by the
183    /// compositor after the callback is fired and as such the client must not
184    /// attempt to use it after that point.
185    ///
186    /// The callback_data passed in the callback is undefined and should be ignored.
187    #[inline]
188    pub fn new_send_sync(
189        &self,
190    ) -> Rc<WlCallback> {
191        let callback = self.core.create_child();
192        self.send_sync(
193            &callback,
194        );
195        callback
196    }
197
198    /// Since when the get_registry message is available.
199    pub const MSG__GET_REGISTRY__SINCE: u32 = 1;
200
201    /// get global registry object
202    ///
203    /// This request creates a registry object that allows the client
204    /// to list and bind the global objects available from the
205    /// compositor.
206    ///
207    /// It should be noted that the server side resources consumed in
208    /// response to a get_registry request can only be released when the
209    /// client disconnects, not when the client side proxy is destroyed.
210    /// Therefore, clients should invoke get_registry as infrequently as
211    /// possible to avoid wasting memory.
212    ///
213    /// # Arguments
214    ///
215    /// - `registry`: global registry object
216    #[inline]
217    pub fn try_send_get_registry(
218        &self,
219        registry: &Rc<WlRegistry>,
220    ) -> Result<(), ObjectError> {
221        let (
222            arg0,
223        ) = (
224            registry,
225        );
226        let arg0_obj = arg0;
227        let arg0 = arg0_obj.core();
228        let core = self.core();
229        let Some(id) = core.server_obj_id.get() else {
230            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
231        };
232        arg0.generate_server_id(arg0_obj.clone())
233            .map_err(|e| ObjectError(ObjectErrorKind::GenerateServerId("registry", e)))?;
234        let arg0_id = arg0.server_obj_id.get().unwrap_or(0);
235        #[cfg(feature = "logging")]
236        if self.core.state.log {
237            #[cold]
238            fn log(state: &State, id: u32, arg0: u32) {
239                let (millis, micros) = time_since_epoch();
240                let prefix = &state.log_prefix;
241                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_display#{}.get_registry(registry: wl_registry#{})\n", id, arg0);
242                state.log(args);
243            }
244            log(&self.core.state, id, arg0_id);
245        }
246        let Some(endpoint) = &self.core.state.server else {
247            return Ok(());
248        };
249        if !endpoint.flush_queued.replace(true) {
250            self.core.state.add_flushable_endpoint(endpoint, None);
251        }
252        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
253        let outgoing = &mut *outgoing_ref;
254        let mut fmt = outgoing.formatter();
255        fmt.words([
256            id,
257            1,
258            arg0_id,
259        ]);
260        Ok(())
261    }
262
263    /// get global registry object
264    ///
265    /// This request creates a registry object that allows the client
266    /// to list and bind the global objects available from the
267    /// compositor.
268    ///
269    /// It should be noted that the server side resources consumed in
270    /// response to a get_registry request can only be released when the
271    /// client disconnects, not when the client side proxy is destroyed.
272    /// Therefore, clients should invoke get_registry as infrequently as
273    /// possible to avoid wasting memory.
274    ///
275    /// # Arguments
276    ///
277    /// - `registry`: global registry object
278    #[inline]
279    pub fn send_get_registry(
280        &self,
281        registry: &Rc<WlRegistry>,
282    ) {
283        let res = self.try_send_get_registry(
284            registry,
285        );
286        if let Err(e) = res {
287            log_send("wl_display.get_registry", &e);
288        }
289    }
290
291    /// get global registry object
292    ///
293    /// This request creates a registry object that allows the client
294    /// to list and bind the global objects available from the
295    /// compositor.
296    ///
297    /// It should be noted that the server side resources consumed in
298    /// response to a get_registry request can only be released when the
299    /// client disconnects, not when the client side proxy is destroyed.
300    /// Therefore, clients should invoke get_registry as infrequently as
301    /// possible to avoid wasting memory.
302    #[inline]
303    pub fn new_try_send_get_registry(
304        &self,
305    ) -> Result<Rc<WlRegistry>, ObjectError> {
306        let registry = self.core.create_child();
307        self.try_send_get_registry(
308            &registry,
309        )?;
310        Ok(registry)
311    }
312
313    /// get global registry object
314    ///
315    /// This request creates a registry object that allows the client
316    /// to list and bind the global objects available from the
317    /// compositor.
318    ///
319    /// It should be noted that the server side resources consumed in
320    /// response to a get_registry request can only be released when the
321    /// client disconnects, not when the client side proxy is destroyed.
322    /// Therefore, clients should invoke get_registry as infrequently as
323    /// possible to avoid wasting memory.
324    #[inline]
325    pub fn new_send_get_registry(
326        &self,
327    ) -> Rc<WlRegistry> {
328        let registry = self.core.create_child();
329        self.send_get_registry(
330            &registry,
331        );
332        registry
333    }
334
335    /// Since when the error message is available.
336    pub const MSG__ERROR__SINCE: u32 = 1;
337
338    /// fatal error event
339    ///
340    /// The error event is sent out when a fatal (non-recoverable)
341    /// error has occurred.  The object_id argument is the object
342    /// where the error occurred, most often in response to a request
343    /// to that object.  The code identifies the error and is defined
344    /// by the object interface.  As such, each interface defines its
345    /// own set of error codes.  The message is a brief description
346    /// of the error, for (debugging) convenience.
347    ///
348    /// # Arguments
349    ///
350    /// - `object_id`: object where the error occurred
351    /// - `code`: error code
352    /// - `message`: error description
353    #[inline]
354    pub fn try_send_error(
355        &self,
356        object_id: Rc<dyn Object>,
357        code: u32,
358        message: &str,
359    ) -> Result<(), ObjectError> {
360        let (
361            arg0,
362            arg1,
363            arg2,
364        ) = (
365            object_id,
366            code,
367            message,
368        );
369        let arg0 = arg0.core();
370        let core = self.core();
371        let client_ref = core.client.borrow();
372        let Some(client) = &*client_ref else {
373            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
374        };
375        let id = core.client_obj_id.get().unwrap_or(0);
376        if arg0.client_id.get() != Some(client.endpoint.id) {
377            return Err(ObjectError(ObjectErrorKind::ArgNoClientId("object_id", client.endpoint.id)));
378        }
379        let arg0_id = arg0.client_obj_id.get().unwrap_or(0);
380        #[cfg(feature = "logging")]
381        if self.core.state.log {
382            #[cold]
383            fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: u32, arg2: &str) {
384                let (millis, micros) = time_since_epoch();
385                let prefix = &state.log_prefix;
386                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_display#{}.error(object_id: unknown#{}, code: {}, message: {:?})\n", client_id, id, arg0, arg1, arg2);
387                state.log(args);
388            }
389            log(&self.core.state, client.endpoint.id, id, arg0_id, arg1, arg2);
390        }
391        let endpoint = &client.endpoint;
392        if !endpoint.flush_queued.replace(true) {
393            self.core.state.add_flushable_endpoint(endpoint, Some(client));
394        }
395        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
396        let outgoing = &mut *outgoing_ref;
397        let mut fmt = outgoing.formatter();
398        fmt.words([
399            id,
400            0,
401            arg0_id,
402            arg1,
403        ]);
404        fmt.string(arg2);
405        Ok(())
406    }
407
408    /// fatal error event
409    ///
410    /// The error event is sent out when a fatal (non-recoverable)
411    /// error has occurred.  The object_id argument is the object
412    /// where the error occurred, most often in response to a request
413    /// to that object.  The code identifies the error and is defined
414    /// by the object interface.  As such, each interface defines its
415    /// own set of error codes.  The message is a brief description
416    /// of the error, for (debugging) convenience.
417    ///
418    /// # Arguments
419    ///
420    /// - `object_id`: object where the error occurred
421    /// - `code`: error code
422    /// - `message`: error description
423    #[inline]
424    pub fn send_error(
425        &self,
426        object_id: Rc<dyn Object>,
427        code: u32,
428        message: &str,
429    ) {
430        let res = self.try_send_error(
431            object_id,
432            code,
433            message,
434        );
435        if let Err(e) = res {
436            log_send("wl_display.error", &e);
437        }
438    }
439
440    /// Since when the delete_id message is available.
441    pub const MSG__DELETE_ID__SINCE: u32 = 1;
442
443    /// acknowledge object ID deletion
444    ///
445    /// This event is used internally by the object ID management
446    /// logic. When a client deletes an object that it had created,
447    /// the server will send this event to acknowledge that it has
448    /// seen the delete request. When the client receives this event,
449    /// it will know that it can safely reuse the object ID.
450    ///
451    /// # Arguments
452    ///
453    /// - `id`: deleted object ID
454    #[inline]
455    pub fn try_send_delete_id(
456        &self,
457        id: u32,
458    ) -> Result<(), ObjectError> {
459        let (
460            arg0,
461        ) = (
462            id,
463        );
464        let core = self.core();
465        let client_ref = core.client.borrow();
466        let Some(client) = &*client_ref else {
467            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
468        };
469        let id = core.client_obj_id.get().unwrap_or(0);
470        #[cfg(feature = "logging")]
471        if self.core.state.log {
472            #[cold]
473            fn log(state: &State, client_id: u64, id: u32, arg0: u32) {
474                let (millis, micros) = time_since_epoch();
475                let prefix = &state.log_prefix;
476                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_display#{}.delete_id(id: {})\n", client_id, id, arg0);
477                state.log(args);
478            }
479            log(&self.core.state, client.endpoint.id, id, arg0);
480        }
481        let endpoint = &client.endpoint;
482        if !endpoint.flush_queued.replace(true) {
483            self.core.state.add_flushable_endpoint(endpoint, Some(client));
484        }
485        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
486        let outgoing = &mut *outgoing_ref;
487        let mut fmt = outgoing.formatter();
488        fmt.words([
489            id,
490            1,
491            arg0,
492        ]);
493        Ok(())
494    }
495
496    /// acknowledge object ID deletion
497    ///
498    /// This event is used internally by the object ID management
499    /// logic. When a client deletes an object that it had created,
500    /// the server will send this event to acknowledge that it has
501    /// seen the delete request. When the client receives this event,
502    /// it will know that it can safely reuse the object ID.
503    ///
504    /// # Arguments
505    ///
506    /// - `id`: deleted object ID
507    #[inline]
508    pub fn send_delete_id(
509        &self,
510        id: u32,
511    ) {
512        let res = self.try_send_delete_id(
513            id,
514        );
515        if let Err(e) = res {
516            log_send("wl_display.delete_id", &e);
517        }
518    }
519}
520
521/// A message handler for [`WlDisplay`] proxies.
522pub trait WlDisplayHandler: Any {
523    /// Event handler for wl_display.delete_id messages deleting the ID of this object.
524    ///
525    /// The default handler forwards the event to the client, if any.
526    #[inline]
527    fn delete_id(&mut self, slf: &Rc<WlDisplay>) {
528        slf.core.delete_id();
529    }
530
531    /// asynchronous roundtrip
532    ///
533    /// The sync request asks the server to emit the 'done' event
534    /// on the returned wl_callback object.  Since requests are
535    /// handled in-order and events are delivered in-order, this can
536    /// be used as a barrier to ensure all previous requests and the
537    /// resulting events have been handled.
538    ///
539    /// The object returned by this request will be destroyed by the
540    /// compositor after the callback is fired and as such the client must not
541    /// attempt to use it after that point.
542    ///
543    /// The callback_data passed in the callback is undefined and should be ignored.
544    ///
545    /// # Arguments
546    ///
547    /// - `callback`: callback object for the sync request
548    #[inline]
549    fn handle_sync(
550        &mut self,
551        slf: &Rc<WlDisplay>,
552        callback: &Rc<WlCallback>,
553    ) {
554        if !slf.core.forward_to_server.get() {
555            return;
556        }
557        let res = slf.try_send_sync(
558            callback,
559        );
560        if let Err(e) = res {
561            log_forward("wl_display.sync", &e);
562        }
563    }
564
565    /// get global registry object
566    ///
567    /// This request creates a registry object that allows the client
568    /// to list and bind the global objects available from the
569    /// compositor.
570    ///
571    /// It should be noted that the server side resources consumed in
572    /// response to a get_registry request can only be released when the
573    /// client disconnects, not when the client side proxy is destroyed.
574    /// Therefore, clients should invoke get_registry as infrequently as
575    /// possible to avoid wasting memory.
576    ///
577    /// # Arguments
578    ///
579    /// - `registry`: global registry object
580    #[inline]
581    fn handle_get_registry(
582        &mut self,
583        slf: &Rc<WlDisplay>,
584        registry: &Rc<WlRegistry>,
585    ) {
586        if !slf.core.forward_to_server.get() {
587            return;
588        }
589        let res = slf.try_send_get_registry(
590            registry,
591        );
592        if let Err(e) = res {
593            log_forward("wl_display.get_registry", &e);
594        }
595    }
596}
597
598impl ObjectPrivate for WlDisplay {
599    fn new(state: &Rc<State>, version: u32) -> Rc<Self> {
600        Rc::<Self>::new_cyclic(|slf| Self {
601            core: ObjectCore::new(state, slf.clone(), ObjectInterface::WlDisplay, version),
602            handler: Default::default(),
603        })
604    }
605
606    fn delete_id(self: Rc<Self>) -> Result<(), (ObjectError, Rc<dyn Object>)> {
607        let Some(mut handler) = self.handler.try_borrow_mut() else {
608            return Err((ObjectError(ObjectErrorKind::HandlerBorrowed), self));
609        };
610        if let Some(handler) = &mut *handler {
611            handler.delete_id(&self);
612        } else {
613            self.core.delete_id();
614        }
615        Ok(())
616    }
617
618    fn handle_request(self: Rc<Self>, client: &Rc<Client>, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
619        let Some(mut handler) = self.handler.try_borrow_mut() else {
620            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
621        };
622        let handler = &mut *handler;
623        match msg[1] & 0xffff {
624            0 => {
625                let [
626                    arg0,
627                ] = msg[2..] else {
628                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
629                };
630                #[cfg(feature = "logging")]
631                if self.core.state.log {
632                    #[cold]
633                    fn log(state: &State, client_id: u64, id: u32, arg0: u32) {
634                        let (millis, micros) = time_since_epoch();
635                        let prefix = &state.log_prefix;
636                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_display#{}.sync(callback: wl_callback#{})\n", client_id, id, arg0);
637                        state.log(args);
638                    }
639                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
640                }
641                let arg0_id = arg0;
642                let arg0 = WlCallback::new(&self.core.state, self.core.version);
643                arg0.core().set_client_id(client, arg0_id, arg0.clone())
644                    .map_err(|e| ObjectError(ObjectErrorKind::SetClientId(arg0_id, "callback", e)))?;
645                let arg0 = &arg0;
646                if let Some(handler) = handler {
647                    (**handler).handle_sync(&self, arg0);
648                } else {
649                    DefaultHandler.handle_sync(&self, arg0);
650                }
651            }
652            1 => {
653                let [
654                    arg0,
655                ] = msg[2..] else {
656                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
657                };
658                #[cfg(feature = "logging")]
659                if self.core.state.log {
660                    #[cold]
661                    fn log(state: &State, client_id: u64, id: u32, arg0: u32) {
662                        let (millis, micros) = time_since_epoch();
663                        let prefix = &state.log_prefix;
664                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_display#{}.get_registry(registry: wl_registry#{})\n", client_id, id, arg0);
665                        state.log(args);
666                    }
667                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
668                }
669                let arg0_id = arg0;
670                let arg0 = WlRegistry::new(&self.core.state, self.core.version);
671                arg0.core().set_client_id(client, arg0_id, arg0.clone())
672                    .map_err(|e| ObjectError(ObjectErrorKind::SetClientId(arg0_id, "registry", e)))?;
673                let arg0 = &arg0;
674                if let Some(handler) = handler {
675                    (**handler).handle_get_registry(&self, arg0);
676                } else {
677                    DefaultHandler.handle_get_registry(&self, arg0);
678                }
679            }
680            n => {
681                let _ = client;
682                let _ = msg;
683                let _ = fds;
684                let _ = handler;
685                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
686            }
687        }
688        Ok(())
689    }
690
691    fn handle_event(self: Rc<Self>, server: &Endpoint, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
692        let Some(mut handler) = self.handler.try_borrow_mut() else {
693            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
694        };
695        let handler = &mut *handler;
696        match msg[1] & 0xffff {
697            0 => {
698                let mut offset = 2;
699                let Some(&arg0) = msg.get(offset) else {
700                    return Err(ObjectError(ObjectErrorKind::MissingArgument("object_id")));
701                };
702                offset += 1;
703                let Some(&arg1) = msg.get(offset) else {
704                    return Err(ObjectError(ObjectErrorKind::MissingArgument("code")));
705                };
706                offset += 1;
707                let arg2;
708                (arg2, offset) = parse_string::<NonNullString>(msg, offset, "message")?;
709                if offset != msg.len() {
710                    return Err(ObjectError(ObjectErrorKind::TrailingBytes));
711                }
712                #[cfg(feature = "logging")]
713                if self.core.state.log {
714                    #[cold]
715                    fn log(state: &State, id: u32, arg0: u32, arg1: u32, arg2: &str) {
716                        let (millis, micros) = time_since_epoch();
717                        let prefix = &state.log_prefix;
718                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_display#{}.error(object_id: unknown#{}, code: {}, message: {:?})\n", id, arg0, arg1, arg2);
719                        state.log(args);
720                    }
721                    log(&self.core.state, msg[0], arg0, arg1, arg2);
722                }
723                let arg0_id = arg0;
724                let Some(arg0) = server.lookup(arg0_id) else {
725                    return Err(ObjectError(ObjectErrorKind::NoServerObject(arg0_id)));
726                };
727                return Err(ObjectError(ObjectErrorKind::ServerError(arg0.core().interface, arg0_id, arg1, StringError(arg2.to_string()))));
728            }
729            1 => {
730                let [
731                    arg0,
732                ] = msg[2..] else {
733                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
734                };
735                #[cfg(feature = "logging")]
736                if self.core.state.log {
737                    #[cold]
738                    fn log(state: &State, id: u32, arg0: u32) {
739                        let (millis, micros) = time_since_epoch();
740                        let prefix = &state.log_prefix;
741                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_display#{}.delete_id(id: {})\n", id, arg0);
742                        state.log(args);
743                    }
744                    log(&self.core.state, msg[0], arg0);
745                }
746                self.core.state.handle_delete_id(server, arg0);
747            }
748            n => {
749                let _ = server;
750                let _ = msg;
751                let _ = fds;
752                let _ = handler;
753                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
754            }
755        }
756        Ok(())
757    }
758
759    fn get_request_name(&self, id: u32) -> Option<&'static str> {
760        let name = match id {
761            0 => "sync",
762            1 => "get_registry",
763            _ => return None,
764        };
765        Some(name)
766    }
767
768    fn get_event_name(&self, id: u32) -> Option<&'static str> {
769        let name = match id {
770            0 => "error",
771            1 => "delete_id",
772            _ => return None,
773        };
774        Some(name)
775    }
776}
777
778impl Object for WlDisplay {
779    fn core(&self) -> &ObjectCore {
780        &self.core
781    }
782
783    fn unset_handler(&self) {
784        self.handler.set(None);
785    }
786
787    fn get_handler_any_ref(&self) -> Result<HandlerRef<'_, dyn Any>, HandlerAccessError> {
788        let borrowed = self.handler.try_borrow().ok_or(HandlerAccessError::AlreadyBorrowed)?;
789        if borrowed.is_none() {
790            return Err(HandlerAccessError::NoHandler);
791        }
792        Ok(HandlerRef::map(borrowed, |handler| &**handler.as_ref().unwrap() as &dyn Any))
793    }
794
795    fn get_handler_any_mut(&self) -> Result<HandlerMut<'_, dyn Any>, HandlerAccessError> {
796        let borrowed = self.handler.try_borrow_mut().ok_or(HandlerAccessError::AlreadyBorrowed)?;
797        if borrowed.is_none() {
798            return Err(HandlerAccessError::NoHandler);
799        }
800        Ok(HandlerMut::map(borrowed, |handler| &mut **handler.as_mut().unwrap() as &mut dyn Any))
801    }
802}
803
804impl WlDisplay {
805    /// Since when the error.invalid_object enum variant is available.
806    pub const ENM__ERROR_INVALID_OBJECT__SINCE: u32 = 1;
807    /// Since when the error.invalid_method enum variant is available.
808    pub const ENM__ERROR_INVALID_METHOD__SINCE: u32 = 1;
809    /// Since when the error.no_memory enum variant is available.
810    pub const ENM__ERROR_NO_MEMORY__SINCE: u32 = 1;
811    /// Since when the error.implementation enum variant is available.
812    pub const ENM__ERROR_IMPLEMENTATION__SINCE: u32 = 1;
813}
814
815/// global error values
816///
817/// These errors are global and can be emitted in response to any
818/// server request.
819#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
820pub struct WlDisplayError(pub u32);
821
822impl WlDisplayError {
823    /// server couldn't find object
824    pub const INVALID_OBJECT: Self = Self(0);
825
826    /// method doesn't exist on the specified interface or malformed request
827    pub const INVALID_METHOD: Self = Self(1);
828
829    /// server is out of memory
830    pub const NO_MEMORY: Self = Self(2);
831
832    /// implementation error in compositor
833    pub const IMPLEMENTATION: Self = Self(3);
834}
835
836impl Debug for WlDisplayError {
837    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
838        let name = match *self {
839            Self::INVALID_OBJECT => "INVALID_OBJECT",
840            Self::INVALID_METHOD => "INVALID_METHOD",
841            Self::NO_MEMORY => "NO_MEMORY",
842            Self::IMPLEMENTATION => "IMPLEMENTATION",
843            _ => return Debug::fmt(&self.0, f),
844        };
845        f.write_str(name)
846    }
847}