keymaps: Use multiple key maps, each within the limit of what Xorg can accept.

Key maps are switched on key press whenever needed.
This commit is contained in:
Dorota Czaplejewicz
2020-09-28 17:29:59 +00:00
parent 4373cf7bc3
commit db298b0fb8
13 changed files with 326 additions and 136 deletions

View File

@ -1,20 +1,47 @@
/*! Managing the events belonging to virtual-keyboard interface. */
use ::keyboard::{ KeyCode, Modifiers, PressType };
use ::layout::c::LevelKeyboard;
use ::keyboard::{ Modifiers, PressType };
use ::submission::Timestamp;
/// Standard xkb keycode
type KeyCode = u32;
/// Gathers stuff defined in C or called by C
pub mod c {
use super::*;
use std::os::raw::c_void;
use std::ffi::CStr;
use std::os::raw::{ c_char, c_void };
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct ZwpVirtualKeyboardV1(*const c_void);
#[repr(C)]
pub struct KeyMap {
fd: u32,
fd_len: usize,
}
impl KeyMap {
pub fn from_cstr(s: &CStr) -> KeyMap {
unsafe {
squeek_key_map_from_str(s.as_ptr())
}
}
}
impl Drop for KeyMap {
fn drop(&mut self) {
unsafe {
close(self.fd as u32);
}
}
}
#[no_mangle]
extern "C" {
// From libc, to let KeyMap get deallocated.
fn close(fd: u32);
pub fn eek_virtual_keyboard_v1_key(
virtual_keyboard: ZwpVirtualKeyboardV1,
timestamp: u32,
@ -24,13 +51,15 @@ pub mod c {
pub fn eek_virtual_keyboard_update_keymap(
virtual_keyboard: ZwpVirtualKeyboardV1,
keyboard: LevelKeyboard,
keymap: *const KeyMap,
);
pub fn eek_virtual_keyboard_set_modifiers(
virtual_keyboard: ZwpVirtualKeyboardV1,
modifiers: u32,
);
pub fn squeek_key_map_from_str(keymap_str: *const c_char) -> KeyMap;
}
}
@ -41,35 +70,15 @@ impl VirtualKeyboard {
// TODO: error out if keymap not set
pub fn switch(
&self,
keycodes: &[KeyCode],
keycode: KeyCode,
action: PressType,
timestamp: Timestamp,
) {
let keycodes_count = keycodes.len();
for keycode in keycodes.iter() {
let keycode = keycode - 8;
match (action, keycodes_count) {
// Pressing a key made out of a single keycode is simple:
// press on press, release on release.
(_, 1) => unsafe {
c::eek_virtual_keyboard_v1_key(
self.0, timestamp.0, keycode, action.clone() as u32
);
},
// A key made of multiple keycodes
// has to submit them one after the other
(PressType::Pressed, _) => unsafe {
c::eek_virtual_keyboard_v1_key(
self.0, timestamp.0, keycode, PressType::Pressed as u32
);
c::eek_virtual_keyboard_v1_key(
self.0, timestamp.0, keycode, PressType::Released as u32
);
},
// Design choice here: submit multiple all at press time
// and do nothing at release time
(PressType::Released, _) => {},
}
let keycode = keycode - 8;
unsafe {
c::eek_virtual_keyboard_v1_key(
self.0, timestamp.0, keycode, action.clone() as u32
);
}
}
@ -80,9 +89,12 @@ impl VirtualKeyboard {
}
}
pub fn update_keymap(&self, keyboard: LevelKeyboard) {
pub fn update_keymap(&self, keymap: &c::KeyMap) {
unsafe {
c::eek_virtual_keyboard_update_keymap(self.0, keyboard);
c::eek_virtual_keyboard_update_keymap(
self.0,
keymap as *const c::KeyMap,
);
}
}
}