1use {
2 crate::common::{
3 protocols::wayland::{
4 wl_display::WlDisplay,
5 wl_keyboard::{
6 WlKeyboard, WlKeyboardEventHandler, WlKeyboardKeyState, WlKeyboardKeymapFormat,
7 WlKeyboardRef,
8 },
9 wl_registry::{WlRegistry, WlRegistryEventHandler, WlRegistryRef},
10 wl_seat::{WlSeat, WlSeatCapability, WlSeatEventHandler, WlSeatRef},
11 wl_surface::WlSurfaceRef,
12 },
13 singletons::get_singletons,
14 },
15 common::simple_window,
16 std::{cell::RefCell, collections::HashMap, os::fd::OwnedFd, rc::Rc},
17 wl_client::{
18 Libwayland,
19 proxy::{self, OwnedProxy},
20 },
21};
22
23#[path = "../common/mod.rs"]
24mod common;
25
26fn main() {
27 let lib = Libwayland::open().unwrap();
28 let con = lib.connect_to_default_display().unwrap();
29 let queue = con.create_local_queue(c"keyboard-events");
30 let singletons = get_singletons(&queue.display());
31 let simple_window = simple_window::prepare(singletons);
32
33 let wl_registry = queue.display::<WlDisplay>().get_registry();
34 proxy::set_event_handler_local(
35 &wl_registry,
36 RegistryEventHandler {
37 wl_registry: wl_registry.clone(),
38 seats: Default::default(),
39 },
40 );
41
42 while !simple_window.exit.get() {
43 queue.dispatch_blocking().unwrap();
44 }
45}
46
47struct RegistryEventHandler {
48 wl_registry: WlRegistry,
49 seats: RefCell<HashMap<u32, Rc<Seat>>>,
50}
51
52struct Seat {
53 wl_seat: WlSeat,
54 wl_keyboard: RefCell<Option<WlKeyboard>>,
55}
56
57#[derive(Clone)]
58struct SeatEventHandler(Rc<Seat>);
59
60impl WlRegistryEventHandler for RegistryEventHandler {
61 fn global(&self, _slf: &WlRegistryRef, name: u32, interface: &str, version: u32) {
62 if interface == WlSeat::INTERFACE {
63 let wl_seat = self.wl_registry.bind::<WlSeat>(name, version.min(5));
64 let seat = Rc::new(Seat {
65 wl_seat: wl_seat.clone(),
66 wl_keyboard: Default::default(),
67 });
68 self.seats.borrow_mut().insert(name, seat.clone());
69 proxy::set_event_handler_local(&wl_seat, SeatEventHandler(seat));
70 }
71 }
72
73 fn global_remove(&self, _slf: &WlRegistryRef, name: u32) {
74 if let Some(seat) = self.seats.borrow_mut().remove(&name) {
75 if let Some(kb) = seat.wl_keyboard.take() {
76 if proxy::version(&*kb) >= WlKeyboard::REQ__RELEASE__SINCE {
77 kb.release();
78 } else {
79 proxy::destroy(&kb);
80 }
81 }
82 if proxy::version(&*seat.wl_seat) >= WlSeat::REQ__RELEASE__SINCE {
83 seat.wl_seat.release();
84 } else {
85 proxy::destroy(&seat.wl_seat);
86 }
87 }
88 }
89}
90
91impl WlSeatEventHandler for SeatEventHandler {
92 fn capabilities(&self, _slf: &WlSeatRef, capabilities: WlSeatCapability) {
93 let kb = &mut *self.0.wl_keyboard.borrow_mut();
94 if capabilities.contains(WlSeatCapability::KEYBOARD) {
95 if kb.is_none() {
96 let wl_keyboard = self.0.wl_seat.get_keyboard();
97 proxy::set_event_handler_local(&wl_keyboard, self.clone());
98 *kb = Some(wl_keyboard);
99 }
100 } else {
101 if let Some(kb) = kb.take() {
102 if proxy::version(&*kb) >= WlKeyboard::REQ__RELEASE__SINCE {
103 kb.release();
104 } else {
105 proxy::destroy(&kb);
106 }
107 }
108 }
109 }
110}
111
112impl WlKeyboardEventHandler for SeatEventHandler {
113 fn keymap(
114 &self,
115 _slf: &WlKeyboardRef,
116 format: WlKeyboardKeymapFormat,
117 _fd: OwnedFd,
118 size: u32,
119 ) {
120 println!("keymap format: {format:?}");
121 println!("keymap size: {size:?}");
122 }
123
124 fn enter(
125 &self,
126 _slf: &WlKeyboardRef,
127 _serial: u32,
128 surface: Option<&WlSurfaceRef>,
129 keys: &[u8],
130 ) {
131 println!("enter surface {:?}", surface.map(proxy::id));
132 println!("keys {keys:?}");
133 }
134
135 fn leave(&self, _slf: &WlKeyboardRef, _serial: u32, surface: Option<&WlSurfaceRef>) {
136 println!("leave surface {:?}", surface.map(proxy::id));
137 }
138
139 fn key(
140 &self,
141 _slf: &WlKeyboardRef,
142 _serial: u32,
143 _time: u32,
144 key: u32,
145 state: WlKeyboardKeyState,
146 ) {
147 println!("key {key:?} {state:?}");
148 }
149
150 fn modifiers(
151 &self,
152 _slf: &WlKeyboardRef,
153 _serial: u32,
154 mods_depressed: u32,
155 mods_latched: u32,
156 mods_locked: u32,
157 group: u32,
158 ) {
159 println!("modifiers {mods_depressed:x?}, {mods_latched:x?}, {mods_locked:x?}, {group}");
160 }
161
162 fn repeat_info(&self, _slf: &WlKeyboardRef, rate: i32, delay: i32) {
163 println!("repeat info {rate:?} {delay:?}");
164 }
165}