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:
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user