1
0
Fork 0
forked from wry/wry

wayland: implement virtual-keyboard

This commit is contained in:
Julian Orth 2024-04-12 19:58:42 +02:00
parent 826f40adca
commit 6c0e3a4fff
20 changed files with 689 additions and 14 deletions

View file

@ -5,7 +5,7 @@ use {
test_error::TestResult, test_object::TestObject, test_transport::TestTransport,
test_utils::test_expected_event::TEEH, testrun::ParseFull,
},
utils::{buffd::MsgParser, clonecell::CloneCell, once::Once},
utils::{buffd::MsgParser, clonecell::CloneCell, numcell::NumCell, once::Once},
wire::{wl_keyboard::*, WlKeyboardId, WlSurfaceId},
},
std::rc::Rc,
@ -22,8 +22,12 @@ pub struct TestKeyboard {
pub tran: Rc<TestTransport>,
pub server: CloneCell<Option<Rc<WlKeyboard>>>,
pub destroyed: Once,
pub keymap: TEEH<(usize, Keymap)>,
pub key: TEEH<(usize, Key)>,
pub modifiers: TEEH<(usize, Modifiers)>,
pub enter: TEEH<TestEnterEvent>,
pub leave: TEEH<Leave>,
pub event_id: NumCell<usize>,
}
impl TestKeyboard {
@ -35,7 +39,8 @@ impl TestKeyboard {
}
fn handle_keymap(&self, parser: MsgParser<'_, '_>) -> TestResult {
let _ev = Keymap::parse_full(parser)?;
let ev = Keymap::parse_full(parser)?;
self.keymap.push((self.event_id.fetch_add(1), ev));
Ok(())
}
@ -56,12 +61,14 @@ impl TestKeyboard {
}
fn handle_key(&self, parser: MsgParser<'_, '_>) -> TestResult {
let _ev = Key::parse_full(parser)?;
let ev = Key::parse_full(parser)?;
self.key.push((self.event_id.fetch_add(1), ev));
Ok(())
}
fn handle_modifiers(&self, parser: MsgParser<'_, '_>) -> TestResult {
let _ev = Modifiers::parse_full(parser)?;
let ev = Modifiers::parse_full(parser)?;
self.modifiers.push((self.event_id.fetch_add(1), ev));
Ok(())
}

View file

@ -15,8 +15,9 @@ use {
test_single_pixel_buffer_manager::TestSinglePixelBufferManager,
test_subcompositor::TestSubcompositor, test_syncobj_manager::TestSyncobjManager,
test_toplevel_drag_manager::TestToplevelDragManager,
test_viewporter::TestViewporter, test_xdg_activation::TestXdgActivation,
test_xdg_base::TestXdgWmBase,
test_viewporter::TestViewporter,
test_virtual_keyboard_manager::TestVirtualKeyboardManager,
test_xdg_activation::TestXdgActivation, test_xdg_base::TestXdgWmBase,
},
test_object::TestObject,
test_transport::TestTransport,
@ -52,6 +53,7 @@ pub struct TestRegistrySingletons {
pub zwp_linux_dmabuf_v1: u32,
pub xdg_toplevel_drag_manager_v1: u32,
pub wp_alpha_modifier_v1: u32,
pub zwp_virtual_keyboard_manager_v1: u32,
}
pub struct TestRegistry {
@ -76,6 +78,7 @@ pub struct TestRegistry {
pub dmabuf: CloneCell<Option<Rc<TestDmabuf>>>,
pub drag_manager: CloneCell<Option<Rc<TestToplevelDragManager>>>,
pub alpha_modifier: CloneCell<Option<Rc<TestAlphaModifier>>>,
pub virtual_keyboard_manager: CloneCell<Option<Rc<TestVirtualKeyboardManager>>>,
pub seats: CopyHashMap<GlobalName, Rc<WlSeatGlobal>>,
}
@ -144,6 +147,7 @@ impl TestRegistry {
zwp_linux_dmabuf_v1,
xdg_toplevel_drag_manager_v1,
wp_alpha_modifier_v1,
zwp_virtual_keyboard_manager_v1,
};
self.singletons.set(Some(singletons.clone()));
Ok(singletons)
@ -238,6 +242,13 @@ impl TestRegistry {
1,
TestAlphaModifier
);
create_singleton!(
get_virtual_keyboard_manager,
virtual_keyboard_manager,
zwp_virtual_keyboard_manager_v1,
1,
TestVirtualKeyboardManager
);
pub fn bind<O: TestObject>(
&self,

View file

@ -42,8 +42,12 @@ impl TestSeat {
tran: self.tran.clone(),
server: Default::default(),
destroyed: Default::default(),
keymap: Default::default(),
key: Default::default(),
modifiers: Default::default(),
enter: Default::default(),
leave: Default::default(),
event_id: Default::default(),
});
self.tran.add_obj(kb.clone())?;
self.tran.sync().await;

View file

@ -0,0 +1,86 @@
use {
crate::{
backend::KeyState,
ifs::wl_seat::wl_keyboard,
it::{test_error::TestError, test_object::TestObject, test_transport::TestTransport},
time::now_usec,
wire::{zwp_virtual_keyboard_v1::*, ZwpVirtualKeyboardV1Id},
},
std::{cell::Cell, io::Write, rc::Rc},
uapi::c,
};
pub struct TestVirtualKeyboard {
pub id: ZwpVirtualKeyboardV1Id,
pub tran: Rc<TestTransport>,
pub destroyed: Cell<bool>,
}
impl TestVirtualKeyboard {
pub fn destroy(&self) -> Result<(), TestError> {
if !self.destroyed.replace(true) {
self.tran.send(Destroy { self_id: self.id })?;
}
Ok(())
}
pub fn set_keymap(&self, map: &str) -> Result<(), TestError> {
let mut memfd =
uapi::memfd_create("keymap", c::MFD_CLOEXEC | c::MFD_ALLOW_SEALING).unwrap();
memfd.write_all(map.as_bytes()).unwrap();
memfd.write_all(&[0]).unwrap();
uapi::lseek(memfd.raw(), 0, c::SEEK_SET).unwrap();
uapi::fcntl_add_seals(
memfd.raw(),
c::F_SEAL_SEAL | c::F_SEAL_GROW | c::F_SEAL_SHRINK | c::F_SEAL_WRITE,
)
.unwrap();
self.tran.send(Keymap {
self_id: self.id,
format: wl_keyboard::XKB_V1,
fd: Rc::new(memfd),
size: map.len() as _,
})
}
pub fn key(&self, key: u32, state: KeyState) -> Result<(), TestError> {
let state = match state {
KeyState::Released => wl_keyboard::RELEASED,
KeyState::Pressed => wl_keyboard::PRESSED,
};
self.tran.send(Key {
self_id: self.id,
time: (now_usec() / 1000) as u32,
key,
state,
})
}
pub fn modifiers(
&self,
mods_depressed: u32,
mods_latched: u32,
mods_locked: u32,
group: u32,
) -> Result<(), TestError> {
self.tran.send(Modifiers {
self_id: self.id,
mods_depressed,
mods_latched,
mods_locked,
group,
})
}
}
impl Drop for TestVirtualKeyboard {
fn drop(&mut self) {
let _ = self.destroy();
}
}
test_object! {
TestVirtualKeyboard, ZwpVirtualKeyboardV1;
}
impl TestObject for TestVirtualKeyboard {}

View file

@ -0,0 +1,49 @@
use {
crate::{
it::{
test_error::TestResult,
test_ifs::{test_seat::TestSeat, test_virtual_keyboard::TestVirtualKeyboard},
test_object::TestObject,
test_transport::TestTransport,
},
wire::{zwp_virtual_keyboard_manager_v1::*, ZwpVirtualKeyboardManagerV1Id},
},
std::{cell::Cell, rc::Rc},
};
pub struct TestVirtualKeyboardManager {
pub id: ZwpVirtualKeyboardManagerV1Id,
pub tran: Rc<TestTransport>,
pub destroyed: Cell<bool>,
}
impl TestVirtualKeyboardManager {
pub fn new(tran: &Rc<TestTransport>) -> Self {
Self {
id: tran.id(),
tran: tran.clone(),
destroyed: Cell::new(false),
}
}
pub fn create_virtual_keyboard(&self, seat: &TestSeat) -> TestResult<Rc<TestVirtualKeyboard>> {
let obj = Rc::new(TestVirtualKeyboard {
id: self.tran.id(),
tran: self.tran.clone(),
destroyed: Cell::new(false),
});
self.tran.add_obj(obj.clone())?;
self.tran.send(CreateVirtualKeyboard {
self_id: self.id,
seat: seat.id,
id: obj.id,
})?;
Ok(obj)
}
}
test_object! {
TestVirtualKeyboardManager, ZwpVirtualKeyboardManagerV1;
}
impl TestObject for TestVirtualKeyboardManager {}