wl_proxy/protocols/wayland/
wl_keyboard.rs

1//! keyboard input device
2//!
3//! The wl_keyboard interface represents one or more keyboards
4//! associated with a seat.
5//!
6//! Each wl_keyboard has the following logical state:
7//!
8//! - an active surface (possibly null),
9//! - the keys currently logically down,
10//! - the active modifiers,
11//! - the active group.
12//!
13//! By default, the active surface is null, the keys currently logically down
14//! are empty, the active modifiers and the active group are 0.
15
16use crate::protocol_helpers::prelude::*;
17use super::super::all_types::*;
18
19/// A wl_keyboard object.
20///
21/// See the documentation of [the module][self] for the interface description.
22pub struct WlKeyboard {
23    core: ObjectCore,
24    handler: HandlerHolder<dyn WlKeyboardHandler>,
25}
26
27struct DefaultHandler;
28
29impl WlKeyboardHandler for DefaultHandler { }
30
31impl ConcreteObject for WlKeyboard {
32    const XML_VERSION: u32 = 10;
33    const INTERFACE: ObjectInterface = ObjectInterface::WlKeyboard;
34    const INTERFACE_NAME: &str = "wl_keyboard";
35}
36
37impl WlKeyboard {
38    /// Sets a new handler.
39    pub fn set_handler(&self, handler: impl WlKeyboardHandler) {
40        self.set_boxed_handler(Box::new(handler));
41    }
42
43    /// Sets a new, already boxed handler.
44    pub fn set_boxed_handler(&self, handler: Box<dyn WlKeyboardHandler>) {
45        if self.core.state.destroyed.get() {
46            return;
47        }
48        self.handler.set(Some(handler));
49    }
50}
51
52impl Debug for WlKeyboard {
53    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
54        f.debug_struct("WlKeyboard")
55            .field("server_obj_id", &self.core.server_obj_id.get())
56            .field("client_id", &self.core.client_id.get())
57            .field("client_obj_id", &self.core.client_obj_id.get())
58            .finish()
59    }
60}
61
62impl WlKeyboard {
63    /// Since when the keymap message is available.
64    pub const MSG__KEYMAP__SINCE: u32 = 1;
65
66    /// keyboard mapping
67    ///
68    /// This event provides a file descriptor to the client which can be
69    /// memory-mapped in read-only mode to provide a keyboard mapping
70    /// description.
71    ///
72    /// From version 7 onwards, the fd must be mapped with MAP_PRIVATE by
73    /// the recipient, as MAP_SHARED may fail.
74    ///
75    /// # Arguments
76    ///
77    /// - `format`: keymap format
78    /// - `fd`: keymap file descriptor
79    /// - `size`: keymap size, in bytes
80    #[inline]
81    pub fn try_send_keymap(
82        &self,
83        format: WlKeyboardKeymapFormat,
84        fd: &Rc<OwnedFd>,
85        size: u32,
86    ) -> Result<(), ObjectError> {
87        let (
88            arg0,
89            arg1,
90            arg2,
91        ) = (
92            format,
93            fd,
94            size,
95        );
96        let core = self.core();
97        let client_ref = core.client.borrow();
98        let Some(client) = &*client_ref else {
99            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
100        };
101        let id = core.client_obj_id.get().unwrap_or(0);
102        #[cfg(feature = "logging")]
103        if self.core.state.log {
104            #[cold]
105            fn log(state: &State, client_id: u64, id: u32, arg0: WlKeyboardKeymapFormat, arg1: i32, arg2: u32) {
106                let (millis, micros) = time_since_epoch();
107                let prefix = &state.log_prefix;
108                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_keyboard#{}.keymap(format: {:?}, fd: {}, size: {})\n", client_id, id, arg0, arg1, arg2);
109                state.log(args);
110            }
111            log(&self.core.state, client.endpoint.id, id, arg0, arg1.as_raw_fd(), arg2);
112        }
113        let endpoint = &client.endpoint;
114        if !endpoint.flush_queued.replace(true) {
115            self.core.state.add_flushable_endpoint(endpoint, Some(client));
116        }
117        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
118        let outgoing = &mut *outgoing_ref;
119        let mut fmt = outgoing.formatter();
120        fmt.fds.push_back(arg1.clone());
121        fmt.words([
122            id,
123            0,
124            arg0.0,
125            arg2,
126        ]);
127        Ok(())
128    }
129
130    /// keyboard mapping
131    ///
132    /// This event provides a file descriptor to the client which can be
133    /// memory-mapped in read-only mode to provide a keyboard mapping
134    /// description.
135    ///
136    /// From version 7 onwards, the fd must be mapped with MAP_PRIVATE by
137    /// the recipient, as MAP_SHARED may fail.
138    ///
139    /// # Arguments
140    ///
141    /// - `format`: keymap format
142    /// - `fd`: keymap file descriptor
143    /// - `size`: keymap size, in bytes
144    #[inline]
145    pub fn send_keymap(
146        &self,
147        format: WlKeyboardKeymapFormat,
148        fd: &Rc<OwnedFd>,
149        size: u32,
150    ) {
151        let res = self.try_send_keymap(
152            format,
153            fd,
154            size,
155        );
156        if let Err(e) = res {
157            log_send("wl_keyboard.keymap", &e);
158        }
159    }
160
161    /// Since when the enter message is available.
162    pub const MSG__ENTER__SINCE: u32 = 1;
163
164    /// enter event
165    ///
166    /// Notification that this seat's keyboard focus is on a certain
167    /// surface.
168    ///
169    /// The compositor must send the wl_keyboard.modifiers event after this
170    /// event.
171    ///
172    /// In the wl_keyboard logical state, this event sets the active surface to
173    /// the surface argument and the keys currently logically down to the keys
174    /// in the keys argument. The compositor must not send this event if the
175    /// wl_keyboard already had an active surface immediately before this event.
176    ///
177    /// Clients should not use the list of pressed keys to emulate key-press
178    /// events. The order of keys in the list is unspecified.
179    ///
180    /// # Arguments
181    ///
182    /// - `serial`: serial number of the enter event
183    /// - `surface`: surface gaining keyboard focus
184    /// - `keys`: the keys currently logically down
185    #[inline]
186    pub fn try_send_enter(
187        &self,
188        serial: u32,
189        surface: &Rc<WlSurface>,
190        keys: &[u8],
191    ) -> Result<(), ObjectError> {
192        let (
193            arg0,
194            arg1,
195            arg2,
196        ) = (
197            serial,
198            surface,
199            keys,
200        );
201        let arg1 = arg1.core();
202        let core = self.core();
203        let client_ref = core.client.borrow();
204        let Some(client) = &*client_ref else {
205            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
206        };
207        let id = core.client_obj_id.get().unwrap_or(0);
208        if arg1.client_id.get() != Some(client.endpoint.id) {
209            return Err(ObjectError(ObjectErrorKind::ArgNoClientId("surface", client.endpoint.id)));
210        }
211        let arg1_id = arg1.client_obj_id.get().unwrap_or(0);
212        #[cfg(feature = "logging")]
213        if self.core.state.log {
214            #[cold]
215            fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: u32, arg2: &[u8]) {
216                let (millis, micros) = time_since_epoch();
217                let prefix = &state.log_prefix;
218                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_keyboard#{}.enter(serial: {}, surface: wl_surface#{}, keys: {})\n", client_id, id, arg0, arg1, debug_array(arg2));
219                state.log(args);
220            }
221            log(&self.core.state, client.endpoint.id, id, arg0, arg1_id, arg2);
222        }
223        let endpoint = &client.endpoint;
224        if !endpoint.flush_queued.replace(true) {
225            self.core.state.add_flushable_endpoint(endpoint, Some(client));
226        }
227        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
228        let outgoing = &mut *outgoing_ref;
229        let mut fmt = outgoing.formatter();
230        fmt.words([
231            id,
232            1,
233            arg0,
234            arg1_id,
235        ]);
236        fmt.array(arg2);
237        Ok(())
238    }
239
240    /// enter event
241    ///
242    /// Notification that this seat's keyboard focus is on a certain
243    /// surface.
244    ///
245    /// The compositor must send the wl_keyboard.modifiers event after this
246    /// event.
247    ///
248    /// In the wl_keyboard logical state, this event sets the active surface to
249    /// the surface argument and the keys currently logically down to the keys
250    /// in the keys argument. The compositor must not send this event if the
251    /// wl_keyboard already had an active surface immediately before this event.
252    ///
253    /// Clients should not use the list of pressed keys to emulate key-press
254    /// events. The order of keys in the list is unspecified.
255    ///
256    /// # Arguments
257    ///
258    /// - `serial`: serial number of the enter event
259    /// - `surface`: surface gaining keyboard focus
260    /// - `keys`: the keys currently logically down
261    #[inline]
262    pub fn send_enter(
263        &self,
264        serial: u32,
265        surface: &Rc<WlSurface>,
266        keys: &[u8],
267    ) {
268        let res = self.try_send_enter(
269            serial,
270            surface,
271            keys,
272        );
273        if let Err(e) = res {
274            log_send("wl_keyboard.enter", &e);
275        }
276    }
277
278    /// Since when the leave message is available.
279    pub const MSG__LEAVE__SINCE: u32 = 1;
280
281    /// leave event
282    ///
283    /// Notification that this seat's keyboard focus is no longer on
284    /// a certain surface.
285    ///
286    /// The leave notification is sent before the enter notification
287    /// for the new focus.
288    ///
289    /// In the wl_keyboard logical state, this event resets all values to their
290    /// defaults. The compositor must not send this event if the active surface
291    /// of the wl_keyboard was not equal to the surface argument immediately
292    /// before this event.
293    ///
294    /// # Arguments
295    ///
296    /// - `serial`: serial number of the leave event
297    /// - `surface`: surface that lost keyboard focus
298    #[inline]
299    pub fn try_send_leave(
300        &self,
301        serial: u32,
302        surface: &Rc<WlSurface>,
303    ) -> Result<(), ObjectError> {
304        let (
305            arg0,
306            arg1,
307        ) = (
308            serial,
309            surface,
310        );
311        let arg1 = arg1.core();
312        let core = self.core();
313        let client_ref = core.client.borrow();
314        let Some(client) = &*client_ref else {
315            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
316        };
317        let id = core.client_obj_id.get().unwrap_or(0);
318        if arg1.client_id.get() != Some(client.endpoint.id) {
319            return Err(ObjectError(ObjectErrorKind::ArgNoClientId("surface", client.endpoint.id)));
320        }
321        let arg1_id = arg1.client_obj_id.get().unwrap_or(0);
322        #[cfg(feature = "logging")]
323        if self.core.state.log {
324            #[cold]
325            fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: u32) {
326                let (millis, micros) = time_since_epoch();
327                let prefix = &state.log_prefix;
328                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_keyboard#{}.leave(serial: {}, surface: wl_surface#{})\n", client_id, id, arg0, arg1);
329                state.log(args);
330            }
331            log(&self.core.state, client.endpoint.id, id, arg0, arg1_id);
332        }
333        let endpoint = &client.endpoint;
334        if !endpoint.flush_queued.replace(true) {
335            self.core.state.add_flushable_endpoint(endpoint, Some(client));
336        }
337        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
338        let outgoing = &mut *outgoing_ref;
339        let mut fmt = outgoing.formatter();
340        fmt.words([
341            id,
342            2,
343            arg0,
344            arg1_id,
345        ]);
346        Ok(())
347    }
348
349    /// leave event
350    ///
351    /// Notification that this seat's keyboard focus is no longer on
352    /// a certain surface.
353    ///
354    /// The leave notification is sent before the enter notification
355    /// for the new focus.
356    ///
357    /// In the wl_keyboard logical state, this event resets all values to their
358    /// defaults. The compositor must not send this event if the active surface
359    /// of the wl_keyboard was not equal to the surface argument immediately
360    /// before this event.
361    ///
362    /// # Arguments
363    ///
364    /// - `serial`: serial number of the leave event
365    /// - `surface`: surface that lost keyboard focus
366    #[inline]
367    pub fn send_leave(
368        &self,
369        serial: u32,
370        surface: &Rc<WlSurface>,
371    ) {
372        let res = self.try_send_leave(
373            serial,
374            surface,
375        );
376        if let Err(e) = res {
377            log_send("wl_keyboard.leave", &e);
378        }
379    }
380
381    /// Since when the key message is available.
382    pub const MSG__KEY__SINCE: u32 = 1;
383
384    /// key event
385    ///
386    /// A key was pressed or released.
387    /// The time argument is a timestamp with millisecond
388    /// granularity, with an undefined base.
389    ///
390    /// The key is a platform-specific key code that can be interpreted
391    /// by feeding it to the keyboard mapping (see the keymap event).
392    ///
393    /// If this event produces a change in modifiers, then the resulting
394    /// wl_keyboard.modifiers event must be sent after this event.
395    ///
396    /// In the wl_keyboard logical state, this event adds the key to the keys
397    /// currently logically down (if the state argument is pressed) or removes
398    /// the key from the keys currently logically down (if the state argument is
399    /// released). The compositor must not send this event if the wl_keyboard
400    /// did not have an active surface immediately before this event. The
401    /// compositor must not send this event if state is pressed (resp. released)
402    /// and the key was already logically down (resp. was not logically down)
403    /// immediately before this event.
404    ///
405    /// Since version 10, compositors may send key events with the "repeated"
406    /// key state when a wl_keyboard.repeat_info event with a rate argument of
407    /// 0 has been received. This allows the compositor to take over the
408    /// responsibility of key repetition.
409    ///
410    /// # Arguments
411    ///
412    /// - `serial`: serial number of the key event
413    /// - `time`: timestamp with millisecond granularity
414    /// - `key`: key that produced the event
415    /// - `state`: physical state of the key
416    #[inline]
417    pub fn try_send_key(
418        &self,
419        serial: u32,
420        time: u32,
421        key: u32,
422        state: WlKeyboardKeyState,
423    ) -> Result<(), ObjectError> {
424        let (
425            arg0,
426            arg1,
427            arg2,
428            arg3,
429        ) = (
430            serial,
431            time,
432            key,
433            state,
434        );
435        let core = self.core();
436        let client_ref = core.client.borrow();
437        let Some(client) = &*client_ref else {
438            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
439        };
440        let id = core.client_obj_id.get().unwrap_or(0);
441        #[cfg(feature = "logging")]
442        if self.core.state.log {
443            #[cold]
444            fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: u32, arg2: u32, arg3: WlKeyboardKeyState) {
445                let (millis, micros) = time_since_epoch();
446                let prefix = &state.log_prefix;
447                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_keyboard#{}.key(serial: {}, time: {}, key: {}, state: {:?})\n", client_id, id, arg0, arg1, arg2, arg3);
448                state.log(args);
449            }
450            log(&self.core.state, client.endpoint.id, id, arg0, arg1, arg2, arg3);
451        }
452        let endpoint = &client.endpoint;
453        if !endpoint.flush_queued.replace(true) {
454            self.core.state.add_flushable_endpoint(endpoint, Some(client));
455        }
456        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
457        let outgoing = &mut *outgoing_ref;
458        let mut fmt = outgoing.formatter();
459        fmt.words([
460            id,
461            3,
462            arg0,
463            arg1,
464            arg2,
465            arg3.0,
466        ]);
467        Ok(())
468    }
469
470    /// key event
471    ///
472    /// A key was pressed or released.
473    /// The time argument is a timestamp with millisecond
474    /// granularity, with an undefined base.
475    ///
476    /// The key is a platform-specific key code that can be interpreted
477    /// by feeding it to the keyboard mapping (see the keymap event).
478    ///
479    /// If this event produces a change in modifiers, then the resulting
480    /// wl_keyboard.modifiers event must be sent after this event.
481    ///
482    /// In the wl_keyboard logical state, this event adds the key to the keys
483    /// currently logically down (if the state argument is pressed) or removes
484    /// the key from the keys currently logically down (if the state argument is
485    /// released). The compositor must not send this event if the wl_keyboard
486    /// did not have an active surface immediately before this event. The
487    /// compositor must not send this event if state is pressed (resp. released)
488    /// and the key was already logically down (resp. was not logically down)
489    /// immediately before this event.
490    ///
491    /// Since version 10, compositors may send key events with the "repeated"
492    /// key state when a wl_keyboard.repeat_info event with a rate argument of
493    /// 0 has been received. This allows the compositor to take over the
494    /// responsibility of key repetition.
495    ///
496    /// # Arguments
497    ///
498    /// - `serial`: serial number of the key event
499    /// - `time`: timestamp with millisecond granularity
500    /// - `key`: key that produced the event
501    /// - `state`: physical state of the key
502    #[inline]
503    pub fn send_key(
504        &self,
505        serial: u32,
506        time: u32,
507        key: u32,
508        state: WlKeyboardKeyState,
509    ) {
510        let res = self.try_send_key(
511            serial,
512            time,
513            key,
514            state,
515        );
516        if let Err(e) = res {
517            log_send("wl_keyboard.key", &e);
518        }
519    }
520
521    /// Since when the modifiers message is available.
522    pub const MSG__MODIFIERS__SINCE: u32 = 1;
523
524    /// modifier and group state
525    ///
526    /// Notifies clients that the modifier and/or group state has
527    /// changed, and it should update its local state.
528    ///
529    /// The compositor may send this event without a surface of the client
530    /// having keyboard focus, for example to tie modifier information to
531    /// pointer focus instead. If a modifier event with pressed modifiers is sent
532    /// without a prior enter event, the client can assume the modifier state is
533    /// valid until it receives the next wl_keyboard.modifiers event. In order to
534    /// reset the modifier state again, the compositor can send a
535    /// wl_keyboard.modifiers event with no pressed modifiers.
536    ///
537    /// In the wl_keyboard logical state, this event updates the modifiers and
538    /// group.
539    ///
540    /// # Arguments
541    ///
542    /// - `serial`: serial number of the modifiers event
543    /// - `mods_depressed`: depressed modifiers
544    /// - `mods_latched`: latched modifiers
545    /// - `mods_locked`: locked modifiers
546    /// - `group`: keyboard layout
547    #[inline]
548    pub fn try_send_modifiers(
549        &self,
550        serial: u32,
551        mods_depressed: u32,
552        mods_latched: u32,
553        mods_locked: u32,
554        group: u32,
555    ) -> Result<(), ObjectError> {
556        let (
557            arg0,
558            arg1,
559            arg2,
560            arg3,
561            arg4,
562        ) = (
563            serial,
564            mods_depressed,
565            mods_latched,
566            mods_locked,
567            group,
568        );
569        let core = self.core();
570        let client_ref = core.client.borrow();
571        let Some(client) = &*client_ref else {
572            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
573        };
574        let id = core.client_obj_id.get().unwrap_or(0);
575        #[cfg(feature = "logging")]
576        if self.core.state.log {
577            #[cold]
578            fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: u32, arg2: u32, arg3: u32, arg4: u32) {
579                let (millis, micros) = time_since_epoch();
580                let prefix = &state.log_prefix;
581                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_keyboard#{}.modifiers(serial: {}, mods_depressed: {}, mods_latched: {}, mods_locked: {}, group: {})\n", client_id, id, arg0, arg1, arg2, arg3, arg4);
582                state.log(args);
583            }
584            log(&self.core.state, client.endpoint.id, id, arg0, arg1, arg2, arg3, arg4);
585        }
586        let endpoint = &client.endpoint;
587        if !endpoint.flush_queued.replace(true) {
588            self.core.state.add_flushable_endpoint(endpoint, Some(client));
589        }
590        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
591        let outgoing = &mut *outgoing_ref;
592        let mut fmt = outgoing.formatter();
593        fmt.words([
594            id,
595            4,
596            arg0,
597            arg1,
598            arg2,
599            arg3,
600            arg4,
601        ]);
602        Ok(())
603    }
604
605    /// modifier and group state
606    ///
607    /// Notifies clients that the modifier and/or group state has
608    /// changed, and it should update its local state.
609    ///
610    /// The compositor may send this event without a surface of the client
611    /// having keyboard focus, for example to tie modifier information to
612    /// pointer focus instead. If a modifier event with pressed modifiers is sent
613    /// without a prior enter event, the client can assume the modifier state is
614    /// valid until it receives the next wl_keyboard.modifiers event. In order to
615    /// reset the modifier state again, the compositor can send a
616    /// wl_keyboard.modifiers event with no pressed modifiers.
617    ///
618    /// In the wl_keyboard logical state, this event updates the modifiers and
619    /// group.
620    ///
621    /// # Arguments
622    ///
623    /// - `serial`: serial number of the modifiers event
624    /// - `mods_depressed`: depressed modifiers
625    /// - `mods_latched`: latched modifiers
626    /// - `mods_locked`: locked modifiers
627    /// - `group`: keyboard layout
628    #[inline]
629    pub fn send_modifiers(
630        &self,
631        serial: u32,
632        mods_depressed: u32,
633        mods_latched: u32,
634        mods_locked: u32,
635        group: u32,
636    ) {
637        let res = self.try_send_modifiers(
638            serial,
639            mods_depressed,
640            mods_latched,
641            mods_locked,
642            group,
643        );
644        if let Err(e) = res {
645            log_send("wl_keyboard.modifiers", &e);
646        }
647    }
648
649    /// Since when the release message is available.
650    pub const MSG__RELEASE__SINCE: u32 = 3;
651
652    /// release the keyboard object
653    #[inline]
654    pub fn try_send_release(
655        &self,
656    ) -> Result<(), ObjectError> {
657        let core = self.core();
658        let Some(id) = core.server_obj_id.get() else {
659            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
660        };
661        #[cfg(feature = "logging")]
662        if self.core.state.log {
663            #[cold]
664            fn log(state: &State, id: u32) {
665                let (millis, micros) = time_since_epoch();
666                let prefix = &state.log_prefix;
667                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_keyboard#{}.release()\n", id);
668                state.log(args);
669            }
670            log(&self.core.state, id);
671        }
672        let Some(endpoint) = &self.core.state.server else {
673            return Ok(());
674        };
675        if !endpoint.flush_queued.replace(true) {
676            self.core.state.add_flushable_endpoint(endpoint, None);
677        }
678        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
679        let outgoing = &mut *outgoing_ref;
680        let mut fmt = outgoing.formatter();
681        fmt.words([
682            id,
683            0,
684        ]);
685        self.core.handle_server_destroy();
686        Ok(())
687    }
688
689    /// release the keyboard object
690    #[inline]
691    pub fn send_release(
692        &self,
693    ) {
694        let res = self.try_send_release(
695        );
696        if let Err(e) = res {
697            log_send("wl_keyboard.release", &e);
698        }
699    }
700
701    /// Since when the repeat_info message is available.
702    pub const MSG__REPEAT_INFO__SINCE: u32 = 4;
703
704    /// repeat rate and delay
705    ///
706    /// Informs the client about the keyboard's repeat rate and delay.
707    ///
708    /// This event is sent as soon as the wl_keyboard object has been created,
709    /// and is guaranteed to be received by the client before any key press
710    /// event.
711    ///
712    /// Negative values for either rate or delay are illegal. A rate of zero
713    /// will disable any repeating (regardless of the value of delay).
714    ///
715    /// This event can be sent later on as well with a new value if necessary,
716    /// so clients should continue listening for the event past the creation
717    /// of wl_keyboard.
718    ///
719    /// # Arguments
720    ///
721    /// - `rate`: the rate of repeating keys in characters per second
722    /// - `delay`: delay in milliseconds since key down until repeating starts
723    #[inline]
724    pub fn try_send_repeat_info(
725        &self,
726        rate: i32,
727        delay: i32,
728    ) -> Result<(), ObjectError> {
729        let (
730            arg0,
731            arg1,
732        ) = (
733            rate,
734            delay,
735        );
736        let core = self.core();
737        let client_ref = core.client.borrow();
738        let Some(client) = &*client_ref else {
739            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
740        };
741        let id = core.client_obj_id.get().unwrap_or(0);
742        #[cfg(feature = "logging")]
743        if self.core.state.log {
744            #[cold]
745            fn log(state: &State, client_id: u64, id: u32, arg0: i32, arg1: i32) {
746                let (millis, micros) = time_since_epoch();
747                let prefix = &state.log_prefix;
748                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_keyboard#{}.repeat_info(rate: {}, delay: {})\n", client_id, id, arg0, arg1);
749                state.log(args);
750            }
751            log(&self.core.state, client.endpoint.id, id, arg0, arg1);
752        }
753        let endpoint = &client.endpoint;
754        if !endpoint.flush_queued.replace(true) {
755            self.core.state.add_flushable_endpoint(endpoint, Some(client));
756        }
757        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
758        let outgoing = &mut *outgoing_ref;
759        let mut fmt = outgoing.formatter();
760        fmt.words([
761            id,
762            5,
763            arg0 as u32,
764            arg1 as u32,
765        ]);
766        Ok(())
767    }
768
769    /// repeat rate and delay
770    ///
771    /// Informs the client about the keyboard's repeat rate and delay.
772    ///
773    /// This event is sent as soon as the wl_keyboard object has been created,
774    /// and is guaranteed to be received by the client before any key press
775    /// event.
776    ///
777    /// Negative values for either rate or delay are illegal. A rate of zero
778    /// will disable any repeating (regardless of the value of delay).
779    ///
780    /// This event can be sent later on as well with a new value if necessary,
781    /// so clients should continue listening for the event past the creation
782    /// of wl_keyboard.
783    ///
784    /// # Arguments
785    ///
786    /// - `rate`: the rate of repeating keys in characters per second
787    /// - `delay`: delay in milliseconds since key down until repeating starts
788    #[inline]
789    pub fn send_repeat_info(
790        &self,
791        rate: i32,
792        delay: i32,
793    ) {
794        let res = self.try_send_repeat_info(
795            rate,
796            delay,
797        );
798        if let Err(e) = res {
799            log_send("wl_keyboard.repeat_info", &e);
800        }
801    }
802}
803
804/// A message handler for [`WlKeyboard`] proxies.
805pub trait WlKeyboardHandler: Any {
806    /// Event handler for wl_display.delete_id messages deleting the ID of this object.
807    ///
808    /// The default handler forwards the event to the client, if any.
809    #[inline]
810    fn delete_id(&mut self, slf: &Rc<WlKeyboard>) {
811        slf.core.delete_id();
812    }
813
814    /// keyboard mapping
815    ///
816    /// This event provides a file descriptor to the client which can be
817    /// memory-mapped in read-only mode to provide a keyboard mapping
818    /// description.
819    ///
820    /// From version 7 onwards, the fd must be mapped with MAP_PRIVATE by
821    /// the recipient, as MAP_SHARED may fail.
822    ///
823    /// # Arguments
824    ///
825    /// - `format`: keymap format
826    /// - `fd`: keymap file descriptor
827    /// - `size`: keymap size, in bytes
828    #[inline]
829    fn handle_keymap(
830        &mut self,
831        slf: &Rc<WlKeyboard>,
832        format: WlKeyboardKeymapFormat,
833        fd: &Rc<OwnedFd>,
834        size: u32,
835    ) {
836        if !slf.core.forward_to_client.get() {
837            return;
838        }
839        let res = slf.try_send_keymap(
840            format,
841            fd,
842            size,
843        );
844        if let Err(e) = res {
845            log_forward("wl_keyboard.keymap", &e);
846        }
847    }
848
849    /// enter event
850    ///
851    /// Notification that this seat's keyboard focus is on a certain
852    /// surface.
853    ///
854    /// The compositor must send the wl_keyboard.modifiers event after this
855    /// event.
856    ///
857    /// In the wl_keyboard logical state, this event sets the active surface to
858    /// the surface argument and the keys currently logically down to the keys
859    /// in the keys argument. The compositor must not send this event if the
860    /// wl_keyboard already had an active surface immediately before this event.
861    ///
862    /// Clients should not use the list of pressed keys to emulate key-press
863    /// events. The order of keys in the list is unspecified.
864    ///
865    /// # Arguments
866    ///
867    /// - `serial`: serial number of the enter event
868    /// - `surface`: surface gaining keyboard focus
869    /// - `keys`: the keys currently logically down
870    ///
871    /// All borrowed proxies passed to this function are guaranteed to be
872    /// immutable and non-null.
873    #[inline]
874    fn handle_enter(
875        &mut self,
876        slf: &Rc<WlKeyboard>,
877        serial: u32,
878        surface: &Rc<WlSurface>,
879        keys: &[u8],
880    ) {
881        if !slf.core.forward_to_client.get() {
882            return;
883        }
884        if let Some(client_id) = slf.core.client_id.get() {
885            if let Some(client_id_2) = surface.core().client_id.get() {
886                if client_id != client_id_2 {
887                    return;
888                }
889            }
890        }
891        let res = slf.try_send_enter(
892            serial,
893            surface,
894            keys,
895        );
896        if let Err(e) = res {
897            log_forward("wl_keyboard.enter", &e);
898        }
899    }
900
901    /// leave event
902    ///
903    /// Notification that this seat's keyboard focus is no longer on
904    /// a certain surface.
905    ///
906    /// The leave notification is sent before the enter notification
907    /// for the new focus.
908    ///
909    /// In the wl_keyboard logical state, this event resets all values to their
910    /// defaults. The compositor must not send this event if the active surface
911    /// of the wl_keyboard was not equal to the surface argument immediately
912    /// before this event.
913    ///
914    /// # Arguments
915    ///
916    /// - `serial`: serial number of the leave event
917    /// - `surface`: surface that lost keyboard focus
918    ///
919    /// All borrowed proxies passed to this function are guaranteed to be
920    /// immutable and non-null.
921    #[inline]
922    fn handle_leave(
923        &mut self,
924        slf: &Rc<WlKeyboard>,
925        serial: u32,
926        surface: &Rc<WlSurface>,
927    ) {
928        if !slf.core.forward_to_client.get() {
929            return;
930        }
931        if let Some(client_id) = slf.core.client_id.get() {
932            if let Some(client_id_2) = surface.core().client_id.get() {
933                if client_id != client_id_2 {
934                    return;
935                }
936            }
937        }
938        let res = slf.try_send_leave(
939            serial,
940            surface,
941        );
942        if let Err(e) = res {
943            log_forward("wl_keyboard.leave", &e);
944        }
945    }
946
947    /// key event
948    ///
949    /// A key was pressed or released.
950    /// The time argument is a timestamp with millisecond
951    /// granularity, with an undefined base.
952    ///
953    /// The key is a platform-specific key code that can be interpreted
954    /// by feeding it to the keyboard mapping (see the keymap event).
955    ///
956    /// If this event produces a change in modifiers, then the resulting
957    /// wl_keyboard.modifiers event must be sent after this event.
958    ///
959    /// In the wl_keyboard logical state, this event adds the key to the keys
960    /// currently logically down (if the state argument is pressed) or removes
961    /// the key from the keys currently logically down (if the state argument is
962    /// released). The compositor must not send this event if the wl_keyboard
963    /// did not have an active surface immediately before this event. The
964    /// compositor must not send this event if state is pressed (resp. released)
965    /// and the key was already logically down (resp. was not logically down)
966    /// immediately before this event.
967    ///
968    /// Since version 10, compositors may send key events with the "repeated"
969    /// key state when a wl_keyboard.repeat_info event with a rate argument of
970    /// 0 has been received. This allows the compositor to take over the
971    /// responsibility of key repetition.
972    ///
973    /// # Arguments
974    ///
975    /// - `serial`: serial number of the key event
976    /// - `time`: timestamp with millisecond granularity
977    /// - `key`: key that produced the event
978    /// - `state`: physical state of the key
979    #[inline]
980    fn handle_key(
981        &mut self,
982        slf: &Rc<WlKeyboard>,
983        serial: u32,
984        time: u32,
985        key: u32,
986        state: WlKeyboardKeyState,
987    ) {
988        if !slf.core.forward_to_client.get() {
989            return;
990        }
991        let res = slf.try_send_key(
992            serial,
993            time,
994            key,
995            state,
996        );
997        if let Err(e) = res {
998            log_forward("wl_keyboard.key", &e);
999        }
1000    }
1001
1002    /// modifier and group state
1003    ///
1004    /// Notifies clients that the modifier and/or group state has
1005    /// changed, and it should update its local state.
1006    ///
1007    /// The compositor may send this event without a surface of the client
1008    /// having keyboard focus, for example to tie modifier information to
1009    /// pointer focus instead. If a modifier event with pressed modifiers is sent
1010    /// without a prior enter event, the client can assume the modifier state is
1011    /// valid until it receives the next wl_keyboard.modifiers event. In order to
1012    /// reset the modifier state again, the compositor can send a
1013    /// wl_keyboard.modifiers event with no pressed modifiers.
1014    ///
1015    /// In the wl_keyboard logical state, this event updates the modifiers and
1016    /// group.
1017    ///
1018    /// # Arguments
1019    ///
1020    /// - `serial`: serial number of the modifiers event
1021    /// - `mods_depressed`: depressed modifiers
1022    /// - `mods_latched`: latched modifiers
1023    /// - `mods_locked`: locked modifiers
1024    /// - `group`: keyboard layout
1025    #[inline]
1026    fn handle_modifiers(
1027        &mut self,
1028        slf: &Rc<WlKeyboard>,
1029        serial: u32,
1030        mods_depressed: u32,
1031        mods_latched: u32,
1032        mods_locked: u32,
1033        group: u32,
1034    ) {
1035        if !slf.core.forward_to_client.get() {
1036            return;
1037        }
1038        let res = slf.try_send_modifiers(
1039            serial,
1040            mods_depressed,
1041            mods_latched,
1042            mods_locked,
1043            group,
1044        );
1045        if let Err(e) = res {
1046            log_forward("wl_keyboard.modifiers", &e);
1047        }
1048    }
1049
1050    /// release the keyboard object
1051    #[inline]
1052    fn handle_release(
1053        &mut self,
1054        slf: &Rc<WlKeyboard>,
1055    ) {
1056        if !slf.core.forward_to_server.get() {
1057            return;
1058        }
1059        let res = slf.try_send_release(
1060        );
1061        if let Err(e) = res {
1062            log_forward("wl_keyboard.release", &e);
1063        }
1064    }
1065
1066    /// repeat rate and delay
1067    ///
1068    /// Informs the client about the keyboard's repeat rate and delay.
1069    ///
1070    /// This event is sent as soon as the wl_keyboard object has been created,
1071    /// and is guaranteed to be received by the client before any key press
1072    /// event.
1073    ///
1074    /// Negative values for either rate or delay are illegal. A rate of zero
1075    /// will disable any repeating (regardless of the value of delay).
1076    ///
1077    /// This event can be sent later on as well with a new value if necessary,
1078    /// so clients should continue listening for the event past the creation
1079    /// of wl_keyboard.
1080    ///
1081    /// # Arguments
1082    ///
1083    /// - `rate`: the rate of repeating keys in characters per second
1084    /// - `delay`: delay in milliseconds since key down until repeating starts
1085    #[inline]
1086    fn handle_repeat_info(
1087        &mut self,
1088        slf: &Rc<WlKeyboard>,
1089        rate: i32,
1090        delay: i32,
1091    ) {
1092        if !slf.core.forward_to_client.get() {
1093            return;
1094        }
1095        let res = slf.try_send_repeat_info(
1096            rate,
1097            delay,
1098        );
1099        if let Err(e) = res {
1100            log_forward("wl_keyboard.repeat_info", &e);
1101        }
1102    }
1103}
1104
1105impl ObjectPrivate for WlKeyboard {
1106    fn new(state: &Rc<State>, version: u32) -> Rc<Self> {
1107        Rc::<Self>::new_cyclic(|slf| Self {
1108            core: ObjectCore::new(state, slf.clone(), ObjectInterface::WlKeyboard, version),
1109            handler: Default::default(),
1110        })
1111    }
1112
1113    fn delete_id(self: Rc<Self>) -> Result<(), (ObjectError, Rc<dyn Object>)> {
1114        let Some(mut handler) = self.handler.try_borrow_mut() else {
1115            return Err((ObjectError(ObjectErrorKind::HandlerBorrowed), self));
1116        };
1117        if let Some(handler) = &mut *handler {
1118            handler.delete_id(&self);
1119        } else {
1120            self.core.delete_id();
1121        }
1122        Ok(())
1123    }
1124
1125    fn handle_request(self: Rc<Self>, client: &Rc<Client>, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
1126        let Some(mut handler) = self.handler.try_borrow_mut() else {
1127            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
1128        };
1129        let handler = &mut *handler;
1130        match msg[1] & 0xffff {
1131            0 => {
1132                if msg.len() != 2 {
1133                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 8)));
1134                }
1135                #[cfg(feature = "logging")]
1136                if self.core.state.log {
1137                    #[cold]
1138                    fn log(state: &State, client_id: u64, id: u32) {
1139                        let (millis, micros) = time_since_epoch();
1140                        let prefix = &state.log_prefix;
1141                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_keyboard#{}.release()\n", client_id, id);
1142                        state.log(args);
1143                    }
1144                    log(&self.core.state, client.endpoint.id, msg[0]);
1145                }
1146                self.core.handle_client_destroy();
1147                if let Some(handler) = handler {
1148                    (**handler).handle_release(&self);
1149                } else {
1150                    DefaultHandler.handle_release(&self);
1151                }
1152            }
1153            n => {
1154                let _ = client;
1155                let _ = msg;
1156                let _ = fds;
1157                let _ = handler;
1158                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
1159            }
1160        }
1161        Ok(())
1162    }
1163
1164    fn handle_event(self: Rc<Self>, server: &Endpoint, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
1165        let Some(mut handler) = self.handler.try_borrow_mut() else {
1166            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
1167        };
1168        let handler = &mut *handler;
1169        match msg[1] & 0xffff {
1170            0 => {
1171                let [
1172                    arg0,
1173                    arg2,
1174                ] = msg[2..] else {
1175                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 16)));
1176                };
1177                let Some(arg1) = fds.pop_front() else {
1178                    return Err(ObjectError(ObjectErrorKind::MissingFd("fd")));
1179                };
1180                let arg0 = WlKeyboardKeymapFormat(arg0);
1181                let arg1 = &arg1;
1182                #[cfg(feature = "logging")]
1183                if self.core.state.log {
1184                    #[cold]
1185                    fn log(state: &State, id: u32, arg0: WlKeyboardKeymapFormat, arg1: i32, arg2: u32) {
1186                        let (millis, micros) = time_since_epoch();
1187                        let prefix = &state.log_prefix;
1188                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_keyboard#{}.keymap(format: {:?}, fd: {}, size: {})\n", id, arg0, arg1, arg2);
1189                        state.log(args);
1190                    }
1191                    log(&self.core.state, msg[0], arg0, arg1.as_raw_fd(), arg2);
1192                }
1193                if let Some(handler) = handler {
1194                    (**handler).handle_keymap(&self, arg0, arg1, arg2);
1195                } else {
1196                    DefaultHandler.handle_keymap(&self, arg0, arg1, arg2);
1197                }
1198            }
1199            1 => {
1200                let mut offset = 2;
1201                let Some(&arg0) = msg.get(offset) else {
1202                    return Err(ObjectError(ObjectErrorKind::MissingArgument("serial")));
1203                };
1204                offset += 1;
1205                let Some(&arg1) = msg.get(offset) else {
1206                    return Err(ObjectError(ObjectErrorKind::MissingArgument("surface")));
1207                };
1208                offset += 1;
1209                let arg2;
1210                (arg2, offset) = parse_array(msg, offset, "keys")?;
1211                if offset != msg.len() {
1212                    return Err(ObjectError(ObjectErrorKind::TrailingBytes));
1213                }
1214                #[cfg(feature = "logging")]
1215                if self.core.state.log {
1216                    #[cold]
1217                    fn log(state: &State, id: u32, arg0: u32, arg1: u32, arg2: &[u8]) {
1218                        let (millis, micros) = time_since_epoch();
1219                        let prefix = &state.log_prefix;
1220                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_keyboard#{}.enter(serial: {}, surface: wl_surface#{}, keys: {})\n", id, arg0, arg1, debug_array(arg2));
1221                        state.log(args);
1222                    }
1223                    log(&self.core.state, msg[0], arg0, arg1, arg2);
1224                }
1225                let arg1_id = arg1;
1226                let Some(arg1) = server.lookup(arg1_id) else {
1227                    return Err(ObjectError(ObjectErrorKind::NoServerObject(arg1_id)));
1228                };
1229                let Ok(arg1) = (arg1 as Rc<dyn Any>).downcast::<WlSurface>() else {
1230                    let o = server.lookup(arg1_id).unwrap();
1231                    return Err(ObjectError(ObjectErrorKind::WrongObjectType("surface", o.core().interface, ObjectInterface::WlSurface)));
1232                };
1233                let arg1 = &arg1;
1234                if let Some(handler) = handler {
1235                    (**handler).handle_enter(&self, arg0, arg1, arg2);
1236                } else {
1237                    DefaultHandler.handle_enter(&self, arg0, arg1, arg2);
1238                }
1239            }
1240            2 => {
1241                let [
1242                    arg0,
1243                    arg1,
1244                ] = msg[2..] else {
1245                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 16)));
1246                };
1247                #[cfg(feature = "logging")]
1248                if self.core.state.log {
1249                    #[cold]
1250                    fn log(state: &State, id: u32, arg0: u32, arg1: u32) {
1251                        let (millis, micros) = time_since_epoch();
1252                        let prefix = &state.log_prefix;
1253                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_keyboard#{}.leave(serial: {}, surface: wl_surface#{})\n", id, arg0, arg1);
1254                        state.log(args);
1255                    }
1256                    log(&self.core.state, msg[0], arg0, arg1);
1257                }
1258                let arg1_id = arg1;
1259                let Some(arg1) = server.lookup(arg1_id) else {
1260                    return Err(ObjectError(ObjectErrorKind::NoServerObject(arg1_id)));
1261                };
1262                let Ok(arg1) = (arg1 as Rc<dyn Any>).downcast::<WlSurface>() else {
1263                    let o = server.lookup(arg1_id).unwrap();
1264                    return Err(ObjectError(ObjectErrorKind::WrongObjectType("surface", o.core().interface, ObjectInterface::WlSurface)));
1265                };
1266                let arg1 = &arg1;
1267                if let Some(handler) = handler {
1268                    (**handler).handle_leave(&self, arg0, arg1);
1269                } else {
1270                    DefaultHandler.handle_leave(&self, arg0, arg1);
1271                }
1272            }
1273            3 => {
1274                let [
1275                    arg0,
1276                    arg1,
1277                    arg2,
1278                    arg3,
1279                ] = msg[2..] else {
1280                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 24)));
1281                };
1282                let arg3 = WlKeyboardKeyState(arg3);
1283                #[cfg(feature = "logging")]
1284                if self.core.state.log {
1285                    #[cold]
1286                    fn log(state: &State, id: u32, arg0: u32, arg1: u32, arg2: u32, arg3: WlKeyboardKeyState) {
1287                        let (millis, micros) = time_since_epoch();
1288                        let prefix = &state.log_prefix;
1289                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_keyboard#{}.key(serial: {}, time: {}, key: {}, state: {:?})\n", id, arg0, arg1, arg2, arg3);
1290                        state.log(args);
1291                    }
1292                    log(&self.core.state, msg[0], arg0, arg1, arg2, arg3);
1293                }
1294                if let Some(handler) = handler {
1295                    (**handler).handle_key(&self, arg0, arg1, arg2, arg3);
1296                } else {
1297                    DefaultHandler.handle_key(&self, arg0, arg1, arg2, arg3);
1298                }
1299            }
1300            4 => {
1301                let [
1302                    arg0,
1303                    arg1,
1304                    arg2,
1305                    arg3,
1306                    arg4,
1307                ] = msg[2..] else {
1308                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 28)));
1309                };
1310                #[cfg(feature = "logging")]
1311                if self.core.state.log {
1312                    #[cold]
1313                    fn log(state: &State, id: u32, arg0: u32, arg1: u32, arg2: u32, arg3: u32, arg4: u32) {
1314                        let (millis, micros) = time_since_epoch();
1315                        let prefix = &state.log_prefix;
1316                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_keyboard#{}.modifiers(serial: {}, mods_depressed: {}, mods_latched: {}, mods_locked: {}, group: {})\n", id, arg0, arg1, arg2, arg3, arg4);
1317                        state.log(args);
1318                    }
1319                    log(&self.core.state, msg[0], arg0, arg1, arg2, arg3, arg4);
1320                }
1321                if let Some(handler) = handler {
1322                    (**handler).handle_modifiers(&self, arg0, arg1, arg2, arg3, arg4);
1323                } else {
1324                    DefaultHandler.handle_modifiers(&self, arg0, arg1, arg2, arg3, arg4);
1325                }
1326            }
1327            5 => {
1328                let [
1329                    arg0,
1330                    arg1,
1331                ] = msg[2..] else {
1332                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 16)));
1333                };
1334                let arg0 = arg0 as i32;
1335                let arg1 = arg1 as i32;
1336                #[cfg(feature = "logging")]
1337                if self.core.state.log {
1338                    #[cold]
1339                    fn log(state: &State, id: u32, arg0: i32, arg1: i32) {
1340                        let (millis, micros) = time_since_epoch();
1341                        let prefix = &state.log_prefix;
1342                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_keyboard#{}.repeat_info(rate: {}, delay: {})\n", id, arg0, arg1);
1343                        state.log(args);
1344                    }
1345                    log(&self.core.state, msg[0], arg0, arg1);
1346                }
1347                if let Some(handler) = handler {
1348                    (**handler).handle_repeat_info(&self, arg0, arg1);
1349                } else {
1350                    DefaultHandler.handle_repeat_info(&self, arg0, arg1);
1351                }
1352            }
1353            n => {
1354                let _ = server;
1355                let _ = msg;
1356                let _ = fds;
1357                let _ = handler;
1358                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
1359            }
1360        }
1361        Ok(())
1362    }
1363
1364    fn get_request_name(&self, id: u32) -> Option<&'static str> {
1365        let name = match id {
1366            0 => "release",
1367            _ => return None,
1368        };
1369        Some(name)
1370    }
1371
1372    fn get_event_name(&self, id: u32) -> Option<&'static str> {
1373        let name = match id {
1374            0 => "keymap",
1375            1 => "enter",
1376            2 => "leave",
1377            3 => "key",
1378            4 => "modifiers",
1379            5 => "repeat_info",
1380            _ => return None,
1381        };
1382        Some(name)
1383    }
1384}
1385
1386impl Object for WlKeyboard {
1387    fn core(&self) -> &ObjectCore {
1388        &self.core
1389    }
1390
1391    fn unset_handler(&self) {
1392        self.handler.set(None);
1393    }
1394
1395    fn get_handler_any_ref(&self) -> Result<HandlerRef<'_, dyn Any>, HandlerAccessError> {
1396        let borrowed = self.handler.try_borrow().ok_or(HandlerAccessError::AlreadyBorrowed)?;
1397        if borrowed.is_none() {
1398            return Err(HandlerAccessError::NoHandler);
1399        }
1400        Ok(HandlerRef::map(borrowed, |handler| &**handler.as_ref().unwrap() as &dyn Any))
1401    }
1402
1403    fn get_handler_any_mut(&self) -> Result<HandlerMut<'_, dyn Any>, HandlerAccessError> {
1404        let borrowed = self.handler.try_borrow_mut().ok_or(HandlerAccessError::AlreadyBorrowed)?;
1405        if borrowed.is_none() {
1406            return Err(HandlerAccessError::NoHandler);
1407        }
1408        Ok(HandlerMut::map(borrowed, |handler| &mut **handler.as_mut().unwrap() as &mut dyn Any))
1409    }
1410}
1411
1412impl WlKeyboard {
1413    /// Since when the keymap_format.no_keymap enum variant is available.
1414    pub const ENM__KEYMAP_FORMAT_NO_KEYMAP__SINCE: u32 = 1;
1415    /// Since when the keymap_format.xkb_v1 enum variant is available.
1416    pub const ENM__KEYMAP_FORMAT_XKB_V1__SINCE: u32 = 1;
1417
1418    /// Since when the key_state.released enum variant is available.
1419    pub const ENM__KEY_STATE_RELEASED__SINCE: u32 = 1;
1420    /// Since when the key_state.pressed enum variant is available.
1421    pub const ENM__KEY_STATE_PRESSED__SINCE: u32 = 1;
1422    /// Since when the key_state.repeated enum variant is available.
1423    pub const ENM__KEY_STATE_REPEATED__SINCE: u32 = 10;
1424}
1425
1426/// keyboard mapping format
1427///
1428/// This specifies the format of the keymap provided to the
1429/// client with the wl_keyboard.keymap event.
1430#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1431pub struct WlKeyboardKeymapFormat(pub u32);
1432
1433impl WlKeyboardKeymapFormat {
1434    /// no keymap; client must understand how to interpret the raw keycode
1435    pub const NO_KEYMAP: Self = Self(0);
1436
1437    /// libxkbcommon compatible, null-terminated string; to determine the xkb keycode, clients must add 8 to the key event keycode
1438    pub const XKB_V1: Self = Self(1);
1439}
1440
1441impl Debug for WlKeyboardKeymapFormat {
1442    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1443        let name = match *self {
1444            Self::NO_KEYMAP => "NO_KEYMAP",
1445            Self::XKB_V1 => "XKB_V1",
1446            _ => return Debug::fmt(&self.0, f),
1447        };
1448        f.write_str(name)
1449    }
1450}
1451
1452/// physical key state
1453///
1454/// Describes the physical state of a key that produced the key event.
1455///
1456/// Since version 10, the key can be in a "repeated" pseudo-state which
1457/// means the same as "pressed", but is used to signal repetition in the
1458/// key event.
1459///
1460/// The key may only enter the repeated state after entering the pressed
1461/// state and before entering the released state. This event may be
1462/// generated multiple times while the key is down.
1463#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1464pub struct WlKeyboardKeyState(pub u32);
1465
1466impl WlKeyboardKeyState {
1467    /// key is not pressed
1468    pub const RELEASED: Self = Self(0);
1469
1470    /// key is pressed
1471    pub const PRESSED: Self = Self(1);
1472
1473    /// key was repeated
1474    pub const REPEATED: Self = Self(2);
1475}
1476
1477impl Debug for WlKeyboardKeyState {
1478    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1479        let name = match *self {
1480            Self::RELEASED => "RELEASED",
1481            Self::PRESSED => "PRESSED",
1482            Self::REPEATED => "REPEATED",
1483            _ => return Debug::fmt(&self.0, f),
1484        };
1485        f.write_str(name)
1486    }
1487}