wl_proxy/protocols/wayland/
wl_fixes.rs

1//! wayland protocol fixes
2//!
3//! This global fixes problems with other core-protocol interfaces that
4//! cannot be fixed in these interfaces themselves.
5
6use crate::protocol_helpers::prelude::*;
7use super::super::all_types::*;
8
9/// A wl_fixes object.
10///
11/// See the documentation of [the module][self] for the interface description.
12pub struct WlFixes {
13    core: ObjectCore,
14    handler: HandlerHolder<dyn WlFixesHandler>,
15}
16
17struct DefaultHandler;
18
19impl WlFixesHandler for DefaultHandler { }
20
21impl ConcreteObject for WlFixes {
22    const XML_VERSION: u32 = 1;
23    const INTERFACE: ObjectInterface = ObjectInterface::WlFixes;
24    const INTERFACE_NAME: &str = "wl_fixes";
25}
26
27impl WlFixes {
28    /// Sets a new handler.
29    pub fn set_handler(&self, handler: impl WlFixesHandler) {
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 WlFixesHandler>) {
35        if self.core.state.destroyed.get() {
36            return;
37        }
38        self.handler.set(Some(handler));
39    }
40}
41
42impl Debug for WlFixes {
43    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
44        f.debug_struct("WlFixes")
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 WlFixes {
53    /// Since when the destroy message is available.
54    pub const MSG__DESTROY__SINCE: u32 = 1;
55
56    /// destroys this object
57    #[inline]
58    pub fn try_send_destroy(
59        &self,
60    ) -> Result<(), ObjectError> {
61        let core = self.core();
62        let Some(id) = core.server_obj_id.get() else {
63            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
64        };
65        #[cfg(feature = "logging")]
66        if self.core.state.log {
67            #[cold]
68            fn log(state: &State, id: u32) {
69                let (millis, micros) = time_since_epoch();
70                let prefix = &state.log_prefix;
71                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_fixes#{}.destroy()\n", id);
72                state.log(args);
73            }
74            log(&self.core.state, id);
75        }
76        let Some(endpoint) = &self.core.state.server else {
77            return Ok(());
78        };
79        if !endpoint.flush_queued.replace(true) {
80            self.core.state.add_flushable_endpoint(endpoint, None);
81        }
82        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
83        let outgoing = &mut *outgoing_ref;
84        let mut fmt = outgoing.formatter();
85        fmt.words([
86            id,
87            0,
88        ]);
89        self.core.handle_server_destroy();
90        Ok(())
91    }
92
93    /// destroys this object
94    #[inline]
95    pub fn send_destroy(
96        &self,
97    ) {
98        let res = self.try_send_destroy(
99        );
100        if let Err(e) = res {
101            log_send("wl_fixes.destroy", &e);
102        }
103    }
104
105    /// Since when the destroy_registry message is available.
106    pub const MSG__DESTROY_REGISTRY__SINCE: u32 = 1;
107
108    /// destroy a wl_registry
109    ///
110    /// This request destroys a wl_registry object.
111    ///
112    /// The client should no longer use the wl_registry after making this
113    /// request.
114    ///
115    /// The compositor will emit a wl_display.delete_id event with the object ID
116    /// of the registry and will no longer emit any events on the registry. The
117    /// client should re-use the object ID once it receives the
118    /// wl_display.delete_id event.
119    ///
120    /// # Arguments
121    ///
122    /// - `registry`: the registry to destroy
123    #[inline]
124    pub fn try_send_destroy_registry(
125        &self,
126        registry: &Rc<WlRegistry>,
127    ) -> Result<(), ObjectError> {
128        let (
129            arg0,
130        ) = (
131            registry,
132        );
133        let arg0 = arg0.core();
134        let core = self.core();
135        let Some(id) = core.server_obj_id.get() else {
136            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
137        };
138        let arg0_id = match arg0.server_obj_id.get() {
139            None => return Err(ObjectError(ObjectErrorKind::ArgNoServerId("registry"))),
140            Some(id) => id,
141        };
142        #[cfg(feature = "logging")]
143        if self.core.state.log {
144            #[cold]
145            fn log(state: &State, id: u32, arg0: u32) {
146                let (millis, micros) = time_since_epoch();
147                let prefix = &state.log_prefix;
148                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_fixes#{}.destroy_registry(registry: wl_registry#{})\n", id, arg0);
149                state.log(args);
150            }
151            log(&self.core.state, id, arg0_id);
152        }
153        let Some(endpoint) = &self.core.state.server else {
154            return Ok(());
155        };
156        if !endpoint.flush_queued.replace(true) {
157            self.core.state.add_flushable_endpoint(endpoint, None);
158        }
159        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
160        let outgoing = &mut *outgoing_ref;
161        let mut fmt = outgoing.formatter();
162        fmt.words([
163            id,
164            1,
165            arg0_id,
166        ]);
167        arg0.handle_server_destroy();
168        Ok(())
169    }
170
171    /// destroy a wl_registry
172    ///
173    /// This request destroys a wl_registry object.
174    ///
175    /// The client should no longer use the wl_registry after making this
176    /// request.
177    ///
178    /// The compositor will emit a wl_display.delete_id event with the object ID
179    /// of the registry and will no longer emit any events on the registry. The
180    /// client should re-use the object ID once it receives the
181    /// wl_display.delete_id event.
182    ///
183    /// # Arguments
184    ///
185    /// - `registry`: the registry to destroy
186    #[inline]
187    pub fn send_destroy_registry(
188        &self,
189        registry: &Rc<WlRegistry>,
190    ) {
191        let res = self.try_send_destroy_registry(
192            registry,
193        );
194        if let Err(e) = res {
195            log_send("wl_fixes.destroy_registry", &e);
196        }
197    }
198}
199
200/// A message handler for [`WlFixes`] proxies.
201pub trait WlFixesHandler: Any {
202    /// Event handler for wl_display.delete_id messages deleting the ID of this object.
203    ///
204    /// The default handler forwards the event to the client, if any.
205    #[inline]
206    fn delete_id(&mut self, slf: &Rc<WlFixes>) {
207        slf.core.delete_id();
208    }
209
210    /// destroys this object
211    #[inline]
212    fn handle_destroy(
213        &mut self,
214        slf: &Rc<WlFixes>,
215    ) {
216        if !slf.core.forward_to_server.get() {
217            return;
218        }
219        let res = slf.try_send_destroy(
220        );
221        if let Err(e) = res {
222            log_forward("wl_fixes.destroy", &e);
223        }
224    }
225
226    /// destroy a wl_registry
227    ///
228    /// This request destroys a wl_registry object.
229    ///
230    /// The client should no longer use the wl_registry after making this
231    /// request.
232    ///
233    /// The compositor will emit a wl_display.delete_id event with the object ID
234    /// of the registry and will no longer emit any events on the registry. The
235    /// client should re-use the object ID once it receives the
236    /// wl_display.delete_id event.
237    ///
238    /// # Arguments
239    ///
240    /// - `registry`: the registry to destroy
241    ///
242    /// All borrowed proxies passed to this function are guaranteed to be
243    /// immutable and non-null.
244    #[inline]
245    fn handle_destroy_registry(
246        &mut self,
247        slf: &Rc<WlFixes>,
248        registry: &Rc<WlRegistry>,
249    ) {
250        if !slf.core.forward_to_server.get() {
251            return;
252        }
253        let res = slf.try_send_destroy_registry(
254            registry,
255        );
256        if let Err(e) = res {
257            log_forward("wl_fixes.destroy_registry", &e);
258        }
259    }
260}
261
262impl ObjectPrivate for WlFixes {
263    fn new(state: &Rc<State>, version: u32) -> Rc<Self> {
264        Rc::<Self>::new_cyclic(|slf| Self {
265            core: ObjectCore::new(state, slf.clone(), ObjectInterface::WlFixes, version),
266            handler: Default::default(),
267        })
268    }
269
270    fn delete_id(self: Rc<Self>) -> Result<(), (ObjectError, Rc<dyn Object>)> {
271        let Some(mut handler) = self.handler.try_borrow_mut() else {
272            return Err((ObjectError(ObjectErrorKind::HandlerBorrowed), self));
273        };
274        if let Some(handler) = &mut *handler {
275            handler.delete_id(&self);
276        } else {
277            self.core.delete_id();
278        }
279        Ok(())
280    }
281
282    fn handle_request(self: Rc<Self>, client: &Rc<Client>, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
283        let Some(mut handler) = self.handler.try_borrow_mut() else {
284            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
285        };
286        let handler = &mut *handler;
287        match msg[1] & 0xffff {
288            0 => {
289                if msg.len() != 2 {
290                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 8)));
291                }
292                #[cfg(feature = "logging")]
293                if self.core.state.log {
294                    #[cold]
295                    fn log(state: &State, client_id: u64, id: u32) {
296                        let (millis, micros) = time_since_epoch();
297                        let prefix = &state.log_prefix;
298                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_fixes#{}.destroy()\n", client_id, id);
299                        state.log(args);
300                    }
301                    log(&self.core.state, client.endpoint.id, msg[0]);
302                }
303                self.core.handle_client_destroy();
304                if let Some(handler) = handler {
305                    (**handler).handle_destroy(&self);
306                } else {
307                    DefaultHandler.handle_destroy(&self);
308                }
309            }
310            1 => {
311                let [
312                    arg0,
313                ] = msg[2..] else {
314                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
315                };
316                #[cfg(feature = "logging")]
317                if self.core.state.log {
318                    #[cold]
319                    fn log(state: &State, client_id: u64, id: u32, arg0: u32) {
320                        let (millis, micros) = time_since_epoch();
321                        let prefix = &state.log_prefix;
322                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_fixes#{}.destroy_registry(registry: wl_registry#{})\n", client_id, id, arg0);
323                        state.log(args);
324                    }
325                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
326                }
327                let arg0_id = arg0;
328                let Some(arg0) = client.endpoint.lookup(arg0_id) else {
329                    return Err(ObjectError(ObjectErrorKind::NoClientObject(client.endpoint.id, arg0_id)));
330                };
331                let Ok(arg0) = (arg0 as Rc<dyn Any>).downcast::<WlRegistry>() else {
332                    let o = client.endpoint.lookup(arg0_id).unwrap();
333                    return Err(ObjectError(ObjectErrorKind::WrongObjectType("registry", o.core().interface, ObjectInterface::WlRegistry)));
334                };
335                let arg0 = &arg0;
336                arg0.core().handle_client_destroy();
337                if let Some(handler) = handler {
338                    (**handler).handle_destroy_registry(&self, arg0);
339                } else {
340                    DefaultHandler.handle_destroy_registry(&self, arg0);
341                }
342            }
343            n => {
344                let _ = client;
345                let _ = msg;
346                let _ = fds;
347                let _ = handler;
348                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
349            }
350        }
351        Ok(())
352    }
353
354    fn handle_event(self: Rc<Self>, server: &Endpoint, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
355        let Some(mut handler) = self.handler.try_borrow_mut() else {
356            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
357        };
358        let handler = &mut *handler;
359        match msg[1] & 0xffff {
360            n => {
361                let _ = server;
362                let _ = msg;
363                let _ = fds;
364                let _ = handler;
365                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
366            }
367        }
368    }
369
370    fn get_request_name(&self, id: u32) -> Option<&'static str> {
371        let name = match id {
372            0 => "destroy",
373            1 => "destroy_registry",
374            _ => return None,
375        };
376        Some(name)
377    }
378
379    fn get_event_name(&self, id: u32) -> Option<&'static str> {
380        let _ = id;
381        None
382    }
383}
384
385impl Object for WlFixes {
386    fn core(&self) -> &ObjectCore {
387        &self.core
388    }
389
390    fn unset_handler(&self) {
391        self.handler.set(None);
392    }
393
394    fn get_handler_any_ref(&self) -> Result<HandlerRef<'_, dyn Any>, HandlerAccessError> {
395        let borrowed = self.handler.try_borrow().ok_or(HandlerAccessError::AlreadyBorrowed)?;
396        if borrowed.is_none() {
397            return Err(HandlerAccessError::NoHandler);
398        }
399        Ok(HandlerRef::map(borrowed, |handler| &**handler.as_ref().unwrap() as &dyn Any))
400    }
401
402    fn get_handler_any_mut(&self) -> Result<HandlerMut<'_, dyn Any>, HandlerAccessError> {
403        let borrowed = self.handler.try_borrow_mut().ok_or(HandlerAccessError::AlreadyBorrowed)?;
404        if borrowed.is_none() {
405            return Err(HandlerAccessError::NoHandler);
406        }
407        Ok(HandlerMut::map(borrowed, |handler| &mut **handler.as_mut().unwrap() as &mut dyn Any))
408    }
409}
410