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}