wayland: implement virtual-keyboard
This commit is contained in:
parent
826f40adca
commit
6c0e3a4fff
20 changed files with 689 additions and 14 deletions
188
src/it/tests/t0040_virtual_keyboard.rs
Normal file
188
src/it/tests/t0040_virtual_keyboard.rs
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
use {
|
||||
crate::{
|
||||
backend::KeyState,
|
||||
clientmem::ClientMem,
|
||||
it::{test_error::TestResult, testrun::TestRun},
|
||||
xkbcommon::XkbContext,
|
||||
},
|
||||
bstr::ByteSlice,
|
||||
std::rc::Rc,
|
||||
};
|
||||
|
||||
testcase!();
|
||||
|
||||
async fn test(run: Rc<TestRun>) -> TestResult {
|
||||
let virtual_keymap_str = {
|
||||
let xkb = XkbContext::new()?;
|
||||
let map = xkb.keymap_from_str(VIRTUAL_KEYMAP).unwrap();
|
||||
read_keymap(map.map.raw(), map.map_len)
|
||||
};
|
||||
|
||||
let ds = run.create_default_setup().await?;
|
||||
|
||||
let s_client = run.create_client().await?;
|
||||
let s_seat = s_client.get_default_seat().await?;
|
||||
let s_win = s_client.create_window().await?;
|
||||
s_win.map2().await?;
|
||||
s_client.sync().await;
|
||||
|
||||
let s_keymap = s_seat.kb.keymap.expect()?;
|
||||
let s_key = s_seat.kb.key.expect()?;
|
||||
let s_modifiers = s_seat.kb.modifiers.expect()?;
|
||||
|
||||
{
|
||||
let v_client = run.create_client().await?;
|
||||
let v_seat = v_client.get_default_seat().await?;
|
||||
let v_kb = v_client
|
||||
.registry
|
||||
.get_virtual_keyboard_manager()
|
||||
.await?
|
||||
.create_virtual_keyboard(&v_seat.seat)?;
|
||||
v_kb.set_keymap(VIRTUAL_KEYMAP)?;
|
||||
v_kb.key(10, KeyState::Pressed)?;
|
||||
v_kb.key(10, KeyState::Released)?;
|
||||
v_kb.modifiers(1, 2, 3, 0)?;
|
||||
v_kb.key(10, KeyState::Pressed)?;
|
||||
v_kb.key(10, KeyState::Released)?;
|
||||
v_kb.modifiers(0, 0, 0, 1)?;
|
||||
v_client.sync().await;
|
||||
}
|
||||
|
||||
s_client.sync().await;
|
||||
let (start, keymap) = s_keymap.next().expect("virtual keymap");
|
||||
tassert_eq!(
|
||||
&read_keymap(keymap.fd.raw(), keymap.size as _),
|
||||
&virtual_keymap_str
|
||||
);
|
||||
{
|
||||
let (pos, mods) = s_modifiers.next().expect("mods 0");
|
||||
tassert_eq!(pos, start + 1);
|
||||
tassert_eq!(
|
||||
(
|
||||
mods.mods_depressed,
|
||||
mods.mods_latched,
|
||||
mods.mods_locked,
|
||||
mods.group
|
||||
),
|
||||
(0, 0, 0, 0)
|
||||
);
|
||||
}
|
||||
{
|
||||
let (pos, key) = s_key.next().expect("key 1");
|
||||
tassert_eq!(pos, start + 2);
|
||||
tassert_eq!((key.key, key.state), (10, 1));
|
||||
}
|
||||
{
|
||||
let (pos, key) = s_key.next().expect("key 2");
|
||||
tassert_eq!(pos, start + 3);
|
||||
tassert_eq!((key.key, key.state), (10, 0));
|
||||
}
|
||||
{
|
||||
let (pos, mods) = s_modifiers.next().expect("mods 1");
|
||||
tassert_eq!(pos, start + 4);
|
||||
tassert_eq!(
|
||||
(
|
||||
mods.mods_depressed,
|
||||
mods.mods_latched,
|
||||
mods.mods_locked,
|
||||
mods.group
|
||||
),
|
||||
(1, 2, 3, 0)
|
||||
);
|
||||
}
|
||||
{
|
||||
let (pos, key) = s_key.next().expect("key 3");
|
||||
tassert_eq!(pos, start + 5);
|
||||
tassert_eq!((key.key, key.state), (10, 1));
|
||||
}
|
||||
{
|
||||
let (pos, key) = s_key.next().expect("key 4");
|
||||
tassert_eq!(pos, start + 6);
|
||||
tassert_eq!((key.key, key.state), (10, 0));
|
||||
}
|
||||
{
|
||||
let (pos, mods) = s_modifiers.next().expect("mods 2");
|
||||
tassert_eq!(pos, start + 7);
|
||||
tassert_eq!(
|
||||
(
|
||||
mods.mods_depressed,
|
||||
mods.mods_latched,
|
||||
mods.mods_locked,
|
||||
mods.group
|
||||
),
|
||||
(0, 0, 0, 0)
|
||||
);
|
||||
}
|
||||
|
||||
ds.kb.press(10);
|
||||
|
||||
s_client.sync().await;
|
||||
let (pos, keymap) = s_keymap.next().expect("seat keymap");
|
||||
tassert_eq!(pos, start + 8);
|
||||
tassert!(read_keymap(keymap.fd.raw(), keymap.size as _) != virtual_keymap_str);
|
||||
{
|
||||
let (pos, mods) = s_modifiers.next().expect("mods 0");
|
||||
tassert_eq!(pos, start + 9);
|
||||
tassert_eq!(
|
||||
(
|
||||
mods.mods_depressed,
|
||||
mods.mods_latched,
|
||||
mods.mods_locked,
|
||||
mods.group
|
||||
),
|
||||
(0, 0, 0, 0)
|
||||
);
|
||||
}
|
||||
{
|
||||
let (pos, key) = s_key.next().expect("key 5");
|
||||
tassert_eq!(pos, start + 10);
|
||||
tassert_eq!((key.key, key.state), (10, 1));
|
||||
}
|
||||
{
|
||||
let (pos, key) = s_key.next().expect("key 6");
|
||||
tassert_eq!(pos, start + 11);
|
||||
tassert_eq!((key.key, key.state), (10, 0));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_keymap(fd: i32, size: usize) -> String {
|
||||
let client_mem = ClientMem::new(fd, size - 1, true).unwrap();
|
||||
let client_mem = Rc::new(client_mem).offset(0);
|
||||
let mut v = vec![];
|
||||
client_mem.read(&mut v).unwrap();
|
||||
v.as_bstr().to_string()
|
||||
}
|
||||
|
||||
const VIRTUAL_KEYMAP: &str = r#"
|
||||
xkb_keymap {
|
||||
xkb_keycodes {
|
||||
<2> = 10; # 1
|
||||
<29> = 37; # LEFTCTRL
|
||||
};
|
||||
|
||||
xkb_types {
|
||||
type "TWO_LEVEL" {
|
||||
modifiers = Control;
|
||||
map[Control] = Level2;
|
||||
level_name[Level1] = "Base";
|
||||
level_name[Level2] = "Control";
|
||||
};
|
||||
};
|
||||
|
||||
xkb_compatibility {
|
||||
interpret.repeat = False;
|
||||
interpret.locking = False;
|
||||
interpret Control_L {
|
||||
action = SetMods(modifiers=Control);
|
||||
};
|
||||
};
|
||||
|
||||
xkb_symbols {
|
||||
key <2> { [ 2, at ] };
|
||||
key <29> { [ Control_L ] };
|
||||
};
|
||||
|
||||
};
|
||||
"#;
|
||||
Loading…
Add table
Add a link
Reference in a new issue