mirror of https://github.com/wayvr-org/wayvr.git
Add keymap support to HID providers and refactor related functionality
This commit is contained in:
parent
0625570285
commit
595e3eb43a
|
|
@ -1,5 +1,5 @@
|
|||
use glam::Vec2;
|
||||
use crate::subsystem::hid::{VirtualKey, WheelDelta};
|
||||
use crate::subsystem::hid::{VirtualKey, WheelDelta, XkbKeymap};
|
||||
use crate::subsystem::hid::provider::HidProvider;
|
||||
|
||||
pub struct DummyProvider;
|
||||
|
|
@ -8,9 +8,12 @@ impl HidProvider for DummyProvider {
|
|||
fn mouse_move(&mut self, _pos: Vec2) {}
|
||||
fn send_button(&mut self, _button: u16, _down: bool) {}
|
||||
fn wheel(&mut self, _delta: WheelDelta) {}
|
||||
fn set_modifiers(&mut self, _modifiers: u8) {}
|
||||
fn send_key(&self, _key: VirtualKey, _down: bool) {}
|
||||
fn set_desktop_extent(&mut self, _extent: Vec2) {}
|
||||
fn set_desktop_origin(&mut self, _origin: Vec2) {}
|
||||
fn set_modifiers(&mut self, _modifiers: u8) {}
|
||||
fn send_key(&self, _key: VirtualKey, _down: bool) {}
|
||||
|
||||
fn set_keymap(&mut self, _keymap: &XkbKeymap) {}
|
||||
|
||||
fn commit(&mut self) {}
|
||||
}
|
||||
|
|
@ -1,17 +1,23 @@
|
|||
use glam::Vec2;
|
||||
use crate::subsystem::hid::{VirtualKey, WheelDelta};
|
||||
use crate::subsystem::hid::{VirtualKey, WheelDelta, XkbKeymap};
|
||||
|
||||
pub mod uinput;
|
||||
pub mod wl_virtual;
|
||||
pub mod dummy;
|
||||
|
||||
pub trait HidProvider: Sync + Send {
|
||||
// Pointer Functions
|
||||
fn mouse_move(&mut self, pos: Vec2);
|
||||
fn send_button(&mut self, button: u16, down: bool);
|
||||
fn wheel(&mut self, delta: WheelDelta);
|
||||
fn set_modifiers(&mut self, mods: u8);
|
||||
fn send_key(&self, key: VirtualKey, down: bool);
|
||||
fn set_desktop_extent(&mut self, extent: Vec2);
|
||||
fn set_desktop_origin(&mut self, origin: Vec2);
|
||||
|
||||
// Keyboard Functions
|
||||
fn set_modifiers(&mut self, mods: u8);
|
||||
fn send_key(&self, key: VirtualKey, down: bool);
|
||||
fn set_keymap(&mut self, keymap: &XkbKeymap);
|
||||
|
||||
// Common Functions
|
||||
fn commit(&mut self);
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ use strum::IntoEnumIterator;
|
|||
use input_linux::{AbsoluteAxis, AbsoluteInfo, AbsoluteInfoSetup, EventKind, InputId, Key, RelativeAxis, UInputHandle};
|
||||
use wlx_common::overlays::ToastTopic;
|
||||
use crate::overlays::toast::Toast;
|
||||
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};
|
||||
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};
|
||||
use crate::subsystem::hid::provider::HidProvider;
|
||||
|
||||
pub struct UInputProvider {
|
||||
|
|
@ -171,6 +171,12 @@ impl HidProvider for UInputProvider {
|
|||
self.current_action.pos = None;
|
||||
}
|
||||
}
|
||||
fn set_desktop_extent(&mut self, extent: Vec2) {
|
||||
self.desktop_extent = extent;
|
||||
}
|
||||
fn set_desktop_origin(&mut self, origin: Vec2) {
|
||||
self.desktop_origin = origin;
|
||||
}
|
||||
fn set_modifiers(&mut self, modifiers: u8) {
|
||||
let changed = self.cur_modifiers ^ modifiers;
|
||||
for i in 0..8 {
|
||||
|
|
@ -183,6 +189,7 @@ impl HidProvider for UInputProvider {
|
|||
}
|
||||
self.cur_modifiers = modifiers;
|
||||
}
|
||||
|
||||
fn send_key(&self, key: VirtualKey, down: bool) {
|
||||
#[cfg(debug_assertions)]
|
||||
log::trace!("send_key: {key:?} {down}");
|
||||
|
|
@ -196,13 +203,8 @@ impl HidProvider for UInputProvider {
|
|||
log::error!("send_key: {res}");
|
||||
}
|
||||
}
|
||||
fn set_desktop_extent(&mut self, extent: Vec2) {
|
||||
self.desktop_extent = extent;
|
||||
}
|
||||
|
||||
fn set_desktop_origin(&mut self, origin: Vec2) {
|
||||
self.desktop_origin = origin;
|
||||
}
|
||||
fn set_keymap(&mut self, _keymap: &XkbKeymap) {}
|
||||
|
||||
fn commit(&mut self) {
|
||||
if let Some(pos) = self.current_action.pos.take() {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ pub struct WlVirtualProvider {
|
|||
virtual_pointer: ZwlrVirtualPointerV1,
|
||||
desktop_extent: Vec2,
|
||||
desktop_origin: Vec2,
|
||||
_file: std::fs::File,
|
||||
keymap_file: Option<std::fs::File>,
|
||||
|
||||
virtual_keyboard: ZwpVirtualKeyboardV1,
|
||||
keyboard_mods_state: u8,
|
||||
|
|
@ -101,6 +101,14 @@ impl HidProvider for WlVirtualProvider {
|
|||
self.virtual_pointer.frame();
|
||||
}
|
||||
|
||||
fn set_desktop_extent(&mut self, extent: Vec2) {
|
||||
self.desktop_extent = extent;
|
||||
}
|
||||
|
||||
fn set_desktop_origin(&mut self, origin: Vec2) {
|
||||
self.desktop_origin = origin;
|
||||
}
|
||||
|
||||
fn set_modifiers(&mut self, mods: u8) {
|
||||
const LOCKED: u8 = CAPS_LOCK | NUM_LOCK;
|
||||
|
||||
|
|
@ -109,7 +117,8 @@ impl HidProvider for WlVirtualProvider {
|
|||
if changed & bit != 0 {
|
||||
let down = mods & bit != 0;
|
||||
if let Some(kc) = Self::modifier_keycode(bit) {
|
||||
self.virtual_keyboard.key(Self::now_ms(), kc - 8, down as u32);
|
||||
self.virtual_keyboard
|
||||
.key(Self::now_ms(), kc - 8, down as u32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -138,12 +147,25 @@ impl HidProvider for WlVirtualProvider {
|
|||
self._connection.flush().unwrap();
|
||||
}
|
||||
|
||||
fn set_desktop_extent(&mut self, extent: Vec2) {
|
||||
self.desktop_extent = extent;
|
||||
}
|
||||
fn set_keymap(&mut self, keymap: &XkbKeymap) {
|
||||
#[cfg(debug_assertions)]
|
||||
log::trace!("Keyboard keymap: {:?}", keymap.inner.layouts().next().unwrap_or("Unknown"));
|
||||
|
||||
fn set_desktop_origin(&mut self, origin: Vec2) {
|
||||
self.desktop_origin = origin;
|
||||
let mut bytes = keymap
|
||||
.inner
|
||||
.get_as_string(KEYMAP_FORMAT_TEXT_V1)
|
||||
.into_bytes();
|
||||
bytes.push(0);
|
||||
let fd = memfd_create("virtual-keyboard-keymap", MemfdFlags::CLOEXEC)
|
||||
.expect("Failed to create memfd");
|
||||
|
||||
let mut file = std::fs::File::from(fd);
|
||||
file.write_all(&bytes).expect("failed to write the keymap");
|
||||
|
||||
self.virtual_keyboard
|
||||
.keymap(KeymapFormat::XkbV1 as u32, file.as_fd(), bytes.len() as u32);
|
||||
self.queue.roundtrip(&mut self.state).unwrap();
|
||||
self.keymap_file.replace(file);
|
||||
}
|
||||
|
||||
fn commit(&mut self) {
|
||||
|
|
@ -153,10 +175,10 @@ impl HidProvider for WlVirtualProvider {
|
|||
|
||||
impl WlVirtualProvider {
|
||||
pub fn try_new() -> anyhow::Result<Self> {
|
||||
let mut state = KbState;
|
||||
let state = KbState;
|
||||
|
||||
let connection = wayland_client::Connection::connect_to_env()?;
|
||||
let (globals, mut queue) = registry_queue_init::<KbState>(&connection)?;
|
||||
let (globals, queue) = registry_queue_init::<KbState>(&connection)?;
|
||||
let qh = queue.handle();
|
||||
let seat: WlSeat = globals
|
||||
.bind(&qh, 4..=9, ())
|
||||
|
|
@ -174,31 +196,8 @@ impl WlVirtualProvider {
|
|||
|
||||
let virtual_keyboard = keyboard_manager.create_virtual_keyboard(&seat, &qh, ());
|
||||
|
||||
let xkb_context = Context::new(CONTEXT_NO_FLAGS);
|
||||
let xkb_keymap = Keymap::new_from_names(
|
||||
&xkb_context,
|
||||
"",
|
||||
"",
|
||||
"us",
|
||||
"",
|
||||
None,
|
||||
KEYMAP_COMPILE_NO_FLAGS,
|
||||
)
|
||||
.expect("Failed to compile XKB keymap");
|
||||
|
||||
let mut bytes = xkb_keymap.get_as_string(KEYMAP_FORMAT_TEXT_V1).into_bytes();
|
||||
bytes.push(0);
|
||||
let fd = memfd_create("virtual-keyboard-keymap", MemfdFlags::CLOEXEC)
|
||||
.expect("Failed to create memfd");
|
||||
|
||||
let mut file = std::fs::File::from(fd);
|
||||
file.write_all(&bytes).expect("failed to write the keymap");
|
||||
|
||||
virtual_keyboard.keymap(KeymapFormat::XkbV1 as u32, file.as_fd(), bytes.len() as u32);
|
||||
queue.roundtrip(&mut state)?;
|
||||
|
||||
Ok(Self {
|
||||
_file: file,
|
||||
let mut result = Self {
|
||||
keymap_file: None,
|
||||
_connection: connection,
|
||||
queue,
|
||||
state,
|
||||
|
|
@ -207,7 +206,27 @@ impl WlVirtualProvider {
|
|||
desktop_extent: Vec2::ZERO,
|
||||
desktop_origin: Vec2::ZERO,
|
||||
keyboard_mods_state: 0,
|
||||
})
|
||||
};
|
||||
|
||||
result.set_keymap(&XkbKeymap {
|
||||
inner: Self::default_keymap(),
|
||||
});
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn default_keymap() -> Keymap {
|
||||
let xkb_context = Context::new(CONTEXT_NO_FLAGS);
|
||||
Keymap::new_from_names(
|
||||
&xkb_context,
|
||||
"",
|
||||
"",
|
||||
"us",
|
||||
"",
|
||||
None,
|
||||
KEYMAP_COMPILE_NO_FLAGS,
|
||||
)
|
||||
.expect("Failed to compile XKB keymap")
|
||||
}
|
||||
|
||||
fn modifier_keycode(bit: u8) -> Option<u32> {
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ impl HidWrapper {
|
|||
.inspect_err(|e| log::error!("Could not set WayVR keymap: {e:?}"));
|
||||
} else {
|
||||
self.keymap = Some(keymap.clone());
|
||||
self.inner.set_keymap(&keymap);
|
||||
}
|
||||
|
||||
log::info!(
|
||||
|
|
|
|||
Loading…
Reference in New Issue