Skip to content

Commit 595e3eb

Browse files
committed
Add keymap support to HID providers and refactor related functionality
1 parent 0625570 commit 595e3eb

5 files changed

Lines changed: 78 additions & 47 deletions

File tree

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use glam::Vec2;
2-
use crate::subsystem::hid::{VirtualKey, WheelDelta};
2+
use crate::subsystem::hid::{VirtualKey, WheelDelta, XkbKeymap};
33
use crate::subsystem::hid::provider::HidProvider;
44

55
pub struct DummyProvider;
@@ -8,9 +8,12 @@ impl HidProvider for DummyProvider {
88
fn mouse_move(&mut self, _pos: Vec2) {}
99
fn send_button(&mut self, _button: u16, _down: bool) {}
1010
fn wheel(&mut self, _delta: WheelDelta) {}
11-
fn set_modifiers(&mut self, _modifiers: u8) {}
12-
fn send_key(&self, _key: VirtualKey, _down: bool) {}
1311
fn set_desktop_extent(&mut self, _extent: Vec2) {}
1412
fn set_desktop_origin(&mut self, _origin: Vec2) {}
13+
fn set_modifiers(&mut self, _modifiers: u8) {}
14+
fn send_key(&self, _key: VirtualKey, _down: bool) {}
15+
16+
fn set_keymap(&mut self, _keymap: &XkbKeymap) {}
17+
1518
fn commit(&mut self) {}
1619
}
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
use glam::Vec2;
2-
use crate::subsystem::hid::{VirtualKey, WheelDelta};
2+
use crate::subsystem::hid::{VirtualKey, WheelDelta, XkbKeymap};
33

44
pub mod uinput;
55
pub mod wl_virtual;
66
pub mod dummy;
77

88
pub trait HidProvider: Sync + Send {
9+
// Pointer Functions
910
fn mouse_move(&mut self, pos: Vec2);
1011
fn send_button(&mut self, button: u16, down: bool);
1112
fn wheel(&mut self, delta: WheelDelta);
12-
fn set_modifiers(&mut self, mods: u8);
13-
fn send_key(&self, key: VirtualKey, down: bool);
1413
fn set_desktop_extent(&mut self, extent: Vec2);
1514
fn set_desktop_origin(&mut self, origin: Vec2);
15+
16+
// Keyboard Functions
17+
fn set_modifiers(&mut self, mods: u8);
18+
fn send_key(&self, key: VirtualKey, down: bool);
19+
fn set_keymap(&mut self, keymap: &XkbKeymap);
20+
21+
// Common Functions
1622
fn commit(&mut self);
1723
}

wayvr/src/subsystem/hid/provider/uinput.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use strum::IntoEnumIterator;
66
use input_linux::{AbsoluteAxis, AbsoluteInfo, AbsoluteInfoSetup, EventKind, InputId, Key, RelativeAxis, UInputHandle};
77
use wlx_common::overlays::ToastTopic;
88
use crate::overlays::toast::Toast;
9-
use crate::subsystem::hid::{get_time, new_event, MouseAction, MouseButtonAction, VirtualKey, WheelDelta, EV_ABS, EV_KEY, EV_REL, EV_SYN, MODS_TO_KEYS, MOUSE_EXTENT, MOUSE_LEFT, MOUSE_MIDDLE};
9+
use crate::subsystem::hid::{get_time, new_event, MouseAction, MouseButtonAction, VirtualKey, WheelDelta, XkbKeymap, EV_ABS, EV_KEY, EV_REL, EV_SYN, MODS_TO_KEYS, MOUSE_EXTENT, MOUSE_LEFT, MOUSE_MIDDLE};
1010
use crate::subsystem::hid::provider::HidProvider;
1111

1212
pub struct UInputProvider {
@@ -171,6 +171,12 @@ impl HidProvider for UInputProvider {
171171
self.current_action.pos = None;
172172
}
173173
}
174+
fn set_desktop_extent(&mut self, extent: Vec2) {
175+
self.desktop_extent = extent;
176+
}
177+
fn set_desktop_origin(&mut self, origin: Vec2) {
178+
self.desktop_origin = origin;
179+
}
174180
fn set_modifiers(&mut self, modifiers: u8) {
175181
let changed = self.cur_modifiers ^ modifiers;
176182
for i in 0..8 {
@@ -183,6 +189,7 @@ impl HidProvider for UInputProvider {
183189
}
184190
self.cur_modifiers = modifiers;
185191
}
192+
186193
fn send_key(&self, key: VirtualKey, down: bool) {
187194
#[cfg(debug_assertions)]
188195
log::trace!("send_key: {key:?} {down}");
@@ -196,13 +203,8 @@ impl HidProvider for UInputProvider {
196203
log::error!("send_key: {res}");
197204
}
198205
}
199-
fn set_desktop_extent(&mut self, extent: Vec2) {
200-
self.desktop_extent = extent;
201-
}
202206

203-
fn set_desktop_origin(&mut self, origin: Vec2) {
204-
self.desktop_origin = origin;
205-
}
207+
fn set_keymap(&mut self, _keymap: &XkbKeymap) {}
206208

207209
fn commit(&mut self) {
208210
if let Some(pos) = self.current_action.pos.take() {

wayvr/src/subsystem/hid/provider/wl_virtual.rs

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub struct WlVirtualProvider {
2828
virtual_pointer: ZwlrVirtualPointerV1,
2929
desktop_extent: Vec2,
3030
desktop_origin: Vec2,
31-
_file: std::fs::File,
31+
keymap_file: Option<std::fs::File>,
3232

3333
virtual_keyboard: ZwpVirtualKeyboardV1,
3434
keyboard_mods_state: u8,
@@ -101,6 +101,14 @@ impl HidProvider for WlVirtualProvider {
101101
self.virtual_pointer.frame();
102102
}
103103

104+
fn set_desktop_extent(&mut self, extent: Vec2) {
105+
self.desktop_extent = extent;
106+
}
107+
108+
fn set_desktop_origin(&mut self, origin: Vec2) {
109+
self.desktop_origin = origin;
110+
}
111+
104112
fn set_modifiers(&mut self, mods: u8) {
105113
const LOCKED: u8 = CAPS_LOCK | NUM_LOCK;
106114

@@ -109,7 +117,8 @@ impl HidProvider for WlVirtualProvider {
109117
if changed & bit != 0 {
110118
let down = mods & bit != 0;
111119
if let Some(kc) = Self::modifier_keycode(bit) {
112-
self.virtual_keyboard.key(Self::now_ms(), kc - 8, down as u32);
120+
self.virtual_keyboard
121+
.key(Self::now_ms(), kc - 8, down as u32);
113122
}
114123
}
115124
}
@@ -138,12 +147,25 @@ impl HidProvider for WlVirtualProvider {
138147
self._connection.flush().unwrap();
139148
}
140149

141-
fn set_desktop_extent(&mut self, extent: Vec2) {
142-
self.desktop_extent = extent;
143-
}
150+
fn set_keymap(&mut self, keymap: &XkbKeymap) {
151+
#[cfg(debug_assertions)]
152+
log::trace!("Keyboard keymap: {:?}", keymap.inner.layouts().next().unwrap_or("Unknown"));
144153

145-
fn set_desktop_origin(&mut self, origin: Vec2) {
146-
self.desktop_origin = origin;
154+
let mut bytes = keymap
155+
.inner
156+
.get_as_string(KEYMAP_FORMAT_TEXT_V1)
157+
.into_bytes();
158+
bytes.push(0);
159+
let fd = memfd_create("virtual-keyboard-keymap", MemfdFlags::CLOEXEC)
160+
.expect("Failed to create memfd");
161+
162+
let mut file = std::fs::File::from(fd);
163+
file.write_all(&bytes).expect("failed to write the keymap");
164+
165+
self.virtual_keyboard
166+
.keymap(KeymapFormat::XkbV1 as u32, file.as_fd(), bytes.len() as u32);
167+
self.queue.roundtrip(&mut self.state).unwrap();
168+
self.keymap_file.replace(file);
147169
}
148170

149171
fn commit(&mut self) {
@@ -153,10 +175,10 @@ impl HidProvider for WlVirtualProvider {
153175

154176
impl WlVirtualProvider {
155177
pub fn try_new() -> anyhow::Result<Self> {
156-
let mut state = KbState;
178+
let state = KbState;
157179

158180
let connection = wayland_client::Connection::connect_to_env()?;
159-
let (globals, mut queue) = registry_queue_init::<KbState>(&connection)?;
181+
let (globals, queue) = registry_queue_init::<KbState>(&connection)?;
160182
let qh = queue.handle();
161183
let seat: WlSeat = globals
162184
.bind(&qh, 4..=9, ())
@@ -174,8 +196,28 @@ impl WlVirtualProvider {
174196

175197
let virtual_keyboard = keyboard_manager.create_virtual_keyboard(&seat, &qh, ());
176198

199+
let mut result = Self {
200+
keymap_file: None,
201+
_connection: connection,
202+
queue,
203+
state,
204+
virtual_pointer,
205+
virtual_keyboard,
206+
desktop_extent: Vec2::ZERO,
207+
desktop_origin: Vec2::ZERO,
208+
keyboard_mods_state: 0,
209+
};
210+
211+
result.set_keymap(&XkbKeymap {
212+
inner: Self::default_keymap(),
213+
});
214+
215+
Ok(result)
216+
}
217+
218+
fn default_keymap() -> Keymap {
177219
let xkb_context = Context::new(CONTEXT_NO_FLAGS);
178-
let xkb_keymap = Keymap::new_from_names(
220+
Keymap::new_from_names(
179221
&xkb_context,
180222
"",
181223
"",
@@ -184,30 +226,7 @@ impl WlVirtualProvider {
184226
None,
185227
KEYMAP_COMPILE_NO_FLAGS,
186228
)
187-
.expect("Failed to compile XKB keymap");
188-
189-
let mut bytes = xkb_keymap.get_as_string(KEYMAP_FORMAT_TEXT_V1).into_bytes();
190-
bytes.push(0);
191-
let fd = memfd_create("virtual-keyboard-keymap", MemfdFlags::CLOEXEC)
192-
.expect("Failed to create memfd");
193-
194-
let mut file = std::fs::File::from(fd);
195-
file.write_all(&bytes).expect("failed to write the keymap");
196-
197-
virtual_keyboard.keymap(KeymapFormat::XkbV1 as u32, file.as_fd(), bytes.len() as u32);
198-
queue.roundtrip(&mut state)?;
199-
200-
Ok(Self {
201-
_file: file,
202-
_connection: connection,
203-
queue,
204-
state,
205-
virtual_pointer,
206-
virtual_keyboard,
207-
desktop_extent: Vec2::ZERO,
208-
desktop_origin: Vec2::ZERO,
209-
keyboard_mods_state: 0,
210-
})
229+
.expect("Failed to compile XKB keymap")
211230
}
212231

213232
fn modifier_keycode(bit: u8) -> Option<u32> {

wayvr/src/subsystem/input.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ impl HidWrapper {
5656
.inspect_err(|e| log::error!("Could not set WayVR keymap: {e:?}"));
5757
} else {
5858
self.keymap = Some(keymap.clone());
59+
self.inner.set_keymap(&keymap);
5960
}
6061

6162
log::info!(

0 commit comments

Comments
 (0)