poll_integration/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 slf: &UntypedBorrowedProxy,
454 opcode: u32,
455 args: *mut wl_argument,
456 ) {
457 // SAFETY: This function required that slf has the interface INTERFACE
458 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlSeatRef>(slf) };
459 match opcode {
460 0 => {
461 // SAFETY: INTERFACE requires that there are 1 arguments
462 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
463 // SAFETY: - INTERFACE requires that args[0] contains a uint
464 let arg0 = unsafe { WlSeatCapability(args[0].u) };
465 self.0.capabilities(slf, arg0);
466 }
467 1 => {
468 // SAFETY: INTERFACE requires that there are 1 arguments
469 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
470 // SAFETY: - INTERFACE requires that args[0] contains a string
471 // - if the pointer is not null, then it is a c string
472 let arg0 = unsafe { convert_string_arg("wl_seat", "name", args[0].s) };
473 self.0.name(slf, arg0);
474 }
475 _ => {
476 invalid_opcode("wl_seat", opcode);
477 }
478 }
479 }
480}
481
482impl<H> CreateEventHandler<H> for private::ProxyApi
483where
484 H: WlSeatEventHandler,
485{
486 type EventHandler = private::EventHandler<H>;
487
488 #[inline]
489 fn create_event_handler(handler: H) -> Self::EventHandler {
490 private::EventHandler(handler)
491 }
492}
493
494impl WlSeat {
495 /// Since when the capability.pointer enum variant is available.
496 #[allow(dead_code)]
497 pub const ENM__CAPABILITY_POINTER__SINCE: u32 = 1;
498 /// Since when the capability.keyboard enum variant is available.
499 #[allow(dead_code)]
500 pub const ENM__CAPABILITY_KEYBOARD__SINCE: u32 = 1;
501 /// Since when the capability.touch enum variant is available.
502 #[allow(dead_code)]
503 pub const ENM__CAPABILITY_TOUCH__SINCE: u32 = 1;
504
505 /// Since when the error.missing_capability enum variant is available.
506 #[allow(dead_code)]
507 pub const ENM__ERROR_MISSING_CAPABILITY__SINCE: u32 = 1;
508}
509
510/// seat capability bitmask
511///
512/// This is a bitmask of capabilities this seat has; if a member is
513/// set, then it is present on the seat.
514#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
515#[allow(dead_code)]
516pub struct WlSeatCapability(pub u32);
517
518/// An iterator over the set bits in a [WlSeatCapability].
519///
520/// You can construct this with the `IntoIterator` implementation of `WlSeatCapability`.
521#[derive(Clone, Debug)]
522pub struct WlSeatCapabilityIter(pub u32);
523
524impl WlSeatCapability {
525 /// the seat has pointer devices
526 #[allow(dead_code)]
527 pub const POINTER: Self = Self(1);
528
529 /// the seat has one or more keyboards
530 #[allow(dead_code)]
531 pub const KEYBOARD: Self = Self(2);
532
533 /// the seat has touch devices
534 #[allow(dead_code)]
535 pub const TOUCH: Self = Self(4);
536}
537
538#[allow(dead_code)]
539impl WlSeatCapability {
540 #[inline]
541 pub const fn empty() -> Self {
542 Self(0)
543 }
544
545 #[inline]
546 #[must_use]
547 pub const fn is_empty(self) -> bool {
548 self.0 == 0
549 }
550
551 #[inline]
552 #[must_use]
553 pub const fn contains(self, other: Self) -> bool {
554 self.0 & other.0 == other.0
555 }
556
557 #[inline]
558 #[must_use]
559 pub const fn intersects(self, other: Self) -> bool {
560 self.0 & other.0 != 0
561 }
562
563 #[inline]
564 pub const fn insert(&mut self, other: Self) {
565 *self = self.union(other);
566 }
567
568 #[inline]
569 pub const fn remove(&mut self, other: Self) {
570 *self = self.difference(other);
571 }
572
573 #[inline]
574 pub const fn toggle(&mut self, other: Self) {
575 *self = self.symmetric_difference(other);
576 }
577
578 #[inline]
579 pub const fn set(&mut self, other: Self, value: bool) {
580 if value {
581 self.insert(other);
582 } else {
583 self.remove(other);
584 }
585 }
586
587 #[inline]
588 #[must_use]
589 pub const fn intersection(self, other: Self) -> Self {
590 Self(self.0 & other.0)
591 }
592
593 #[inline]
594 #[must_use]
595 pub const fn union(self, other: Self) -> Self {
596 Self(self.0 | other.0)
597 }
598
599 #[inline]
600 #[must_use]
601 pub const fn difference(self, other: Self) -> Self {
602 Self(self.0 & !other.0)
603 }
604
605 #[inline]
606 #[must_use]
607 pub const fn complement(self) -> Self {
608 Self(!self.0)
609 }
610
611 #[inline]
612 #[must_use]
613 pub const fn symmetric_difference(self, other: Self) -> Self {
614 Self(self.0 ^ other.0)
615 }
616
617 #[inline]
618 pub const fn all_known() -> Self {
619 #[allow(clippy::eq_op, clippy::identity_op)]
620 Self(0 | 1 | 2 | 4)
621 }
622}
623
624impl Iterator for WlSeatCapabilityIter {
625 type Item = WlSeatCapability;
626
627 fn next(&mut self) -> Option<Self::Item> {
628 if self.0 == 0 {
629 return None;
630 }
631 let bit = 1 << self.0.trailing_zeros();
632 self.0 &= !bit;
633 Some(WlSeatCapability(bit))
634 }
635}
636
637impl IntoIterator for WlSeatCapability {
638 type Item = WlSeatCapability;
639 type IntoIter = WlSeatCapabilityIter;
640
641 fn into_iter(self) -> Self::IntoIter {
642 WlSeatCapabilityIter(self.0)
643 }
644}
645
646impl BitAnd for WlSeatCapability {
647 type Output = Self;
648
649 fn bitand(self, rhs: Self) -> Self::Output {
650 self.intersection(rhs)
651 }
652}
653
654impl BitAndAssign for WlSeatCapability {
655 fn bitand_assign(&mut self, rhs: Self) {
656 *self = self.intersection(rhs);
657 }
658}
659
660impl BitOr for WlSeatCapability {
661 type Output = Self;
662
663 fn bitor(self, rhs: Self) -> Self::Output {
664 self.union(rhs)
665 }
666}
667
668impl BitOrAssign for WlSeatCapability {
669 fn bitor_assign(&mut self, rhs: Self) {
670 *self = self.union(rhs);
671 }
672}
673
674impl BitXor for WlSeatCapability {
675 type Output = Self;
676
677 fn bitxor(self, rhs: Self) -> Self::Output {
678 self.symmetric_difference(rhs)
679 }
680}
681
682impl BitXorAssign for WlSeatCapability {
683 fn bitxor_assign(&mut self, rhs: Self) {
684 *self = self.symmetric_difference(rhs);
685 }
686}
687
688impl Sub for WlSeatCapability {
689 type Output = Self;
690
691 fn sub(self, rhs: Self) -> Self::Output {
692 self.difference(rhs)
693 }
694}
695
696impl SubAssign for WlSeatCapability {
697 fn sub_assign(&mut self, rhs: Self) {
698 *self = self.difference(rhs);
699 }
700}
701
702impl Not for WlSeatCapability {
703 type Output = Self;
704
705 fn not(self) -> Self::Output {
706 self.complement()
707 }
708}
709
710impl Debug for WlSeatCapability {
711 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
712 let mut v = self.0;
713 let mut first = true;
714 if v & 1 == 1 {
715 v &= !1;
716 if first {
717 first = false;
718 } else {
719 f.write_str(" | ")?;
720 }
721 f.write_str("POINTER")?;
722 }
723 if v & 2 == 2 {
724 v &= !2;
725 if first {
726 first = false;
727 } else {
728 f.write_str(" | ")?;
729 }
730 f.write_str("KEYBOARD")?;
731 }
732 if v & 4 == 4 {
733 v &= !4;
734 if first {
735 first = false;
736 } else {
737 f.write_str(" | ")?;
738 }
739 f.write_str("TOUCH")?;
740 }
741 if v != 0 {
742 if first {
743 first = false;
744 } else {
745 f.write_str(" | ")?;
746 }
747 write!(f, "0x{v:032x}")?;
748 }
749 if first {
750 f.write_str("0")?;
751 }
752 Ok(())
753 }
754}
755
756/// wl_seat error values
757///
758/// These errors can be emitted in response to wl_seat requests.
759#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
760#[allow(dead_code)]
761pub struct WlSeatError(pub u32);
762
763impl WlSeatError {
764 /// get_pointer, get_keyboard or get_touch called on seat without the matching capability
765 #[allow(dead_code)]
766 pub const MISSING_CAPABILITY: Self = Self(0);
767}
768
769impl Debug for WlSeatError {
770 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
771 let name = match *self {
772 Self::MISSING_CAPABILITY => "MISSING_CAPABILITY",
773 _ => return Debug::fmt(&self.0, f),
774 };
775 f.write_str(name)
776 }
777}
778
779/// Functional event handlers.
780pub mod event_handlers {
781 use super::*;
782
783 /// Event handler for capabilities events.
784 pub struct Capabilities<F>(F);
785 impl<F> WlSeatEventHandler for Capabilities<F>
786 where
787 F: Fn(&WlSeatRef, WlSeatCapability),
788 {
789 #[inline]
790 fn capabilities(&self, _slf: &WlSeatRef, capabilities: WlSeatCapability) {
791 self.0(_slf, capabilities)
792 }
793 }
794
795 /// Event handler for name events.
796 pub struct Name<F>(F);
797 impl<F> WlSeatEventHandler for Name<F>
798 where
799 F: Fn(&WlSeatRef, &str),
800 {
801 #[inline]
802 fn name(&self, _slf: &WlSeatRef, name: &str) {
803 self.0(_slf, name)
804 }
805 }
806
807 impl WlSeat {
808 /// Creates an event handler for capabilities events.
809 ///
810 /// The event handler ignores all other events.
811 #[allow(dead_code)]
812 pub fn on_capabilities<F>(f: F) -> Capabilities<F>
813 where
814 F: Fn(&WlSeatRef, WlSeatCapability),
815 {
816 Capabilities(f)
817 }
818
819 /// Creates an event handler for name events.
820 ///
821 /// The event handler ignores all other events.
822 #[allow(dead_code)]
823 pub fn on_name<F>(f: F) -> Name<F>
824 where
825 F: Fn(&WlSeatRef, &str),
826 {
827 Name(f)
828 }
829 }
830}