wl_proxy/protocols/wayland/
wl_data_source.rs

1//! offer to transfer data
2//!
3//! The wl_data_source object is the source side of a wl_data_offer.
4//! It is created by the source client in a data transfer and
5//! provides a way to describe the offered data and a way to respond
6//! to requests to transfer the data.
7
8use crate::protocol_helpers::prelude::*;
9use super::super::all_types::*;
10
11/// A wl_data_source object.
12///
13/// See the documentation of [the module][self] for the interface description.
14pub struct WlDataSource {
15    core: ObjectCore,
16    handler: HandlerHolder<dyn WlDataSourceHandler>,
17}
18
19struct DefaultHandler;
20
21impl WlDataSourceHandler for DefaultHandler { }
22
23impl ConcreteObject for WlDataSource {
24    const XML_VERSION: u32 = 3;
25    const INTERFACE: ObjectInterface = ObjectInterface::WlDataSource;
26    const INTERFACE_NAME: &str = "wl_data_source";
27}
28
29impl WlDataSource {
30    /// Sets a new handler.
31    pub fn set_handler(&self, handler: impl WlDataSourceHandler) {
32        self.set_boxed_handler(Box::new(handler));
33    }
34
35    /// Sets a new, already boxed handler.
36    pub fn set_boxed_handler(&self, handler: Box<dyn WlDataSourceHandler>) {
37        if self.core.state.destroyed.get() {
38            return;
39        }
40        self.handler.set(Some(handler));
41    }
42}
43
44impl Debug for WlDataSource {
45    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
46        f.debug_struct("WlDataSource")
47            .field("server_obj_id", &self.core.server_obj_id.get())
48            .field("client_id", &self.core.client_id.get())
49            .field("client_obj_id", &self.core.client_obj_id.get())
50            .finish()
51    }
52}
53
54impl WlDataSource {
55    /// Since when the offer message is available.
56    pub const MSG__OFFER__SINCE: u32 = 1;
57
58    /// add an offered mime type
59    ///
60    /// This request adds a mime type to the set of mime types
61    /// advertised to targets.  Can be called several times to offer
62    /// multiple types.
63    ///
64    /// # Arguments
65    ///
66    /// - `mime_type`: mime type offered by the data source
67    #[inline]
68    pub fn try_send_offer(
69        &self,
70        mime_type: &str,
71    ) -> Result<(), ObjectError> {
72        let (
73            arg0,
74        ) = (
75            mime_type,
76        );
77        let core = self.core();
78        let Some(id) = core.server_obj_id.get() else {
79            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
80        };
81        #[cfg(feature = "logging")]
82        if self.core.state.log {
83            #[cold]
84            fn log(state: &State, id: u32, arg0: &str) {
85                let (millis, micros) = time_since_epoch();
86                let prefix = &state.log_prefix;
87                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_data_source#{}.offer(mime_type: {:?})\n", id, arg0);
88                state.log(args);
89            }
90            log(&self.core.state, id, arg0);
91        }
92        let Some(endpoint) = &self.core.state.server else {
93            return Ok(());
94        };
95        if !endpoint.flush_queued.replace(true) {
96            self.core.state.add_flushable_endpoint(endpoint, None);
97        }
98        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
99        let outgoing = &mut *outgoing_ref;
100        let mut fmt = outgoing.formatter();
101        fmt.words([
102            id,
103            0,
104        ]);
105        fmt.string(arg0);
106        Ok(())
107    }
108
109    /// add an offered mime type
110    ///
111    /// This request adds a mime type to the set of mime types
112    /// advertised to targets.  Can be called several times to offer
113    /// multiple types.
114    ///
115    /// # Arguments
116    ///
117    /// - `mime_type`: mime type offered by the data source
118    #[inline]
119    pub fn send_offer(
120        &self,
121        mime_type: &str,
122    ) {
123        let res = self.try_send_offer(
124            mime_type,
125        );
126        if let Err(e) = res {
127            log_send("wl_data_source.offer", &e);
128        }
129    }
130
131    /// Since when the destroy message is available.
132    pub const MSG__DESTROY__SINCE: u32 = 1;
133
134    /// destroy the data source
135    ///
136    /// Destroy the data source.
137    #[inline]
138    pub fn try_send_destroy(
139        &self,
140    ) -> Result<(), ObjectError> {
141        let core = self.core();
142        let Some(id) = core.server_obj_id.get() else {
143            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
144        };
145        #[cfg(feature = "logging")]
146        if self.core.state.log {
147            #[cold]
148            fn log(state: &State, id: u32) {
149                let (millis, micros) = time_since_epoch();
150                let prefix = &state.log_prefix;
151                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_data_source#{}.destroy()\n", id);
152                state.log(args);
153            }
154            log(&self.core.state, id);
155        }
156        let Some(endpoint) = &self.core.state.server else {
157            return Ok(());
158        };
159        if !endpoint.flush_queued.replace(true) {
160            self.core.state.add_flushable_endpoint(endpoint, None);
161        }
162        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
163        let outgoing = &mut *outgoing_ref;
164        let mut fmt = outgoing.formatter();
165        fmt.words([
166            id,
167            1,
168        ]);
169        self.core.handle_server_destroy();
170        Ok(())
171    }
172
173    /// destroy the data source
174    ///
175    /// Destroy the data source.
176    #[inline]
177    pub fn send_destroy(
178        &self,
179    ) {
180        let res = self.try_send_destroy(
181        );
182        if let Err(e) = res {
183            log_send("wl_data_source.destroy", &e);
184        }
185    }
186
187    /// Since when the target message is available.
188    pub const MSG__TARGET__SINCE: u32 = 1;
189
190    /// a target accepts an offered mime type
191    ///
192    /// Sent when a target accepts pointer_focus or motion events.  If
193    /// a target does not accept any of the offered types, type is NULL.
194    ///
195    /// Used for feedback during drag-and-drop.
196    ///
197    /// # Arguments
198    ///
199    /// - `mime_type`: mime type accepted by the target
200    #[inline]
201    pub fn try_send_target(
202        &self,
203        mime_type: Option<&str>,
204    ) -> Result<(), ObjectError> {
205        let (
206            arg0,
207        ) = (
208            mime_type,
209        );
210        let core = self.core();
211        let client_ref = core.client.borrow();
212        let Some(client) = &*client_ref else {
213            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
214        };
215        let id = core.client_obj_id.get().unwrap_or(0);
216        #[cfg(feature = "logging")]
217        if self.core.state.log {
218            #[cold]
219            fn log(state: &State, client_id: u64, id: u32, arg0: Option<&str>) {
220                let (millis, micros) = time_since_epoch();
221                let prefix = &state.log_prefix;
222                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_data_source#{}.target(mime_type: {:?})\n", client_id, id, arg0);
223                state.log(args);
224            }
225            log(&self.core.state, client.endpoint.id, id, arg0);
226        }
227        let endpoint = &client.endpoint;
228        if !endpoint.flush_queued.replace(true) {
229            self.core.state.add_flushable_endpoint(endpoint, Some(client));
230        }
231        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
232        let outgoing = &mut *outgoing_ref;
233        let mut fmt = outgoing.formatter();
234        fmt.words([
235            id,
236            0,
237        ]);
238        if let Some(arg0) = arg0 {
239            fmt.string(arg0);
240        } else {
241            fmt.words([0]);
242        }
243        Ok(())
244    }
245
246    /// a target accepts an offered mime type
247    ///
248    /// Sent when a target accepts pointer_focus or motion events.  If
249    /// a target does not accept any of the offered types, type is NULL.
250    ///
251    /// Used for feedback during drag-and-drop.
252    ///
253    /// # Arguments
254    ///
255    /// - `mime_type`: mime type accepted by the target
256    #[inline]
257    pub fn send_target(
258        &self,
259        mime_type: Option<&str>,
260    ) {
261        let res = self.try_send_target(
262            mime_type,
263        );
264        if let Err(e) = res {
265            log_send("wl_data_source.target", &e);
266        }
267    }
268
269    /// Since when the send message is available.
270    pub const MSG__SEND__SINCE: u32 = 1;
271
272    /// send the data
273    ///
274    /// Request for data from the client.  Send the data as the
275    /// specified mime type over the passed file descriptor, then
276    /// close it.
277    ///
278    /// # Arguments
279    ///
280    /// - `mime_type`: mime type for the data
281    /// - `fd`: file descriptor for the data
282    #[inline]
283    pub fn try_send_send(
284        &self,
285        mime_type: &str,
286        fd: &Rc<OwnedFd>,
287    ) -> Result<(), ObjectError> {
288        let (
289            arg0,
290            arg1,
291        ) = (
292            mime_type,
293            fd,
294        );
295        let core = self.core();
296        let client_ref = core.client.borrow();
297        let Some(client) = &*client_ref else {
298            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
299        };
300        let id = core.client_obj_id.get().unwrap_or(0);
301        #[cfg(feature = "logging")]
302        if self.core.state.log {
303            #[cold]
304            fn log(state: &State, client_id: u64, id: u32, arg0: &str, arg1: i32) {
305                let (millis, micros) = time_since_epoch();
306                let prefix = &state.log_prefix;
307                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_data_source#{}.send(mime_type: {:?}, fd: {})\n", client_id, id, arg0, arg1);
308                state.log(args);
309            }
310            log(&self.core.state, client.endpoint.id, id, arg0, arg1.as_raw_fd());
311        }
312        let endpoint = &client.endpoint;
313        if !endpoint.flush_queued.replace(true) {
314            self.core.state.add_flushable_endpoint(endpoint, Some(client));
315        }
316        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
317        let outgoing = &mut *outgoing_ref;
318        let mut fmt = outgoing.formatter();
319        fmt.words([
320            id,
321            1,
322        ]);
323        fmt.string(arg0);
324        fmt.fds.push_back(arg1.clone());
325        Ok(())
326    }
327
328    /// send the data
329    ///
330    /// Request for data from the client.  Send the data as the
331    /// specified mime type over the passed file descriptor, then
332    /// close it.
333    ///
334    /// # Arguments
335    ///
336    /// - `mime_type`: mime type for the data
337    /// - `fd`: file descriptor for the data
338    #[inline]
339    pub fn send_send(
340        &self,
341        mime_type: &str,
342        fd: &Rc<OwnedFd>,
343    ) {
344        let res = self.try_send_send(
345            mime_type,
346            fd,
347        );
348        if let Err(e) = res {
349            log_send("wl_data_source.send", &e);
350        }
351    }
352
353    /// Since when the cancelled message is available.
354    pub const MSG__CANCELLED__SINCE: u32 = 1;
355
356    /// selection was cancelled
357    ///
358    /// This data source is no longer valid. There are several reasons why
359    /// this could happen:
360    ///
361    /// - The data source has been replaced by another data source.
362    /// - The drag-and-drop operation was performed, but the drop destination
363    ///   did not accept any of the mime types offered through
364    ///   wl_data_source.target.
365    /// - The drag-and-drop operation was performed, but the drop destination
366    ///   did not select any of the actions present in the mask offered through
367    ///   wl_data_source.action.
368    /// - The drag-and-drop operation was performed but didn't happen over a
369    ///   surface.
370    /// - The compositor cancelled the drag-and-drop operation (e.g. compositor
371    ///   dependent timeouts to avoid stale drag-and-drop transfers).
372    ///
373    /// The client should clean up and destroy this data source.
374    ///
375    /// For objects of version 2 or older, wl_data_source.cancelled will
376    /// only be emitted if the data source was replaced by another data
377    /// source.
378    #[inline]
379    pub fn try_send_cancelled(
380        &self,
381    ) -> Result<(), ObjectError> {
382        let core = self.core();
383        let client_ref = core.client.borrow();
384        let Some(client) = &*client_ref else {
385            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
386        };
387        let id = core.client_obj_id.get().unwrap_or(0);
388        #[cfg(feature = "logging")]
389        if self.core.state.log {
390            #[cold]
391            fn log(state: &State, client_id: u64, id: u32) {
392                let (millis, micros) = time_since_epoch();
393                let prefix = &state.log_prefix;
394                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_data_source#{}.cancelled()\n", client_id, id);
395                state.log(args);
396            }
397            log(&self.core.state, client.endpoint.id, id);
398        }
399        let endpoint = &client.endpoint;
400        if !endpoint.flush_queued.replace(true) {
401            self.core.state.add_flushable_endpoint(endpoint, Some(client));
402        }
403        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
404        let outgoing = &mut *outgoing_ref;
405        let mut fmt = outgoing.formatter();
406        fmt.words([
407            id,
408            2,
409        ]);
410        Ok(())
411    }
412
413    /// selection was cancelled
414    ///
415    /// This data source is no longer valid. There are several reasons why
416    /// this could happen:
417    ///
418    /// - The data source has been replaced by another data source.
419    /// - The drag-and-drop operation was performed, but the drop destination
420    ///   did not accept any of the mime types offered through
421    ///   wl_data_source.target.
422    /// - The drag-and-drop operation was performed, but the drop destination
423    ///   did not select any of the actions present in the mask offered through
424    ///   wl_data_source.action.
425    /// - The drag-and-drop operation was performed but didn't happen over a
426    ///   surface.
427    /// - The compositor cancelled the drag-and-drop operation (e.g. compositor
428    ///   dependent timeouts to avoid stale drag-and-drop transfers).
429    ///
430    /// The client should clean up and destroy this data source.
431    ///
432    /// For objects of version 2 or older, wl_data_source.cancelled will
433    /// only be emitted if the data source was replaced by another data
434    /// source.
435    #[inline]
436    pub fn send_cancelled(
437        &self,
438    ) {
439        let res = self.try_send_cancelled(
440        );
441        if let Err(e) = res {
442            log_send("wl_data_source.cancelled", &e);
443        }
444    }
445
446    /// Since when the set_actions message is available.
447    pub const MSG__SET_ACTIONS__SINCE: u32 = 3;
448
449    /// set the available drag-and-drop actions
450    ///
451    /// Sets the actions that the source side client supports for this
452    /// operation. This request may trigger wl_data_source.action and
453    /// wl_data_offer.action events if the compositor needs to change the
454    /// selected action.
455    ///
456    /// The dnd_actions argument must contain only values expressed in the
457    /// wl_data_device_manager.dnd_actions enum, otherwise it will result
458    /// in a protocol error.
459    ///
460    /// This request must be made once only, and can only be made on sources
461    /// used in drag-and-drop, so it must be performed before
462    /// wl_data_device.start_drag. Attempting to use the source other than
463    /// for drag-and-drop will raise a protocol error.
464    ///
465    /// # Arguments
466    ///
467    /// - `dnd_actions`: actions supported by the data source
468    #[inline]
469    pub fn try_send_set_actions(
470        &self,
471        dnd_actions: WlDataDeviceManagerDndAction,
472    ) -> Result<(), ObjectError> {
473        let (
474            arg0,
475        ) = (
476            dnd_actions,
477        );
478        let core = self.core();
479        let Some(id) = core.server_obj_id.get() else {
480            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
481        };
482        #[cfg(feature = "logging")]
483        if self.core.state.log {
484            #[cold]
485            fn log(state: &State, id: u32, arg0: WlDataDeviceManagerDndAction) {
486                let (millis, micros) = time_since_epoch();
487                let prefix = &state.log_prefix;
488                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_data_source#{}.set_actions(dnd_actions: {:?})\n", id, arg0);
489                state.log(args);
490            }
491            log(&self.core.state, id, arg0);
492        }
493        let Some(endpoint) = &self.core.state.server else {
494            return Ok(());
495        };
496        if !endpoint.flush_queued.replace(true) {
497            self.core.state.add_flushable_endpoint(endpoint, None);
498        }
499        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
500        let outgoing = &mut *outgoing_ref;
501        let mut fmt = outgoing.formatter();
502        fmt.words([
503            id,
504            2,
505            arg0.0,
506        ]);
507        Ok(())
508    }
509
510    /// set the available drag-and-drop actions
511    ///
512    /// Sets the actions that the source side client supports for this
513    /// operation. This request may trigger wl_data_source.action and
514    /// wl_data_offer.action events if the compositor needs to change the
515    /// selected action.
516    ///
517    /// The dnd_actions argument must contain only values expressed in the
518    /// wl_data_device_manager.dnd_actions enum, otherwise it will result
519    /// in a protocol error.
520    ///
521    /// This request must be made once only, and can only be made on sources
522    /// used in drag-and-drop, so it must be performed before
523    /// wl_data_device.start_drag. Attempting to use the source other than
524    /// for drag-and-drop will raise a protocol error.
525    ///
526    /// # Arguments
527    ///
528    /// - `dnd_actions`: actions supported by the data source
529    #[inline]
530    pub fn send_set_actions(
531        &self,
532        dnd_actions: WlDataDeviceManagerDndAction,
533    ) {
534        let res = self.try_send_set_actions(
535            dnd_actions,
536        );
537        if let Err(e) = res {
538            log_send("wl_data_source.set_actions", &e);
539        }
540    }
541
542    /// Since when the dnd_drop_performed message is available.
543    pub const MSG__DND_DROP_PERFORMED__SINCE: u32 = 3;
544
545    /// the drag-and-drop operation physically finished
546    ///
547    /// The user performed the drop action. This event does not indicate
548    /// acceptance, wl_data_source.cancelled may still be emitted afterwards
549    /// if the drop destination does not accept any mime type.
550    ///
551    /// However, this event might however not be received if the compositor
552    /// cancelled the drag-and-drop operation before this event could happen.
553    ///
554    /// Note that the data_source may still be used in the future and should
555    /// not be destroyed here.
556    #[inline]
557    pub fn try_send_dnd_drop_performed(
558        &self,
559    ) -> Result<(), ObjectError> {
560        let core = self.core();
561        let client_ref = core.client.borrow();
562        let Some(client) = &*client_ref else {
563            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
564        };
565        let id = core.client_obj_id.get().unwrap_or(0);
566        #[cfg(feature = "logging")]
567        if self.core.state.log {
568            #[cold]
569            fn log(state: &State, client_id: u64, id: u32) {
570                let (millis, micros) = time_since_epoch();
571                let prefix = &state.log_prefix;
572                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_data_source#{}.dnd_drop_performed()\n", client_id, id);
573                state.log(args);
574            }
575            log(&self.core.state, client.endpoint.id, id);
576        }
577        let endpoint = &client.endpoint;
578        if !endpoint.flush_queued.replace(true) {
579            self.core.state.add_flushable_endpoint(endpoint, Some(client));
580        }
581        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
582        let outgoing = &mut *outgoing_ref;
583        let mut fmt = outgoing.formatter();
584        fmt.words([
585            id,
586            3,
587        ]);
588        Ok(())
589    }
590
591    /// the drag-and-drop operation physically finished
592    ///
593    /// The user performed the drop action. This event does not indicate
594    /// acceptance, wl_data_source.cancelled may still be emitted afterwards
595    /// if the drop destination does not accept any mime type.
596    ///
597    /// However, this event might however not be received if the compositor
598    /// cancelled the drag-and-drop operation before this event could happen.
599    ///
600    /// Note that the data_source may still be used in the future and should
601    /// not be destroyed here.
602    #[inline]
603    pub fn send_dnd_drop_performed(
604        &self,
605    ) {
606        let res = self.try_send_dnd_drop_performed(
607        );
608        if let Err(e) = res {
609            log_send("wl_data_source.dnd_drop_performed", &e);
610        }
611    }
612
613    /// Since when the dnd_finished message is available.
614    pub const MSG__DND_FINISHED__SINCE: u32 = 3;
615
616    /// the drag-and-drop operation concluded
617    ///
618    /// The drop destination finished interoperating with this data
619    /// source, so the client is now free to destroy this data source and
620    /// free all associated data.
621    ///
622    /// If the action used to perform the operation was "move", the
623    /// source can now delete the transferred data.
624    #[inline]
625    pub fn try_send_dnd_finished(
626        &self,
627    ) -> Result<(), ObjectError> {
628        let core = self.core();
629        let client_ref = core.client.borrow();
630        let Some(client) = &*client_ref else {
631            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
632        };
633        let id = core.client_obj_id.get().unwrap_or(0);
634        #[cfg(feature = "logging")]
635        if self.core.state.log {
636            #[cold]
637            fn log(state: &State, client_id: u64, id: u32) {
638                let (millis, micros) = time_since_epoch();
639                let prefix = &state.log_prefix;
640                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_data_source#{}.dnd_finished()\n", client_id, id);
641                state.log(args);
642            }
643            log(&self.core.state, client.endpoint.id, id);
644        }
645        let endpoint = &client.endpoint;
646        if !endpoint.flush_queued.replace(true) {
647            self.core.state.add_flushable_endpoint(endpoint, Some(client));
648        }
649        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
650        let outgoing = &mut *outgoing_ref;
651        let mut fmt = outgoing.formatter();
652        fmt.words([
653            id,
654            4,
655        ]);
656        Ok(())
657    }
658
659    /// the drag-and-drop operation concluded
660    ///
661    /// The drop destination finished interoperating with this data
662    /// source, so the client is now free to destroy this data source and
663    /// free all associated data.
664    ///
665    /// If the action used to perform the operation was "move", the
666    /// source can now delete the transferred data.
667    #[inline]
668    pub fn send_dnd_finished(
669        &self,
670    ) {
671        let res = self.try_send_dnd_finished(
672        );
673        if let Err(e) = res {
674            log_send("wl_data_source.dnd_finished", &e);
675        }
676    }
677
678    /// Since when the action message is available.
679    pub const MSG__ACTION__SINCE: u32 = 3;
680
681    /// notify the selected action
682    ///
683    /// This event indicates the action selected by the compositor after
684    /// matching the source/destination side actions. Only one action (or
685    /// none) will be offered here.
686    ///
687    /// This event can be emitted multiple times during the drag-and-drop
688    /// operation, mainly in response to destination side changes through
689    /// wl_data_offer.set_actions, and as the data device enters/leaves
690    /// surfaces.
691    ///
692    /// It is only possible to receive this event after
693    /// wl_data_source.dnd_drop_performed if the drag-and-drop operation
694    /// ended in an "ask" action, in which case the final wl_data_source.action
695    /// event will happen immediately before wl_data_source.dnd_finished.
696    ///
697    /// Compositors may also change the selected action on the fly, mainly
698    /// in response to keyboard modifier changes during the drag-and-drop
699    /// operation.
700    ///
701    /// The most recent action received is always the valid one. The chosen
702    /// action may change alongside negotiation (e.g. an "ask" action can turn
703    /// into a "move" operation), so the effects of the final action must
704    /// always be applied in wl_data_offer.dnd_finished.
705    ///
706    /// Clients can trigger cursor surface changes from this point, so
707    /// they reflect the current action.
708    ///
709    /// # Arguments
710    ///
711    /// - `dnd_action`: action selected by the compositor
712    #[inline]
713    pub fn try_send_action(
714        &self,
715        dnd_action: WlDataDeviceManagerDndAction,
716    ) -> Result<(), ObjectError> {
717        let (
718            arg0,
719        ) = (
720            dnd_action,
721        );
722        let core = self.core();
723        let client_ref = core.client.borrow();
724        let Some(client) = &*client_ref else {
725            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
726        };
727        let id = core.client_obj_id.get().unwrap_or(0);
728        #[cfg(feature = "logging")]
729        if self.core.state.log {
730            #[cold]
731            fn log(state: &State, client_id: u64, id: u32, arg0: WlDataDeviceManagerDndAction) {
732                let (millis, micros) = time_since_epoch();
733                let prefix = &state.log_prefix;
734                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_data_source#{}.action(dnd_action: {:?})\n", client_id, id, arg0);
735                state.log(args);
736            }
737            log(&self.core.state, client.endpoint.id, id, arg0);
738        }
739        let endpoint = &client.endpoint;
740        if !endpoint.flush_queued.replace(true) {
741            self.core.state.add_flushable_endpoint(endpoint, Some(client));
742        }
743        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
744        let outgoing = &mut *outgoing_ref;
745        let mut fmt = outgoing.formatter();
746        fmt.words([
747            id,
748            5,
749            arg0.0,
750        ]);
751        Ok(())
752    }
753
754    /// notify the selected action
755    ///
756    /// This event indicates the action selected by the compositor after
757    /// matching the source/destination side actions. Only one action (or
758    /// none) will be offered here.
759    ///
760    /// This event can be emitted multiple times during the drag-and-drop
761    /// operation, mainly in response to destination side changes through
762    /// wl_data_offer.set_actions, and as the data device enters/leaves
763    /// surfaces.
764    ///
765    /// It is only possible to receive this event after
766    /// wl_data_source.dnd_drop_performed if the drag-and-drop operation
767    /// ended in an "ask" action, in which case the final wl_data_source.action
768    /// event will happen immediately before wl_data_source.dnd_finished.
769    ///
770    /// Compositors may also change the selected action on the fly, mainly
771    /// in response to keyboard modifier changes during the drag-and-drop
772    /// operation.
773    ///
774    /// The most recent action received is always the valid one. The chosen
775    /// action may change alongside negotiation (e.g. an "ask" action can turn
776    /// into a "move" operation), so the effects of the final action must
777    /// always be applied in wl_data_offer.dnd_finished.
778    ///
779    /// Clients can trigger cursor surface changes from this point, so
780    /// they reflect the current action.
781    ///
782    /// # Arguments
783    ///
784    /// - `dnd_action`: action selected by the compositor
785    #[inline]
786    pub fn send_action(
787        &self,
788        dnd_action: WlDataDeviceManagerDndAction,
789    ) {
790        let res = self.try_send_action(
791            dnd_action,
792        );
793        if let Err(e) = res {
794            log_send("wl_data_source.action", &e);
795        }
796    }
797}
798
799/// A message handler for [`WlDataSource`] proxies.
800pub trait WlDataSourceHandler: Any {
801    /// Event handler for wl_display.delete_id messages deleting the ID of this object.
802    ///
803    /// The default handler forwards the event to the client, if any.
804    #[inline]
805    fn delete_id(&mut self, slf: &Rc<WlDataSource>) {
806        slf.core.delete_id();
807    }
808
809    /// add an offered mime type
810    ///
811    /// This request adds a mime type to the set of mime types
812    /// advertised to targets.  Can be called several times to offer
813    /// multiple types.
814    ///
815    /// # Arguments
816    ///
817    /// - `mime_type`: mime type offered by the data source
818    #[inline]
819    fn handle_offer(
820        &mut self,
821        slf: &Rc<WlDataSource>,
822        mime_type: &str,
823    ) {
824        if !slf.core.forward_to_server.get() {
825            return;
826        }
827        let res = slf.try_send_offer(
828            mime_type,
829        );
830        if let Err(e) = res {
831            log_forward("wl_data_source.offer", &e);
832        }
833    }
834
835    /// destroy the data source
836    ///
837    /// Destroy the data source.
838    #[inline]
839    fn handle_destroy(
840        &mut self,
841        slf: &Rc<WlDataSource>,
842    ) {
843        if !slf.core.forward_to_server.get() {
844            return;
845        }
846        let res = slf.try_send_destroy(
847        );
848        if let Err(e) = res {
849            log_forward("wl_data_source.destroy", &e);
850        }
851    }
852
853    /// a target accepts an offered mime type
854    ///
855    /// Sent when a target accepts pointer_focus or motion events.  If
856    /// a target does not accept any of the offered types, type is NULL.
857    ///
858    /// Used for feedback during drag-and-drop.
859    ///
860    /// # Arguments
861    ///
862    /// - `mime_type`: mime type accepted by the target
863    #[inline]
864    fn handle_target(
865        &mut self,
866        slf: &Rc<WlDataSource>,
867        mime_type: Option<&str>,
868    ) {
869        if !slf.core.forward_to_client.get() {
870            return;
871        }
872        let res = slf.try_send_target(
873            mime_type,
874        );
875        if let Err(e) = res {
876            log_forward("wl_data_source.target", &e);
877        }
878    }
879
880    /// send the data
881    ///
882    /// Request for data from the client.  Send the data as the
883    /// specified mime type over the passed file descriptor, then
884    /// close it.
885    ///
886    /// # Arguments
887    ///
888    /// - `mime_type`: mime type for the data
889    /// - `fd`: file descriptor for the data
890    #[inline]
891    fn handle_send(
892        &mut self,
893        slf: &Rc<WlDataSource>,
894        mime_type: &str,
895        fd: &Rc<OwnedFd>,
896    ) {
897        if !slf.core.forward_to_client.get() {
898            return;
899        }
900        let res = slf.try_send_send(
901            mime_type,
902            fd,
903        );
904        if let Err(e) = res {
905            log_forward("wl_data_source.send", &e);
906        }
907    }
908
909    /// selection was cancelled
910    ///
911    /// This data source is no longer valid. There are several reasons why
912    /// this could happen:
913    ///
914    /// - The data source has been replaced by another data source.
915    /// - The drag-and-drop operation was performed, but the drop destination
916    ///   did not accept any of the mime types offered through
917    ///   wl_data_source.target.
918    /// - The drag-and-drop operation was performed, but the drop destination
919    ///   did not select any of the actions present in the mask offered through
920    ///   wl_data_source.action.
921    /// - The drag-and-drop operation was performed but didn't happen over a
922    ///   surface.
923    /// - The compositor cancelled the drag-and-drop operation (e.g. compositor
924    ///   dependent timeouts to avoid stale drag-and-drop transfers).
925    ///
926    /// The client should clean up and destroy this data source.
927    ///
928    /// For objects of version 2 or older, wl_data_source.cancelled will
929    /// only be emitted if the data source was replaced by another data
930    /// source.
931    #[inline]
932    fn handle_cancelled(
933        &mut self,
934        slf: &Rc<WlDataSource>,
935    ) {
936        if !slf.core.forward_to_client.get() {
937            return;
938        }
939        let res = slf.try_send_cancelled(
940        );
941        if let Err(e) = res {
942            log_forward("wl_data_source.cancelled", &e);
943        }
944    }
945
946    /// set the available drag-and-drop actions
947    ///
948    /// Sets the actions that the source side client supports for this
949    /// operation. This request may trigger wl_data_source.action and
950    /// wl_data_offer.action events if the compositor needs to change the
951    /// selected action.
952    ///
953    /// The dnd_actions argument must contain only values expressed in the
954    /// wl_data_device_manager.dnd_actions enum, otherwise it will result
955    /// in a protocol error.
956    ///
957    /// This request must be made once only, and can only be made on sources
958    /// used in drag-and-drop, so it must be performed before
959    /// wl_data_device.start_drag. Attempting to use the source other than
960    /// for drag-and-drop will raise a protocol error.
961    ///
962    /// # Arguments
963    ///
964    /// - `dnd_actions`: actions supported by the data source
965    #[inline]
966    fn handle_set_actions(
967        &mut self,
968        slf: &Rc<WlDataSource>,
969        dnd_actions: WlDataDeviceManagerDndAction,
970    ) {
971        if !slf.core.forward_to_server.get() {
972            return;
973        }
974        let res = slf.try_send_set_actions(
975            dnd_actions,
976        );
977        if let Err(e) = res {
978            log_forward("wl_data_source.set_actions", &e);
979        }
980    }
981
982    /// the drag-and-drop operation physically finished
983    ///
984    /// The user performed the drop action. This event does not indicate
985    /// acceptance, wl_data_source.cancelled may still be emitted afterwards
986    /// if the drop destination does not accept any mime type.
987    ///
988    /// However, this event might however not be received if the compositor
989    /// cancelled the drag-and-drop operation before this event could happen.
990    ///
991    /// Note that the data_source may still be used in the future and should
992    /// not be destroyed here.
993    #[inline]
994    fn handle_dnd_drop_performed(
995        &mut self,
996        slf: &Rc<WlDataSource>,
997    ) {
998        if !slf.core.forward_to_client.get() {
999            return;
1000        }
1001        let res = slf.try_send_dnd_drop_performed(
1002        );
1003        if let Err(e) = res {
1004            log_forward("wl_data_source.dnd_drop_performed", &e);
1005        }
1006    }
1007
1008    /// the drag-and-drop operation concluded
1009    ///
1010    /// The drop destination finished interoperating with this data
1011    /// source, so the client is now free to destroy this data source and
1012    /// free all associated data.
1013    ///
1014    /// If the action used to perform the operation was "move", the
1015    /// source can now delete the transferred data.
1016    #[inline]
1017    fn handle_dnd_finished(
1018        &mut self,
1019        slf: &Rc<WlDataSource>,
1020    ) {
1021        if !slf.core.forward_to_client.get() {
1022            return;
1023        }
1024        let res = slf.try_send_dnd_finished(
1025        );
1026        if let Err(e) = res {
1027            log_forward("wl_data_source.dnd_finished", &e);
1028        }
1029    }
1030
1031    /// notify the selected action
1032    ///
1033    /// This event indicates the action selected by the compositor after
1034    /// matching the source/destination side actions. Only one action (or
1035    /// none) will be offered here.
1036    ///
1037    /// This event can be emitted multiple times during the drag-and-drop
1038    /// operation, mainly in response to destination side changes through
1039    /// wl_data_offer.set_actions, and as the data device enters/leaves
1040    /// surfaces.
1041    ///
1042    /// It is only possible to receive this event after
1043    /// wl_data_source.dnd_drop_performed if the drag-and-drop operation
1044    /// ended in an "ask" action, in which case the final wl_data_source.action
1045    /// event will happen immediately before wl_data_source.dnd_finished.
1046    ///
1047    /// Compositors may also change the selected action on the fly, mainly
1048    /// in response to keyboard modifier changes during the drag-and-drop
1049    /// operation.
1050    ///
1051    /// The most recent action received is always the valid one. The chosen
1052    /// action may change alongside negotiation (e.g. an "ask" action can turn
1053    /// into a "move" operation), so the effects of the final action must
1054    /// always be applied in wl_data_offer.dnd_finished.
1055    ///
1056    /// Clients can trigger cursor surface changes from this point, so
1057    /// they reflect the current action.
1058    ///
1059    /// # Arguments
1060    ///
1061    /// - `dnd_action`: action selected by the compositor
1062    #[inline]
1063    fn handle_action(
1064        &mut self,
1065        slf: &Rc<WlDataSource>,
1066        dnd_action: WlDataDeviceManagerDndAction,
1067    ) {
1068        if !slf.core.forward_to_client.get() {
1069            return;
1070        }
1071        let res = slf.try_send_action(
1072            dnd_action,
1073        );
1074        if let Err(e) = res {
1075            log_forward("wl_data_source.action", &e);
1076        }
1077    }
1078}
1079
1080impl ObjectPrivate for WlDataSource {
1081    fn new(state: &Rc<State>, version: u32) -> Rc<Self> {
1082        Rc::<Self>::new_cyclic(|slf| Self {
1083            core: ObjectCore::new(state, slf.clone(), ObjectInterface::WlDataSource, version),
1084            handler: Default::default(),
1085        })
1086    }
1087
1088    fn delete_id(self: Rc<Self>) -> Result<(), (ObjectError, Rc<dyn Object>)> {
1089        let Some(mut handler) = self.handler.try_borrow_mut() else {
1090            return Err((ObjectError(ObjectErrorKind::HandlerBorrowed), self));
1091        };
1092        if let Some(handler) = &mut *handler {
1093            handler.delete_id(&self);
1094        } else {
1095            self.core.delete_id();
1096        }
1097        Ok(())
1098    }
1099
1100    fn handle_request(self: Rc<Self>, client: &Rc<Client>, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
1101        let Some(mut handler) = self.handler.try_borrow_mut() else {
1102            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
1103        };
1104        let handler = &mut *handler;
1105        match msg[1] & 0xffff {
1106            0 => {
1107                let mut offset = 2;
1108                let arg0;
1109                (arg0, offset) = parse_string::<NonNullString>(msg, offset, "mime_type")?;
1110                if offset != msg.len() {
1111                    return Err(ObjectError(ObjectErrorKind::TrailingBytes));
1112                }
1113                #[cfg(feature = "logging")]
1114                if self.core.state.log {
1115                    #[cold]
1116                    fn log(state: &State, client_id: u64, id: u32, arg0: &str) {
1117                        let (millis, micros) = time_since_epoch();
1118                        let prefix = &state.log_prefix;
1119                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_data_source#{}.offer(mime_type: {:?})\n", client_id, id, arg0);
1120                        state.log(args);
1121                    }
1122                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
1123                }
1124                if let Some(handler) = handler {
1125                    (**handler).handle_offer(&self, arg0);
1126                } else {
1127                    DefaultHandler.handle_offer(&self, arg0);
1128                }
1129            }
1130            1 => {
1131                if msg.len() != 2 {
1132                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 8)));
1133                }
1134                #[cfg(feature = "logging")]
1135                if self.core.state.log {
1136                    #[cold]
1137                    fn log(state: &State, client_id: u64, id: u32) {
1138                        let (millis, micros) = time_since_epoch();
1139                        let prefix = &state.log_prefix;
1140                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_data_source#{}.destroy()\n", client_id, id);
1141                        state.log(args);
1142                    }
1143                    log(&self.core.state, client.endpoint.id, msg[0]);
1144                }
1145                self.core.handle_client_destroy();
1146                if let Some(handler) = handler {
1147                    (**handler).handle_destroy(&self);
1148                } else {
1149                    DefaultHandler.handle_destroy(&self);
1150                }
1151            }
1152            2 => {
1153                let [
1154                    arg0,
1155                ] = msg[2..] else {
1156                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
1157                };
1158                let arg0 = WlDataDeviceManagerDndAction(arg0);
1159                #[cfg(feature = "logging")]
1160                if self.core.state.log {
1161                    #[cold]
1162                    fn log(state: &State, client_id: u64, id: u32, arg0: WlDataDeviceManagerDndAction) {
1163                        let (millis, micros) = time_since_epoch();
1164                        let prefix = &state.log_prefix;
1165                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_data_source#{}.set_actions(dnd_actions: {:?})\n", client_id, id, arg0);
1166                        state.log(args);
1167                    }
1168                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
1169                }
1170                if let Some(handler) = handler {
1171                    (**handler).handle_set_actions(&self, arg0);
1172                } else {
1173                    DefaultHandler.handle_set_actions(&self, arg0);
1174                }
1175            }
1176            n => {
1177                let _ = client;
1178                let _ = msg;
1179                let _ = fds;
1180                let _ = handler;
1181                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
1182            }
1183        }
1184        Ok(())
1185    }
1186
1187    fn handle_event(self: Rc<Self>, server: &Endpoint, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
1188        let Some(mut handler) = self.handler.try_borrow_mut() else {
1189            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
1190        };
1191        let handler = &mut *handler;
1192        match msg[1] & 0xffff {
1193            0 => {
1194                let mut offset = 2;
1195                let arg0;
1196                (arg0, offset) = parse_string::<NullableString>(msg, offset, "mime_type")?;
1197                if offset != msg.len() {
1198                    return Err(ObjectError(ObjectErrorKind::TrailingBytes));
1199                }
1200                #[cfg(feature = "logging")]
1201                if self.core.state.log {
1202                    #[cold]
1203                    fn log(state: &State, id: u32, arg0: Option<&str>) {
1204                        let (millis, micros) = time_since_epoch();
1205                        let prefix = &state.log_prefix;
1206                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_data_source#{}.target(mime_type: {:?})\n", id, arg0);
1207                        state.log(args);
1208                    }
1209                    log(&self.core.state, msg[0], arg0);
1210                }
1211                if let Some(handler) = handler {
1212                    (**handler).handle_target(&self, arg0);
1213                } else {
1214                    DefaultHandler.handle_target(&self, arg0);
1215                }
1216            }
1217            1 => {
1218                let mut offset = 2;
1219                let arg0;
1220                (arg0, offset) = parse_string::<NonNullString>(msg, offset, "mime_type")?;
1221                if offset != msg.len() {
1222                    return Err(ObjectError(ObjectErrorKind::TrailingBytes));
1223                }
1224                let Some(arg1) = fds.pop_front() else {
1225                    return Err(ObjectError(ObjectErrorKind::MissingFd("fd")));
1226                };
1227                let arg1 = &arg1;
1228                #[cfg(feature = "logging")]
1229                if self.core.state.log {
1230                    #[cold]
1231                    fn log(state: &State, id: u32, arg0: &str, arg1: i32) {
1232                        let (millis, micros) = time_since_epoch();
1233                        let prefix = &state.log_prefix;
1234                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_data_source#{}.send(mime_type: {:?}, fd: {})\n", id, arg0, arg1);
1235                        state.log(args);
1236                    }
1237                    log(&self.core.state, msg[0], arg0, arg1.as_raw_fd());
1238                }
1239                if let Some(handler) = handler {
1240                    (**handler).handle_send(&self, arg0, arg1);
1241                } else {
1242                    DefaultHandler.handle_send(&self, arg0, arg1);
1243                }
1244            }
1245            2 => {
1246                if msg.len() != 2 {
1247                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 8)));
1248                }
1249                #[cfg(feature = "logging")]
1250                if self.core.state.log {
1251                    #[cold]
1252                    fn log(state: &State, id: u32) {
1253                        let (millis, micros) = time_since_epoch();
1254                        let prefix = &state.log_prefix;
1255                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_data_source#{}.cancelled()\n", id);
1256                        state.log(args);
1257                    }
1258                    log(&self.core.state, msg[0]);
1259                }
1260                if let Some(handler) = handler {
1261                    (**handler).handle_cancelled(&self);
1262                } else {
1263                    DefaultHandler.handle_cancelled(&self);
1264                }
1265            }
1266            3 => {
1267                if msg.len() != 2 {
1268                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 8)));
1269                }
1270                #[cfg(feature = "logging")]
1271                if self.core.state.log {
1272                    #[cold]
1273                    fn log(state: &State, id: u32) {
1274                        let (millis, micros) = time_since_epoch();
1275                        let prefix = &state.log_prefix;
1276                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_data_source#{}.dnd_drop_performed()\n", id);
1277                        state.log(args);
1278                    }
1279                    log(&self.core.state, msg[0]);
1280                }
1281                if let Some(handler) = handler {
1282                    (**handler).handle_dnd_drop_performed(&self);
1283                } else {
1284                    DefaultHandler.handle_dnd_drop_performed(&self);
1285                }
1286            }
1287            4 => {
1288                if msg.len() != 2 {
1289                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 8)));
1290                }
1291                #[cfg(feature = "logging")]
1292                if self.core.state.log {
1293                    #[cold]
1294                    fn log(state: &State, id: u32) {
1295                        let (millis, micros) = time_since_epoch();
1296                        let prefix = &state.log_prefix;
1297                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_data_source#{}.dnd_finished()\n", id);
1298                        state.log(args);
1299                    }
1300                    log(&self.core.state, msg[0]);
1301                }
1302                if let Some(handler) = handler {
1303                    (**handler).handle_dnd_finished(&self);
1304                } else {
1305                    DefaultHandler.handle_dnd_finished(&self);
1306                }
1307            }
1308            5 => {
1309                let [
1310                    arg0,
1311                ] = msg[2..] else {
1312                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
1313                };
1314                let arg0 = WlDataDeviceManagerDndAction(arg0);
1315                #[cfg(feature = "logging")]
1316                if self.core.state.log {
1317                    #[cold]
1318                    fn log(state: &State, id: u32, arg0: WlDataDeviceManagerDndAction) {
1319                        let (millis, micros) = time_since_epoch();
1320                        let prefix = &state.log_prefix;
1321                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_data_source#{}.action(dnd_action: {:?})\n", id, arg0);
1322                        state.log(args);
1323                    }
1324                    log(&self.core.state, msg[0], arg0);
1325                }
1326                if let Some(handler) = handler {
1327                    (**handler).handle_action(&self, arg0);
1328                } else {
1329                    DefaultHandler.handle_action(&self, arg0);
1330                }
1331            }
1332            n => {
1333                let _ = server;
1334                let _ = msg;
1335                let _ = fds;
1336                let _ = handler;
1337                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
1338            }
1339        }
1340        Ok(())
1341    }
1342
1343    fn get_request_name(&self, id: u32) -> Option<&'static str> {
1344        let name = match id {
1345            0 => "offer",
1346            1 => "destroy",
1347            2 => "set_actions",
1348            _ => return None,
1349        };
1350        Some(name)
1351    }
1352
1353    fn get_event_name(&self, id: u32) -> Option<&'static str> {
1354        let name = match id {
1355            0 => "target",
1356            1 => "send",
1357            2 => "cancelled",
1358            3 => "dnd_drop_performed",
1359            4 => "dnd_finished",
1360            5 => "action",
1361            _ => return None,
1362        };
1363        Some(name)
1364    }
1365}
1366
1367impl Object for WlDataSource {
1368    fn core(&self) -> &ObjectCore {
1369        &self.core
1370    }
1371
1372    fn unset_handler(&self) {
1373        self.handler.set(None);
1374    }
1375
1376    fn get_handler_any_ref(&self) -> Result<HandlerRef<'_, dyn Any>, HandlerAccessError> {
1377        let borrowed = self.handler.try_borrow().ok_or(HandlerAccessError::AlreadyBorrowed)?;
1378        if borrowed.is_none() {
1379            return Err(HandlerAccessError::NoHandler);
1380        }
1381        Ok(HandlerRef::map(borrowed, |handler| &**handler.as_ref().unwrap() as &dyn Any))
1382    }
1383
1384    fn get_handler_any_mut(&self) -> Result<HandlerMut<'_, dyn Any>, HandlerAccessError> {
1385        let borrowed = self.handler.try_borrow_mut().ok_or(HandlerAccessError::AlreadyBorrowed)?;
1386        if borrowed.is_none() {
1387            return Err(HandlerAccessError::NoHandler);
1388        }
1389        Ok(HandlerMut::map(borrowed, |handler| &mut **handler.as_mut().unwrap() as &mut dyn Any))
1390    }
1391}
1392
1393impl WlDataSource {
1394    /// Since when the error.invalid_action_mask enum variant is available.
1395    pub const ENM__ERROR_INVALID_ACTION_MASK__SINCE: u32 = 1;
1396    /// Since when the error.invalid_source enum variant is available.
1397    pub const ENM__ERROR_INVALID_SOURCE__SINCE: u32 = 1;
1398}
1399
1400#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1401pub struct WlDataSourceError(pub u32);
1402
1403impl WlDataSourceError {
1404    /// action mask contains invalid values
1405    pub const INVALID_ACTION_MASK: Self = Self(0);
1406
1407    /// source doesn't accept this request
1408    pub const INVALID_SOURCE: Self = Self(1);
1409}
1410
1411impl Debug for WlDataSourceError {
1412    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1413        let name = match *self {
1414            Self::INVALID_ACTION_MASK => "INVALID_ACTION_MASK",
1415            Self::INVALID_SOURCE => "INVALID_SOURCE",
1416            _ => return Debug::fmt(&self.0, f),
1417        };
1418        f.write_str(name)
1419    }
1420}