simple_window/common/protocols/wayland/
wl_seat.rs

1//! group of input devices
2//!
3//! A seat is a group of keyboards, pointer and touch devices. This
4//! object is published as a global during start up, or when such a
5//! device is hot plugged.  A seat typically has a pointer and
6//! maintains a keyboard focus and a pointer focus.
7
8use {super::super::all_types::*, ::wl_client::builder::prelude::*};
9
10static INTERFACE: wl_interface = wl_interface {
11    name: c"wl_seat".as_ptr(),
12    version: 10,
13    method_count: 4,
14    methods: {
15        static MESSAGES: [wl_message; 4] = [
16            wl_message {
17                name: c"get_pointer".as_ptr(),
18                signature: c"n".as_ptr(),
19                types: {
20                    static TYPES: [Option<&'static wl_interface>; 1] =
21                        [Some(WlPointer::WL_INTERFACE)];
22                    TYPES.as_ptr().cast()
23                },
24            },
25            wl_message {
26                name: c"get_keyboard".as_ptr(),
27                signature: c"n".as_ptr(),
28                types: {
29                    static TYPES: [Option<&'static wl_interface>; 1] =
30                        [Some(WlKeyboard::WL_INTERFACE)];
31                    TYPES.as_ptr().cast()
32                },
33            },
34            wl_message {
35                name: c"get_touch".as_ptr(),
36                signature: c"n".as_ptr(),
37                types: {
38                    static TYPES: [Option<&'static wl_interface>; 1] =
39                        [Some(WlTouch::WL_INTERFACE)];
40                    TYPES.as_ptr().cast()
41                },
42            },
43            wl_message {
44                name: c"release".as_ptr(),
45                signature: c"".as_ptr(),
46                types: {
47                    static TYPES: [Option<&'static wl_interface>; 0] = [];
48                    TYPES.as_ptr().cast()
49                },
50            },
51        ];
52        MESSAGES.as_ptr()
53    },
54    event_count: 2,
55    events: {
56        static MESSAGES: [wl_message; 2] = [
57            wl_message {
58                name: c"capabilities".as_ptr(),
59                signature: c"u".as_ptr(),
60                types: {
61                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
62                    TYPES.as_ptr().cast()
63                },
64            },
65            wl_message {
66                name: c"name".as_ptr(),
67                signature: c"s".as_ptr(),
68                types: {
69                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
70                    TYPES.as_ptr().cast()
71                },
72            },
73        ];
74        MESSAGES.as_ptr()
75    },
76};
77
78/// An owned wl_seat proxy.
79///
80/// See the documentation of [the module][self] for the interface description.
81#[derive(Clone, Eq, PartialEq)]
82#[repr(transparent)]
83pub struct WlSeat {
84    /// This proxy has the interface INTERFACE.
85    proxy: UntypedOwnedProxy,
86}
87
88/// A borrowed wl_seat proxy.
89///
90/// See the documentation of [the module][self] for the interface description.
91#[derive(Eq, PartialEq)]
92#[repr(transparent)]
93pub struct WlSeatRef {
94    /// This proxy has the interface INTERFACE.
95    proxy: UntypedBorrowedProxy,
96}
97
98// SAFETY: WlSeat is a transparent wrapper around UntypedOwnedProxy
99unsafe impl UntypedOwnedProxyWrapper for WlSeat {}
100
101// SAFETY: - INTERFACE is a valid wl_interface
102//         - The only invariant is that self.proxy has a compatible interface
103unsafe impl OwnedProxy for WlSeat {
104    const INTERFACE: &'static str = "wl_seat";
105    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
106    const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
107        private::EventHandler(private::NoOpEventHandler);
108    const MAX_VERSION: u32 = 10;
109
110    type Borrowed = WlSeatRef;
111    type Api = private::ProxyApi;
112    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
113}
114
115// SAFETY: WlSeatRef is a transparent wrapper around UntypedBorrowedProxy
116unsafe impl UntypedBorrowedProxyWrapper for WlSeatRef {}
117
118// SAFETY: - The only invariant is that self.proxy has a compatible interface
119unsafe impl BorrowedProxy for WlSeatRef {
120    type Owned = WlSeat;
121}
122
123impl Deref for WlSeat {
124    type Target = WlSeatRef;
125
126    fn deref(&self) -> &Self::Target {
127        proxy::low_level::deref(self)
128    }
129}
130
131mod private {
132    pub struct ProxyApi;
133
134    #[allow(dead_code)]
135    pub struct EventHandler<H>(pub(super) H);
136
137    #[allow(dead_code)]
138    pub struct NoOpEventHandler;
139}
140
141impl Debug for WlSeat {
142    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
143        write!(f, "wl_seat#{}", self.proxy.id())
144    }
145}
146
147impl Debug for WlSeatRef {
148    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
149        write!(f, "wl_seat#{}", self.proxy.id())
150    }
151}
152
153impl PartialEq<WlSeatRef> for WlSeat {
154    fn eq(&self, other: &WlSeatRef) -> bool {
155        self.proxy == other.proxy
156    }
157}
158
159impl PartialEq<WlSeat> for WlSeatRef {
160    fn eq(&self, other: &WlSeat) -> bool {
161        self.proxy == other.proxy
162    }
163}
164
165#[allow(dead_code)]
166impl WlSeat {
167    /// Since when the get_pointer request is available.
168    #[allow(dead_code)]
169    pub const REQ__GET_POINTER__SINCE: u32 = 1;
170
171    /// return pointer object
172    ///
173    /// The ID provided will be initialized to the wl_pointer interface
174    /// for this seat.
175    ///
176    /// This request only takes effect if the seat has the pointer
177    /// capability, or has had the pointer capability in the past.
178    /// It is a protocol violation to issue this request on a seat that has
179    /// never had the pointer capability. The missing_capability error will
180    /// be sent in this case.
181    #[inline]
182    pub fn get_pointer(&self) -> WlPointer {
183        let mut args = [wl_argument { n: 0 }];
184        // SAFETY: - self.proxy has the interface INTERFACE
185        //         - 0 < INTERFACE.method_count = 4
186        //         - the request signature is `n`
187        //         - OwnedProxy::WL_INTERFACE is always a valid interface
188        let data = unsafe {
189            self.proxy
190                .send_constructor::<false>(0, &mut args, WlPointer::WL_INTERFACE, None)
191        };
192        // SAFETY: data has the interface WlPointer::WL_INTERFACE
193        unsafe { proxy::low_level::from_untyped_owned(data) }
194    }
195
196    /// Since when the get_keyboard request is available.
197    #[allow(dead_code)]
198    pub const REQ__GET_KEYBOARD__SINCE: u32 = 1;
199
200    /// return keyboard object
201    ///
202    /// The ID provided will be initialized to the wl_keyboard interface
203    /// for this seat.
204    ///
205    /// This request only takes effect if the seat has the keyboard
206    /// capability, or has had the keyboard capability in the past.
207    /// It is a protocol violation to issue this request on a seat that has
208    /// never had the keyboard capability. The missing_capability error will
209    /// be sent in this case.
210    #[inline]
211    pub fn get_keyboard(&self) -> WlKeyboard {
212        let mut args = [wl_argument { n: 0 }];
213        // SAFETY: - self.proxy has the interface INTERFACE
214        //         - 1 < INTERFACE.method_count = 4
215        //         - the request signature is `n`
216        //         - OwnedProxy::WL_INTERFACE is always a valid interface
217        let data = unsafe {
218            self.proxy
219                .send_constructor::<false>(1, &mut args, WlKeyboard::WL_INTERFACE, None)
220        };
221        // SAFETY: data has the interface WlKeyboard::WL_INTERFACE
222        unsafe { proxy::low_level::from_untyped_owned(data) }
223    }
224
225    /// Since when the get_touch request is available.
226    #[allow(dead_code)]
227    pub const REQ__GET_TOUCH__SINCE: u32 = 1;
228
229    /// return touch object
230    ///
231    /// The ID provided will be initialized to the wl_touch interface
232    /// for this seat.
233    ///
234    /// This request only takes effect if the seat has the touch
235    /// capability, or has had the touch capability in the past.
236    /// It is a protocol violation to issue this request on a seat that has
237    /// never had the touch capability. The missing_capability error will
238    /// be sent in this case.
239    #[inline]
240    pub fn get_touch(&self) -> WlTouch {
241        let mut args = [wl_argument { n: 0 }];
242        // SAFETY: - self.proxy has the interface INTERFACE
243        //         - 2 < INTERFACE.method_count = 4
244        //         - the request signature is `n`
245        //         - OwnedProxy::WL_INTERFACE is always a valid interface
246        let data = unsafe {
247            self.proxy
248                .send_constructor::<false>(2, &mut args, WlTouch::WL_INTERFACE, None)
249        };
250        // SAFETY: data has the interface WlTouch::WL_INTERFACE
251        unsafe { proxy::low_level::from_untyped_owned(data) }
252    }
253
254    /// Since when the release request is available.
255    #[allow(dead_code)]
256    pub const REQ__RELEASE__SINCE: u32 = 5;
257
258    /// release the seat object
259    ///
260    /// Using this request a client can tell the server that it is not going to
261    /// use the seat object anymore.
262    #[inline]
263    pub fn release(&self) {
264        let mut args = [];
265        // SAFETY: - self.proxy has the interface INTERFACE
266        //         - 3 < INTERFACE.method_count = 4
267        //         - the request signature is ``
268        unsafe {
269            self.proxy.send_destructor(3, &mut args);
270        }
271    }
272}
273
274#[allow(dead_code)]
275impl WlSeatRef {
276    /// return pointer object
277    ///
278    /// The ID provided will be initialized to the wl_pointer interface
279    /// for this seat.
280    ///
281    /// This request only takes effect if the seat has the pointer
282    /// capability, or has had the pointer capability in the past.
283    /// It is a protocol violation to issue this request on a seat that has
284    /// never had the pointer capability. The missing_capability error will
285    /// be sent in this case.
286    ///
287    /// # Arguments
288    ///
289    /// - `_queue`: The queue that the returned proxy is assigned to.
290    #[inline]
291    pub fn get_pointer(&self, _queue: &Queue) -> WlPointer {
292        let mut args = [wl_argument { n: 0 }];
293        // SAFETY: - self.proxy has the interface INTERFACE
294        //         - 0 < INTERFACE.method_count = 4
295        //         - the request signature is `n`
296        //         - OwnedProxy::WL_INTERFACE is always a valid interface
297        let data = unsafe {
298            self.proxy
299                .send_constructor(_queue, 0, &mut args, WlPointer::WL_INTERFACE, None)
300        };
301        // SAFETY: data has the interface WlPointer::WL_INTERFACE
302        unsafe { proxy::low_level::from_untyped_owned(data) }
303    }
304
305    /// return keyboard object
306    ///
307    /// The ID provided will be initialized to the wl_keyboard interface
308    /// for this seat.
309    ///
310    /// This request only takes effect if the seat has the keyboard
311    /// capability, or has had the keyboard capability in the past.
312    /// It is a protocol violation to issue this request on a seat that has
313    /// never had the keyboard capability. The missing_capability error will
314    /// be sent in this case.
315    ///
316    /// # Arguments
317    ///
318    /// - `_queue`: The queue that the returned proxy is assigned to.
319    #[inline]
320    pub fn get_keyboard(&self, _queue: &Queue) -> WlKeyboard {
321        let mut args = [wl_argument { n: 0 }];
322        // SAFETY: - self.proxy has the interface INTERFACE
323        //         - 1 < INTERFACE.method_count = 4
324        //         - the request signature is `n`
325        //         - OwnedProxy::WL_INTERFACE is always a valid interface
326        let data = unsafe {
327            self.proxy
328                .send_constructor(_queue, 1, &mut args, WlKeyboard::WL_INTERFACE, None)
329        };
330        // SAFETY: data has the interface WlKeyboard::WL_INTERFACE
331        unsafe { proxy::low_level::from_untyped_owned(data) }
332    }
333
334    /// return touch object
335    ///
336    /// The ID provided will be initialized to the wl_touch interface
337    /// for this seat.
338    ///
339    /// This request only takes effect if the seat has the touch
340    /// capability, or has had the touch capability in the past.
341    /// It is a protocol violation to issue this request on a seat that has
342    /// never had the touch capability. The missing_capability error will
343    /// be sent in this case.
344    ///
345    /// # Arguments
346    ///
347    /// - `_queue`: The queue that the returned proxy is assigned to.
348    #[inline]
349    pub fn get_touch(&self, _queue: &Queue) -> WlTouch {
350        let mut args = [wl_argument { n: 0 }];
351        // SAFETY: - self.proxy has the interface INTERFACE
352        //         - 2 < INTERFACE.method_count = 4
353        //         - the request signature is `n`
354        //         - OwnedProxy::WL_INTERFACE is always a valid interface
355        let data = unsafe {
356            self.proxy
357                .send_constructor(_queue, 2, &mut args, WlTouch::WL_INTERFACE, None)
358        };
359        // SAFETY: data has the interface WlTouch::WL_INTERFACE
360        unsafe { proxy::low_level::from_untyped_owned(data) }
361    }
362}
363
364impl WlSeat {
365    /// Since when the capabilities event is available.
366    #[allow(dead_code)]
367    pub const EVT__CAPABILITIES__SINCE: u32 = 1;
368
369    /// Since when the name event is available.
370    #[allow(dead_code)]
371    pub const EVT__NAME__SINCE: u32 = 2;
372}
373
374/// An event handler for [WlSeat] proxies.
375#[allow(dead_code)]
376pub trait WlSeatEventHandler {
377    /// seat capabilities changed
378    ///
379    /// This is emitted whenever a seat gains or loses the pointer,
380    /// keyboard or touch capabilities.  The argument is a capability
381    /// enum containing the complete set of capabilities this seat has.
382    ///
383    /// When the pointer capability is added, a client may create a
384    /// wl_pointer object using the wl_seat.get_pointer request. This object
385    /// will receive pointer events until the capability is removed in the
386    /// future.
387    ///
388    /// When the pointer capability is removed, a client should destroy the
389    /// wl_pointer objects associated with the seat where the capability was
390    /// removed, using the wl_pointer.release request. No further pointer
391    /// events will be received on these objects.
392    ///
393    /// In some compositors, if a seat regains the pointer capability and a
394    /// client has a previously obtained wl_pointer object of version 4 or
395    /// less, that object may start sending pointer events again. This
396    /// behavior is considered a misinterpretation of the intended behavior
397    /// and must not be relied upon by the client. wl_pointer objects of
398    /// version 5 or later must not send events if created before the most
399    /// recent event notifying the client of an added pointer capability.
400    ///
401    /// The above behavior also applies to wl_keyboard and wl_touch with the
402    /// keyboard and touch capabilities, respectively.
403    ///
404    /// # Arguments
405    ///
406    /// - `capabilities`: capabilities of the seat
407    #[inline]
408    fn capabilities(&self, _slf: &WlSeatRef, capabilities: WlSeatCapability) {
409        let _ = capabilities;
410    }
411
412    /// unique identifier for this seat
413    ///
414    /// In a multi-seat configuration the seat name can be used by clients to
415    /// help identify which physical devices the seat represents.
416    ///
417    /// The seat name is a UTF-8 string with no convention defined for its
418    /// contents. Each name is unique among all wl_seat globals. The name is
419    /// only guaranteed to be unique for the current compositor instance.
420    ///
421    /// The same seat names are used for all clients. Thus, the name can be
422    /// shared across processes to refer to a specific wl_seat global.
423    ///
424    /// The name event is sent after binding to the seat global. This event is
425    /// only sent once per seat object, and the name does not change over the
426    /// lifetime of the wl_seat global.
427    ///
428    /// Compositors may re-use the same seat name if the wl_seat global is
429    /// destroyed and re-created later.
430    ///
431    /// # Arguments
432    ///
433    /// - `name`: seat identifier
434    #[inline]
435    fn name(&self, _slf: &WlSeatRef, name: &str) {
436        let _ = name;
437    }
438}
439
440impl WlSeatEventHandler for private::NoOpEventHandler {}
441
442// SAFETY: - INTERFACE is a valid wl_interface
443unsafe impl<H> EventHandler for private::EventHandler<H>
444where
445    H: WlSeatEventHandler,
446{
447    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
448
449    #[allow(unused_variables)]
450    unsafe fn handle_event(
451        &self,
452        queue: &Queue,
453        data: *mut u8,
454        slf: &UntypedBorrowedProxy,
455        opcode: u32,
456        args: *mut wl_argument,
457    ) {
458        // SAFETY: This function requires that slf has the interface INTERFACE
459        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlSeatRef>(slf) };
460        match opcode {
461            0 => {
462                // SAFETY: INTERFACE requires that there are 1 arguments
463                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
464                // SAFETY: - INTERFACE requires that args[0] contains a uint
465                let arg0 = unsafe { WlSeatCapability(args[0].u) };
466                self.0.capabilities(slf, arg0);
467            }
468            1 => {
469                // SAFETY: INTERFACE requires that there are 1 arguments
470                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
471                // SAFETY: - INTERFACE requires that args[0] contains a string
472                //         - if the pointer is not null, then it is a c string
473                let arg0 = unsafe { convert_string_arg("wl_seat", "name", args[0].s) };
474                self.0.name(slf, arg0);
475            }
476            _ => {
477                invalid_opcode("wl_seat", opcode);
478            }
479        }
480    }
481}
482
483impl<H> CreateEventHandler<H> for private::ProxyApi
484where
485    H: WlSeatEventHandler,
486{
487    type EventHandler = private::EventHandler<H>;
488
489    #[inline]
490    fn create_event_handler(handler: H) -> Self::EventHandler {
491        private::EventHandler(handler)
492    }
493}
494
495impl WlSeat {
496    /// Since when the capability.pointer enum variant is available.
497    #[allow(dead_code)]
498    pub const ENM__CAPABILITY_POINTER__SINCE: u32 = 1;
499    /// Since when the capability.keyboard enum variant is available.
500    #[allow(dead_code)]
501    pub const ENM__CAPABILITY_KEYBOARD__SINCE: u32 = 1;
502    /// Since when the capability.touch enum variant is available.
503    #[allow(dead_code)]
504    pub const ENM__CAPABILITY_TOUCH__SINCE: u32 = 1;
505
506    /// Since when the error.missing_capability enum variant is available.
507    #[allow(dead_code)]
508    pub const ENM__ERROR_MISSING_CAPABILITY__SINCE: u32 = 1;
509}
510
511/// seat capability bitmask
512///
513/// This is a bitmask of capabilities this seat has; if a member is
514/// set, then it is present on the seat.
515#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
516#[allow(dead_code)]
517pub struct WlSeatCapability(pub u32);
518
519/// An iterator over the set bits in a [WlSeatCapability].
520///
521/// You can construct this with the `IntoIterator` implementation of `WlSeatCapability`.
522#[derive(Clone, Debug)]
523pub struct WlSeatCapabilityIter(pub u32);
524
525impl WlSeatCapability {
526    /// the seat has pointer devices
527    #[allow(dead_code)]
528    pub const POINTER: Self = Self(1);
529
530    /// the seat has one or more keyboards
531    #[allow(dead_code)]
532    pub const KEYBOARD: Self = Self(2);
533
534    /// the seat has touch devices
535    #[allow(dead_code)]
536    pub const TOUCH: Self = Self(4);
537}
538
539#[allow(dead_code)]
540impl WlSeatCapability {
541    #[inline]
542    pub const fn empty() -> Self {
543        Self(0)
544    }
545
546    #[inline]
547    #[must_use]
548    pub const fn is_empty(self) -> bool {
549        self.0 == 0
550    }
551
552    #[inline]
553    #[must_use]
554    pub const fn contains(self, other: Self) -> bool {
555        self.0 & other.0 == other.0
556    }
557
558    #[inline]
559    #[must_use]
560    pub const fn intersects(self, other: Self) -> bool {
561        self.0 & other.0 != 0
562    }
563
564    #[inline]
565    pub const fn insert(&mut self, other: Self) {
566        *self = self.union(other);
567    }
568
569    #[inline]
570    pub const fn remove(&mut self, other: Self) {
571        *self = self.difference(other);
572    }
573
574    #[inline]
575    pub const fn toggle(&mut self, other: Self) {
576        *self = self.symmetric_difference(other);
577    }
578
579    #[inline]
580    pub const fn set(&mut self, other: Self, value: bool) {
581        if value {
582            self.insert(other);
583        } else {
584            self.remove(other);
585        }
586    }
587
588    #[inline]
589    #[must_use]
590    pub const fn intersection(self, other: Self) -> Self {
591        Self(self.0 & other.0)
592    }
593
594    #[inline]
595    #[must_use]
596    pub const fn union(self, other: Self) -> Self {
597        Self(self.0 | other.0)
598    }
599
600    #[inline]
601    #[must_use]
602    pub const fn difference(self, other: Self) -> Self {
603        Self(self.0 & !other.0)
604    }
605
606    #[inline]
607    #[must_use]
608    pub const fn complement(self) -> Self {
609        Self(!self.0)
610    }
611
612    #[inline]
613    #[must_use]
614    pub const fn symmetric_difference(self, other: Self) -> Self {
615        Self(self.0 ^ other.0)
616    }
617
618    #[inline]
619    pub const fn all_known() -> Self {
620        #[allow(clippy::eq_op, clippy::identity_op)]
621        Self(0 | 1 | 2 | 4)
622    }
623}
624
625impl Iterator for WlSeatCapabilityIter {
626    type Item = WlSeatCapability;
627
628    fn next(&mut self) -> Option<Self::Item> {
629        if self.0 == 0 {
630            return None;
631        }
632        let bit = 1 << self.0.trailing_zeros();
633        self.0 &= !bit;
634        Some(WlSeatCapability(bit))
635    }
636}
637
638impl IntoIterator for WlSeatCapability {
639    type Item = WlSeatCapability;
640    type IntoIter = WlSeatCapabilityIter;
641
642    fn into_iter(self) -> Self::IntoIter {
643        WlSeatCapabilityIter(self.0)
644    }
645}
646
647impl BitAnd for WlSeatCapability {
648    type Output = Self;
649
650    fn bitand(self, rhs: Self) -> Self::Output {
651        self.intersection(rhs)
652    }
653}
654
655impl BitAndAssign for WlSeatCapability {
656    fn bitand_assign(&mut self, rhs: Self) {
657        *self = self.intersection(rhs);
658    }
659}
660
661impl BitOr for WlSeatCapability {
662    type Output = Self;
663
664    fn bitor(self, rhs: Self) -> Self::Output {
665        self.union(rhs)
666    }
667}
668
669impl BitOrAssign for WlSeatCapability {
670    fn bitor_assign(&mut self, rhs: Self) {
671        *self = self.union(rhs);
672    }
673}
674
675impl BitXor for WlSeatCapability {
676    type Output = Self;
677
678    fn bitxor(self, rhs: Self) -> Self::Output {
679        self.symmetric_difference(rhs)
680    }
681}
682
683impl BitXorAssign for WlSeatCapability {
684    fn bitxor_assign(&mut self, rhs: Self) {
685        *self = self.symmetric_difference(rhs);
686    }
687}
688
689impl Sub for WlSeatCapability {
690    type Output = Self;
691
692    fn sub(self, rhs: Self) -> Self::Output {
693        self.difference(rhs)
694    }
695}
696
697impl SubAssign for WlSeatCapability {
698    fn sub_assign(&mut self, rhs: Self) {
699        *self = self.difference(rhs);
700    }
701}
702
703impl Not for WlSeatCapability {
704    type Output = Self;
705
706    fn not(self) -> Self::Output {
707        self.complement()
708    }
709}
710
711impl Debug for WlSeatCapability {
712    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
713        let mut v = self.0;
714        let mut first = true;
715        if v & 1 == 1 {
716            v &= !1;
717            if first {
718                first = false;
719            } else {
720                f.write_str(" | ")?;
721            }
722            f.write_str("POINTER")?;
723        }
724        if v & 2 == 2 {
725            v &= !2;
726            if first {
727                first = false;
728            } else {
729                f.write_str(" | ")?;
730            }
731            f.write_str("KEYBOARD")?;
732        }
733        if v & 4 == 4 {
734            v &= !4;
735            if first {
736                first = false;
737            } else {
738                f.write_str(" | ")?;
739            }
740            f.write_str("TOUCH")?;
741        }
742        if v != 0 {
743            if first {
744                first = false;
745            } else {
746                f.write_str(" | ")?;
747            }
748            write!(f, "0x{v:032x}")?;
749        }
750        if first {
751            f.write_str("0")?;
752        }
753        Ok(())
754    }
755}
756
757/// wl_seat error values
758///
759/// These errors can be emitted in response to wl_seat requests.
760#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
761#[allow(dead_code)]
762pub struct WlSeatError(pub u32);
763
764impl WlSeatError {
765    /// get_pointer, get_keyboard or get_touch called on seat without the matching capability
766    #[allow(dead_code)]
767    pub const MISSING_CAPABILITY: Self = Self(0);
768}
769
770impl Debug for WlSeatError {
771    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
772        let name = match *self {
773            Self::MISSING_CAPABILITY => "MISSING_CAPABILITY",
774            _ => return Debug::fmt(&self.0, f),
775        };
776        f.write_str(name)
777    }
778}
779
780/// Functional event handlers.
781pub mod event_handlers {
782    use super::*;
783
784    /// Event handler for capabilities events.
785    pub struct Capabilities<F>(F);
786    impl<F> WlSeatEventHandler for Capabilities<F>
787    where
788        F: Fn(&WlSeatRef, WlSeatCapability),
789    {
790        #[inline]
791        fn capabilities(&self, _slf: &WlSeatRef, capabilities: WlSeatCapability) {
792            self.0(_slf, capabilities)
793        }
794    }
795
796    /// Event handler for name events.
797    pub struct Name<F>(F);
798    impl<F> WlSeatEventHandler for Name<F>
799    where
800        F: Fn(&WlSeatRef, &str),
801    {
802        #[inline]
803        fn name(&self, _slf: &WlSeatRef, name: &str) {
804            self.0(_slf, name)
805        }
806    }
807
808    impl WlSeat {
809        /// Creates an event handler for capabilities events.
810        ///
811        /// The event handler ignores all other events.
812        #[allow(dead_code)]
813        pub fn on_capabilities<F>(f: F) -> Capabilities<F>
814        where
815            F: Fn(&WlSeatRef, WlSeatCapability),
816        {
817            Capabilities(f)
818        }
819
820        /// Creates an event handler for name events.
821        ///
822        /// The event handler ignores all other events.
823        #[allow(dead_code)]
824        pub fn on_name<F>(f: F) -> Name<F>
825        where
826            F: Fn(&WlSeatRef, &str),
827        {
828            Name(f)
829        }
830    }
831}