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}