Skip to main content

wl_proxy/protocols/wayland/
wl_data_device_manager.rs

1//! data transfer interface
2//!
3//! The wl_data_device_manager is a singleton global object that
4//! provides access to inter-client data transfer mechanisms such as
5//! copy-and-paste and drag-and-drop.  These mechanisms are tied to
6//! a wl_seat and this interface lets a client get a wl_data_device
7//! corresponding to a wl_seat.
8//!
9//! Depending on the version bound, the objects created from the bound
10//! wl_data_device_manager object will have different requirements for
11//! functioning properly. See wl_data_source.set_actions,
12//! wl_data_offer.accept and wl_data_offer.finish for details.
13
14use crate::protocol_helpers::prelude::*;
15use super::super::all_types::*;
16
17/// A wl_data_device_manager object.
18///
19/// See the documentation of [the module][self] for the interface description.
20pub struct WlDataDeviceManager {
21    core: ObjectCore,
22    handler: HandlerHolder<dyn WlDataDeviceManagerHandler>,
23}
24
25struct DefaultHandler;
26
27impl WlDataDeviceManagerHandler for DefaultHandler { }
28
29impl ConcreteObject for WlDataDeviceManager {
30    const XML_VERSION: u32 = 4;
31    const INTERFACE: ObjectInterface = ObjectInterface::WlDataDeviceManager;
32    const INTERFACE_NAME: &str = "wl_data_device_manager";
33}
34
35impl WlDataDeviceManager {
36    /// Sets a new handler.
37    pub fn set_handler(&self, handler: impl WlDataDeviceManagerHandler) {
38        self.set_boxed_handler(Box::new(handler));
39    }
40
41    /// Sets a new, already boxed handler.
42    pub fn set_boxed_handler(&self, handler: Box<dyn WlDataDeviceManagerHandler>) {
43        if self.core.state.destroyed.get() {
44            return;
45        }
46        self.handler.set(Some(handler));
47    }
48}
49
50impl Debug for WlDataDeviceManager {
51    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
52        f.debug_struct("WlDataDeviceManager")
53            .field("server_obj_id", &self.core.server_obj_id.get())
54            .field("client_id", &self.core.client_id.get())
55            .field("client_obj_id", &self.core.client_obj_id.get())
56            .finish()
57    }
58}
59
60impl WlDataDeviceManager {
61    /// Since when the create_data_source message is available.
62    pub const MSG__CREATE_DATA_SOURCE__SINCE: u32 = 1;
63
64    /// create a new data source
65    ///
66    /// Create a new data source.
67    ///
68    /// # Arguments
69    ///
70    /// - `id`: data source to create
71    #[inline]
72    pub fn try_send_create_data_source(
73        &self,
74        id: &Rc<WlDataSource>,
75    ) -> Result<(), ObjectError> {
76        let (
77            arg0,
78        ) = (
79            id,
80        );
81        let arg0_obj = arg0;
82        let arg0 = arg0_obj.core();
83        let core = self.core();
84        let Some(id) = core.server_obj_id.get() else {
85            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
86        };
87        arg0.generate_server_id(arg0_obj.clone())
88            .map_err(|e| ObjectError(ObjectErrorKind::GenerateServerId("id", e)))?;
89        let arg0_id = arg0.server_obj_id.get().unwrap_or(0);
90        #[cfg(feature = "logging")]
91        if self.core.state.log {
92            #[cold]
93            fn log(state: &State, id: u32, arg0: u32) {
94                let (millis, micros) = time_since_epoch();
95                let prefix = &state.log_prefix;
96                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_data_device_manager#{}.create_data_source(id: wl_data_source#{})\n", id, arg0);
97                state.log(args);
98            }
99            log(&self.core.state, id, arg0_id);
100        }
101        let Some(endpoint) = &self.core.state.server else {
102            return Ok(());
103        };
104        if !endpoint.flush_queued.replace(true) {
105            self.core.state.add_flushable_endpoint(endpoint, None);
106        }
107        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
108        let outgoing = &mut *outgoing_ref;
109        let mut fmt = outgoing.formatter();
110        fmt.words([
111            id,
112            0,
113            arg0_id,
114        ]);
115        Ok(())
116    }
117
118    /// create a new data source
119    ///
120    /// Create a new data source.
121    ///
122    /// # Arguments
123    ///
124    /// - `id`: data source to create
125    #[inline]
126    pub fn send_create_data_source(
127        &self,
128        id: &Rc<WlDataSource>,
129    ) {
130        let res = self.try_send_create_data_source(
131            id,
132        );
133        if let Err(e) = res {
134            log_send("wl_data_device_manager.create_data_source", &e);
135        }
136    }
137
138    /// create a new data source
139    ///
140    /// Create a new data source.
141    #[inline]
142    pub fn new_try_send_create_data_source(
143        &self,
144    ) -> Result<Rc<WlDataSource>, ObjectError> {
145        let id = self.core.create_child();
146        self.try_send_create_data_source(
147            &id,
148        )?;
149        Ok(id)
150    }
151
152    /// create a new data source
153    ///
154    /// Create a new data source.
155    #[inline]
156    pub fn new_send_create_data_source(
157        &self,
158    ) -> Rc<WlDataSource> {
159        let id = self.core.create_child();
160        self.send_create_data_source(
161            &id,
162        );
163        id
164    }
165
166    /// Since when the get_data_device message is available.
167    pub const MSG__GET_DATA_DEVICE__SINCE: u32 = 1;
168
169    /// create a new data device
170    ///
171    /// Create a new data device for a given seat.
172    ///
173    /// # Arguments
174    ///
175    /// - `id`: data device to create
176    /// - `seat`: seat associated with the data device
177    #[inline]
178    pub fn try_send_get_data_device(
179        &self,
180        id: &Rc<WlDataDevice>,
181        seat: &Rc<WlSeat>,
182    ) -> Result<(), ObjectError> {
183        let (
184            arg0,
185            arg1,
186        ) = (
187            id,
188            seat,
189        );
190        let arg0_obj = arg0;
191        let arg0 = arg0_obj.core();
192        let arg1 = arg1.core();
193        let core = self.core();
194        let Some(id) = core.server_obj_id.get() else {
195            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
196        };
197        let arg1_id = match arg1.server_obj_id.get() {
198            None => return Err(ObjectError(ObjectErrorKind::ArgNoServerId("seat"))),
199            Some(id) => id,
200        };
201        arg0.generate_server_id(arg0_obj.clone())
202            .map_err(|e| ObjectError(ObjectErrorKind::GenerateServerId("id", e)))?;
203        let arg0_id = arg0.server_obj_id.get().unwrap_or(0);
204        #[cfg(feature = "logging")]
205        if self.core.state.log {
206            #[cold]
207            fn log(state: &State, id: u32, arg0: u32, arg1: u32) {
208                let (millis, micros) = time_since_epoch();
209                let prefix = &state.log_prefix;
210                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_data_device_manager#{}.get_data_device(id: wl_data_device#{}, seat: wl_seat#{})\n", id, arg0, arg1);
211                state.log(args);
212            }
213            log(&self.core.state, id, arg0_id, arg1_id);
214        }
215        let Some(endpoint) = &self.core.state.server else {
216            return Ok(());
217        };
218        if !endpoint.flush_queued.replace(true) {
219            self.core.state.add_flushable_endpoint(endpoint, None);
220        }
221        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
222        let outgoing = &mut *outgoing_ref;
223        let mut fmt = outgoing.formatter();
224        fmt.words([
225            id,
226            1,
227            arg0_id,
228            arg1_id,
229        ]);
230        Ok(())
231    }
232
233    /// create a new data device
234    ///
235    /// Create a new data device for a given seat.
236    ///
237    /// # Arguments
238    ///
239    /// - `id`: data device to create
240    /// - `seat`: seat associated with the data device
241    #[inline]
242    pub fn send_get_data_device(
243        &self,
244        id: &Rc<WlDataDevice>,
245        seat: &Rc<WlSeat>,
246    ) {
247        let res = self.try_send_get_data_device(
248            id,
249            seat,
250        );
251        if let Err(e) = res {
252            log_send("wl_data_device_manager.get_data_device", &e);
253        }
254    }
255
256    /// create a new data device
257    ///
258    /// Create a new data device for a given seat.
259    ///
260    /// # Arguments
261    ///
262    /// - `seat`: seat associated with the data device
263    #[inline]
264    pub fn new_try_send_get_data_device(
265        &self,
266        seat: &Rc<WlSeat>,
267    ) -> Result<Rc<WlDataDevice>, ObjectError> {
268        let id = self.core.create_child();
269        self.try_send_get_data_device(
270            &id,
271            seat,
272        )?;
273        Ok(id)
274    }
275
276    /// create a new data device
277    ///
278    /// Create a new data device for a given seat.
279    ///
280    /// # Arguments
281    ///
282    /// - `seat`: seat associated with the data device
283    #[inline]
284    pub fn new_send_get_data_device(
285        &self,
286        seat: &Rc<WlSeat>,
287    ) -> Rc<WlDataDevice> {
288        let id = self.core.create_child();
289        self.send_get_data_device(
290            &id,
291            seat,
292        );
293        id
294    }
295
296    /// Since when the release message is available.
297    pub const MSG__RELEASE__SINCE: u32 = 4;
298
299    /// destroy wl_data_device_manager
300    ///
301    /// This request destroys the wl_data_device_manager. This has no effect on any other
302    /// objects.
303    #[inline]
304    pub fn try_send_release(
305        &self,
306    ) -> Result<(), ObjectError> {
307        let core = self.core();
308        let Some(id) = core.server_obj_id.get() else {
309            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
310        };
311        #[cfg(feature = "logging")]
312        if self.core.state.log {
313            #[cold]
314            fn log(state: &State, id: u32) {
315                let (millis, micros) = time_since_epoch();
316                let prefix = &state.log_prefix;
317                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_data_device_manager#{}.release()\n", id);
318                state.log(args);
319            }
320            log(&self.core.state, id);
321        }
322        let Some(endpoint) = &self.core.state.server else {
323            return Ok(());
324        };
325        if !endpoint.flush_queued.replace(true) {
326            self.core.state.add_flushable_endpoint(endpoint, None);
327        }
328        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
329        let outgoing = &mut *outgoing_ref;
330        let mut fmt = outgoing.formatter();
331        fmt.words([
332            id,
333            2,
334        ]);
335        self.core.handle_server_destroy();
336        Ok(())
337    }
338
339    /// destroy wl_data_device_manager
340    ///
341    /// This request destroys the wl_data_device_manager. This has no effect on any other
342    /// objects.
343    #[inline]
344    pub fn send_release(
345        &self,
346    ) {
347        let res = self.try_send_release(
348        );
349        if let Err(e) = res {
350            log_send("wl_data_device_manager.release", &e);
351        }
352    }
353}
354
355/// A message handler for [`WlDataDeviceManager`] proxies.
356pub trait WlDataDeviceManagerHandler: Any {
357    /// Event handler for wl_display.delete_id messages deleting the ID of this object.
358    ///
359    /// The default handler forwards the event to the client, if any.
360    #[inline]
361    fn delete_id(&mut self, slf: &Rc<WlDataDeviceManager>) {
362        slf.core.delete_id();
363    }
364
365    /// create a new data source
366    ///
367    /// Create a new data source.
368    ///
369    /// # Arguments
370    ///
371    /// - `id`: data source to create
372    #[inline]
373    fn handle_create_data_source(
374        &mut self,
375        slf: &Rc<WlDataDeviceManager>,
376        id: &Rc<WlDataSource>,
377    ) {
378        if !slf.core.forward_to_server.get() {
379            return;
380        }
381        let res = slf.try_send_create_data_source(
382            id,
383        );
384        if let Err(e) = res {
385            log_forward("wl_data_device_manager.create_data_source", &e);
386        }
387    }
388
389    /// create a new data device
390    ///
391    /// Create a new data device for a given seat.
392    ///
393    /// # Arguments
394    ///
395    /// - `id`: data device to create
396    /// - `seat`: seat associated with the data device
397    ///
398    /// All borrowed proxies passed to this function are guaranteed to be
399    /// immutable and non-null.
400    #[inline]
401    fn handle_get_data_device(
402        &mut self,
403        slf: &Rc<WlDataDeviceManager>,
404        id: &Rc<WlDataDevice>,
405        seat: &Rc<WlSeat>,
406    ) {
407        if !slf.core.forward_to_server.get() {
408            return;
409        }
410        let res = slf.try_send_get_data_device(
411            id,
412            seat,
413        );
414        if let Err(e) = res {
415            log_forward("wl_data_device_manager.get_data_device", &e);
416        }
417    }
418
419    /// destroy wl_data_device_manager
420    ///
421    /// This request destroys the wl_data_device_manager. This has no effect on any other
422    /// objects.
423    #[inline]
424    fn handle_release(
425        &mut self,
426        slf: &Rc<WlDataDeviceManager>,
427    ) {
428        if !slf.core.forward_to_server.get() {
429            return;
430        }
431        let res = slf.try_send_release(
432        );
433        if let Err(e) = res {
434            log_forward("wl_data_device_manager.release", &e);
435        }
436    }
437}
438
439impl ObjectPrivate for WlDataDeviceManager {
440    fn new(state: &Rc<State>, version: u32) -> Rc<Self> {
441        Rc::<Self>::new_cyclic(|slf| Self {
442            core: ObjectCore::new(state, slf.clone(), ObjectInterface::WlDataDeviceManager, version),
443            handler: Default::default(),
444        })
445    }
446
447    fn delete_id(self: Rc<Self>) -> Result<(), (ObjectError, Rc<dyn Object>)> {
448        let Some(mut handler) = self.handler.try_borrow_mut() else {
449            return Err((ObjectError(ObjectErrorKind::HandlerBorrowed), self));
450        };
451        if let Some(handler) = &mut *handler {
452            handler.delete_id(&self);
453        } else {
454            self.core.delete_id();
455        }
456        Ok(())
457    }
458
459    fn handle_request(self: Rc<Self>, client: &Rc<Client>, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
460        let Some(mut handler) = self.handler.try_borrow_mut() else {
461            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
462        };
463        let handler = &mut *handler;
464        match msg[1] & 0xffff {
465            0 => {
466                let [
467                    arg0,
468                ] = msg[2..] else {
469                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
470                };
471                #[cfg(feature = "logging")]
472                if self.core.state.log {
473                    #[cold]
474                    fn log(state: &State, client_id: u64, id: u32, arg0: u32) {
475                        let (millis, micros) = time_since_epoch();
476                        let prefix = &state.log_prefix;
477                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_data_device_manager#{}.create_data_source(id: wl_data_source#{})\n", client_id, id, arg0);
478                        state.log(args);
479                    }
480                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
481                }
482                let arg0_id = arg0;
483                let arg0 = WlDataSource::new(&self.core.state, self.core.version);
484                arg0.core().set_client_id(client, arg0_id, arg0.clone())
485                    .map_err(|e| ObjectError(ObjectErrorKind::SetClientId(arg0_id, "id", e)))?;
486                let arg0 = &arg0;
487                if let Some(handler) = handler {
488                    (**handler).handle_create_data_source(&self, arg0);
489                } else {
490                    DefaultHandler.handle_create_data_source(&self, arg0);
491                }
492            }
493            1 => {
494                let [
495                    arg0,
496                    arg1,
497                ] = msg[2..] else {
498                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 16)));
499                };
500                #[cfg(feature = "logging")]
501                if self.core.state.log {
502                    #[cold]
503                    fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: u32) {
504                        let (millis, micros) = time_since_epoch();
505                        let prefix = &state.log_prefix;
506                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_data_device_manager#{}.get_data_device(id: wl_data_device#{}, seat: wl_seat#{})\n", client_id, id, arg0, arg1);
507                        state.log(args);
508                    }
509                    log(&self.core.state, client.endpoint.id, msg[0], arg0, arg1);
510                }
511                let arg0_id = arg0;
512                let arg0 = WlDataDevice::new(&self.core.state, self.core.version);
513                arg0.core().set_client_id(client, arg0_id, arg0.clone())
514                    .map_err(|e| ObjectError(ObjectErrorKind::SetClientId(arg0_id, "id", e)))?;
515                let arg1_id = arg1;
516                let Some(arg1) = client.endpoint.lookup(arg1_id) else {
517                    return Err(ObjectError(ObjectErrorKind::NoClientObject(client.endpoint.id, arg1_id)));
518                };
519                let Ok(arg1) = (arg1 as Rc<dyn Any>).downcast::<WlSeat>() else {
520                    let o = client.endpoint.lookup(arg1_id).unwrap();
521                    return Err(ObjectError(ObjectErrorKind::WrongObjectType("seat", o.core().interface, ObjectInterface::WlSeat)));
522                };
523                let arg0 = &arg0;
524                let arg1 = &arg1;
525                if let Some(handler) = handler {
526                    (**handler).handle_get_data_device(&self, arg0, arg1);
527                } else {
528                    DefaultHandler.handle_get_data_device(&self, arg0, arg1);
529                }
530            }
531            2 => {
532                if msg.len() != 2 {
533                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 8)));
534                }
535                #[cfg(feature = "logging")]
536                if self.core.state.log {
537                    #[cold]
538                    fn log(state: &State, client_id: u64, id: u32) {
539                        let (millis, micros) = time_since_epoch();
540                        let prefix = &state.log_prefix;
541                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_data_device_manager#{}.release()\n", client_id, id);
542                        state.log(args);
543                    }
544                    log(&self.core.state, client.endpoint.id, msg[0]);
545                }
546                self.core.handle_client_destroy();
547                if let Some(handler) = handler {
548                    (**handler).handle_release(&self);
549                } else {
550                    DefaultHandler.handle_release(&self);
551                }
552            }
553            n => {
554                let _ = client;
555                let _ = msg;
556                let _ = fds;
557                let _ = handler;
558                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
559            }
560        }
561        Ok(())
562    }
563
564    fn handle_event(self: Rc<Self>, server: &Endpoint, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
565        let Some(mut handler) = self.handler.try_borrow_mut() else {
566            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
567        };
568        let handler = &mut *handler;
569        match msg[1] & 0xffff {
570            n => {
571                let _ = server;
572                let _ = msg;
573                let _ = fds;
574                let _ = handler;
575                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
576            }
577        }
578    }
579
580    fn get_request_name(&self, id: u32) -> Option<&'static str> {
581        let name = match id {
582            0 => "create_data_source",
583            1 => "get_data_device",
584            2 => "release",
585            _ => return None,
586        };
587        Some(name)
588    }
589
590    fn get_event_name(&self, id: u32) -> Option<&'static str> {
591        let _ = id;
592        None
593    }
594}
595
596impl Object for WlDataDeviceManager {
597    fn core(&self) -> &ObjectCore {
598        &self.core
599    }
600
601    fn unset_handler(&self) {
602        self.handler.set(None);
603    }
604
605    fn get_handler_any_ref(&self) -> Result<HandlerRef<'_, dyn Any>, HandlerAccessError> {
606        let borrowed = self.handler.try_borrow().ok_or(HandlerAccessError::AlreadyBorrowed)?;
607        if borrowed.is_none() {
608            return Err(HandlerAccessError::NoHandler);
609        }
610        Ok(HandlerRef::map(borrowed, |handler| &**handler.as_ref().unwrap() as &dyn Any))
611    }
612
613    fn get_handler_any_mut(&self) -> Result<HandlerMut<'_, dyn Any>, HandlerAccessError> {
614        let borrowed = self.handler.try_borrow_mut().ok_or(HandlerAccessError::AlreadyBorrowed)?;
615        if borrowed.is_none() {
616            return Err(HandlerAccessError::NoHandler);
617        }
618        Ok(HandlerMut::map(borrowed, |handler| &mut **handler.as_mut().unwrap() as &mut dyn Any))
619    }
620}
621
622impl WlDataDeviceManager {
623    /// Since when the dnd_action.none enum variant is available.
624    pub const ENM__DND_ACTION_NONE__SINCE: u32 = 1;
625    /// Since when the dnd_action.copy enum variant is available.
626    pub const ENM__DND_ACTION_COPY__SINCE: u32 = 1;
627    /// Since when the dnd_action.move enum variant is available.
628    pub const ENM__DND_ACTION_MOVE__SINCE: u32 = 1;
629    /// Since when the dnd_action.ask enum variant is available.
630    pub const ENM__DND_ACTION_ASK__SINCE: u32 = 1;
631}
632
633/// drag and drop actions
634///
635/// This is a bitmask of the available/preferred actions in a
636/// drag-and-drop operation.
637///
638/// In the compositor, the selected action is a result of matching the
639/// actions offered by the source and destination sides.  "action" events
640/// with a "none" action will be sent to both source and destination if
641/// there is no match. All further checks will effectively happen on
642/// (source actions ∩ destination actions).
643///
644/// In addition, compositors may also pick different actions in
645/// reaction to key modifiers being pressed. One common design that
646/// is used in major toolkits (and the behavior recommended for
647/// compositors) is:
648///
649/// - If no modifiers are pressed, the first match (in bit order)
650///   will be used.
651/// - Pressing Shift selects "move", if enabled in the mask.
652/// - Pressing Control selects "copy", if enabled in the mask.
653///
654/// Behavior beyond that is considered implementation-dependent.
655/// Compositors may for example bind other modifiers (like Alt/Meta)
656/// or drags initiated with other buttons than BTN_LEFT to specific
657/// actions (e.g. "ask").
658#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
659#[derive(Default)]
660pub struct WlDataDeviceManagerDndAction(pub u32);
661
662/// An iterator over the set bits in a [`WlDataDeviceManagerDndAction`].
663///
664/// You can construct this with the `IntoIterator` implementation of `WlDataDeviceManagerDndAction`.
665#[derive(Clone, Debug)]
666pub struct WlDataDeviceManagerDndActionIter(pub u32);
667
668impl WlDataDeviceManagerDndAction {
669    /// no action
670    pub const NONE: Self = Self(0);
671
672    /// copy action
673    pub const COPY: Self = Self(1);
674
675    /// move action
676    pub const MOVE: Self = Self(2);
677
678    /// ask action
679    pub const ASK: Self = Self(4);
680}
681
682impl WlDataDeviceManagerDndAction {
683    #[inline]
684    pub const fn empty() -> Self {
685        Self(0)
686    }
687
688    #[inline]
689    #[must_use]
690    pub const fn is_empty(self) -> bool {
691        self.0 == 0
692    }
693
694    #[inline]
695    #[must_use]
696    pub const fn contains(self, other: Self) -> bool {
697        self.0 & other.0 == other.0
698    }
699
700    #[inline]
701    #[must_use]
702    pub const fn intersects(self, other: Self) -> bool {
703        self.0 & other.0 != 0
704    }
705
706    #[inline]
707    pub const fn insert(&mut self, other: Self) {
708        *self = self.union(other);
709    }
710
711    #[inline]
712    pub const fn remove(&mut self, other: Self) {
713        *self = self.difference(other);
714    }
715
716    #[inline]
717    pub const fn toggle(&mut self, other: Self) {
718        *self = self.symmetric_difference(other);
719    }
720
721    #[inline]
722    pub const fn set(&mut self, other: Self, value: bool) {
723        if value {
724            self.insert(other);
725        } else {
726            self.remove(other);
727        }
728    }
729
730    #[inline]
731    #[must_use]
732    pub const fn intersection(self, other: Self) -> Self {
733        Self(self.0 & other.0)
734    }
735
736    #[inline]
737    #[must_use]
738    pub const fn union(self, other: Self) -> Self {
739        Self(self.0 | other.0)
740    }
741
742    #[inline]
743    #[must_use]
744    pub const fn difference(self, other: Self) -> Self {
745        Self(self.0 & !other.0)
746    }
747
748    #[inline]
749    #[must_use]
750    pub const fn complement(self) -> Self {
751        Self(!self.0)
752    }
753
754    #[inline]
755    #[must_use]
756    pub const fn symmetric_difference(self, other: Self) -> Self {
757        Self(self.0 ^ other.0)
758    }
759
760    #[inline]
761    pub const fn all_known() -> Self {
762        #[allow(clippy::eq_op, clippy::identity_op)]
763        Self(0 | 0 | 1 | 2 | 4)
764    }
765}
766
767impl Iterator for WlDataDeviceManagerDndActionIter {
768    type Item = WlDataDeviceManagerDndAction;
769
770    fn next(&mut self) -> Option<Self::Item> {
771        if self.0 == 0 {
772            return None;
773        }
774        let bit = 1 << self.0.trailing_zeros();
775        self.0 &= !bit;
776        Some(WlDataDeviceManagerDndAction(bit))
777    }
778}
779
780impl IntoIterator for WlDataDeviceManagerDndAction {
781    type Item = WlDataDeviceManagerDndAction;
782    type IntoIter = WlDataDeviceManagerDndActionIter;
783
784    fn into_iter(self) -> Self::IntoIter {
785        WlDataDeviceManagerDndActionIter(self.0)
786    }
787}
788
789impl BitAnd for WlDataDeviceManagerDndAction {
790    type Output = Self;
791
792    fn bitand(self, rhs: Self) -> Self::Output {
793        self.intersection(rhs)
794    }
795}
796
797impl BitAndAssign for WlDataDeviceManagerDndAction {
798    fn bitand_assign(&mut self, rhs: Self) {
799        *self = self.intersection(rhs);
800    }
801}
802
803impl BitOr for WlDataDeviceManagerDndAction {
804    type Output = Self;
805
806    fn bitor(self, rhs: Self) -> Self::Output {
807        self.union(rhs)
808    }
809}
810
811impl BitOrAssign for WlDataDeviceManagerDndAction {
812    fn bitor_assign(&mut self, rhs: Self) {
813        *self = self.union(rhs);
814    }
815}
816
817impl BitXor for WlDataDeviceManagerDndAction {
818    type Output = Self;
819
820    fn bitxor(self, rhs: Self) -> Self::Output {
821        self.symmetric_difference(rhs)
822    }
823}
824
825impl BitXorAssign for WlDataDeviceManagerDndAction {
826    fn bitxor_assign(&mut self, rhs: Self) {
827        *self = self.symmetric_difference(rhs);
828    }
829}
830
831impl Sub for WlDataDeviceManagerDndAction {
832    type Output = Self;
833
834    fn sub(self, rhs: Self) -> Self::Output {
835        self.difference(rhs)
836    }
837}
838
839impl SubAssign for WlDataDeviceManagerDndAction {
840    fn sub_assign(&mut self, rhs: Self) {
841        *self = self.difference(rhs);
842    }
843}
844
845impl Not for WlDataDeviceManagerDndAction {
846    type Output = Self;
847
848    fn not(self) -> Self::Output {
849        self.complement()
850    }
851}
852
853impl Debug for WlDataDeviceManagerDndAction {
854    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
855        let mut v = self.0;
856        let mut first = true;
857        if v & 1 == 1 {
858            v &= !1;
859            if first {
860                first = false;
861            } else {
862                f.write_str(" | ")?;
863            }
864            f.write_str("COPY")?;
865        }
866        if v & 2 == 2 {
867            v &= !2;
868            if first {
869                first = false;
870            } else {
871                f.write_str(" | ")?;
872            }
873            f.write_str("MOVE")?;
874        }
875        if v & 4 == 4 {
876            v &= !4;
877            if first {
878                first = false;
879            } else {
880                f.write_str(" | ")?;
881            }
882            f.write_str("ASK")?;
883        }
884        if v != 0 {
885            if first {
886                first = false;
887            } else {
888                f.write_str(" | ")?;
889            }
890            write!(f, "0x{v:032x}")?;
891        }
892        if first {
893            f.write_str("NONE")?;
894        }
895        Ok(())
896    }
897}