167 lines
5.6 KiB
Rust
167 lines
5.6 KiB
Rust
use {
|
|
crate::{
|
|
client::{ClientId, RequestParser},
|
|
fixed::Fixed,
|
|
ifs::wl_seat::WlSeatGlobal,
|
|
it::{
|
|
test_backend::{TestBackend, TestBackendKb, TestBackendMouse, TestConnector},
|
|
test_client::TestClient,
|
|
test_config::TestConfig,
|
|
test_error::{TestError, TestErrorExt},
|
|
test_ifs::test_display::TestDisplay,
|
|
test_transport::TestTransport,
|
|
},
|
|
object::WL_DISPLAY_ID,
|
|
state::State,
|
|
tree::OutputNode,
|
|
utils::{bitfield::Bitfield, buffd::MsgParser, oserror::OsErrorExt, stack::Stack},
|
|
},
|
|
std::{
|
|
cell::{Cell, RefCell},
|
|
rc::Rc,
|
|
},
|
|
uapi::c,
|
|
};
|
|
|
|
pub struct TestRun {
|
|
pub state: Rc<State>,
|
|
pub backend: Rc<TestBackend>,
|
|
pub errors: Stack<String>,
|
|
pub server_addr: c::sockaddr_un,
|
|
pub out_dir: String,
|
|
pub in_dir: String,
|
|
pub cfg: Rc<TestConfig>,
|
|
}
|
|
|
|
impl TestRun {
|
|
pub async fn create_client(self: &Rc<Self>) -> Result<Rc<TestClient>, TestError> {
|
|
self.create_client2()
|
|
.await
|
|
.with_context(|| "Could not create a client")
|
|
}
|
|
|
|
async fn create_client2(self: &Rc<Self>) -> Result<Rc<TestClient>, TestError> {
|
|
let socket = uapi::socket(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0)
|
|
.to_os_error()
|
|
.with_context(|| "Could not create a unix socket")?;
|
|
let socket = Rc::new(socket);
|
|
self.backend
|
|
.state
|
|
.ring
|
|
.connect(&socket, &self.server_addr)
|
|
.await
|
|
.with_context(|| "Could not connect to the compositor")?;
|
|
let mut obj_ids = Bitfield::default();
|
|
obj_ids.take(0);
|
|
obj_ids.take(1);
|
|
let tran = Rc::new(TestTransport {
|
|
run: self.clone(),
|
|
socket,
|
|
client_id: Cell::new(ClientId::from_raw(0)),
|
|
swapchain: Default::default(),
|
|
flush_request: Default::default(),
|
|
incoming: Default::default(),
|
|
outgoing: Default::default(),
|
|
objects: Default::default(),
|
|
obj_ids: RefCell::new(obj_ids),
|
|
killed: Cell::new(false),
|
|
});
|
|
tran.add_obj(Rc::new(TestDisplay {
|
|
tran: tran.clone(),
|
|
id: WL_DISPLAY_ID,
|
|
}))?;
|
|
tran.init();
|
|
let registry = tran.get_registry();
|
|
let jc = registry.get_jay_compositor().await?;
|
|
jc.enable_symmetric_delete()?;
|
|
let client_id = jc.get_client_id().await?;
|
|
let client = self.state.clients.get(client_id)?;
|
|
Ok(Rc::new(TestClient {
|
|
run: self.clone(),
|
|
server: client,
|
|
tran,
|
|
jc,
|
|
comp: registry.get_compositor().await?,
|
|
sub: registry.get_subcompositor().await?,
|
|
shm: registry.get_shm().await?,
|
|
spbm: registry.get_spbm().await?,
|
|
viewporter: registry.get_viewporter().await?,
|
|
xdg: registry.get_xdg().await?,
|
|
activation: registry.get_activation().await?,
|
|
data_device_manager: registry.get_data_device_manager().await?,
|
|
cursor_shape_manager: registry.get_cursor_shape_manager().await?,
|
|
fifo_manager: registry.get_fifo_manager().await?,
|
|
pointer_warp: registry.get_pointer_warp().await?,
|
|
registry,
|
|
}))
|
|
}
|
|
|
|
pub fn get_seat(&self, name: &str) -> Result<Rc<WlSeatGlobal>, TestError> {
|
|
let id = self.cfg.get_seat(name)?;
|
|
for seat in self.state.globals.seats.lock().values() {
|
|
if seat.id() == id {
|
|
return Ok(seat.clone());
|
|
}
|
|
}
|
|
bail!("Seat {} does not exist", id)
|
|
}
|
|
|
|
pub async fn create_default_setup(&self) -> Result<DefaultSetup, TestError> {
|
|
self.create_default_setup2(false).await
|
|
}
|
|
|
|
pub async fn create_default_setup2(&self, need_drm: bool) -> Result<DefaultSetup, TestError> {
|
|
self.backend.install_default2(need_drm)?;
|
|
let seat = self.get_seat("default")?;
|
|
self.state.eng.yield_now().await;
|
|
let output = match self.state.root.outputs.lock().values().next() {
|
|
None => bail!("No output"),
|
|
Some(d) => d.clone(),
|
|
};
|
|
self.cfg
|
|
.set_input_device_seat(self.backend.default_kb.common.id, seat.id())?;
|
|
self.cfg
|
|
.set_input_device_seat(self.backend.default_mouse.common.id, seat.id())?;
|
|
self.backend.default_mouse.click(1);
|
|
self.state.eng.yield_now().await;
|
|
self.cfg.show_workspace(seat.id(), "")?;
|
|
Ok(DefaultSetup {
|
|
connector: self.backend.default_connector.clone(),
|
|
output,
|
|
kb: self.backend.default_kb.clone(),
|
|
mouse: self.backend.default_mouse.clone(),
|
|
seat,
|
|
})
|
|
}
|
|
|
|
pub async fn sync(&self) {
|
|
self.state.eng.yield_now().await;
|
|
}
|
|
}
|
|
|
|
pub trait ParseFull<'a>: Sized {
|
|
fn parse_full(parser: MsgParser<'_, 'a>) -> Result<Self, TestError>;
|
|
}
|
|
|
|
impl<'a, T: RequestParser<'a>> ParseFull<'a> for T {
|
|
fn parse_full(mut parser: MsgParser<'_, 'a>) -> Result<Self, TestError> {
|
|
T::parse(&mut parser).map_err(Into::into)
|
|
}
|
|
}
|
|
|
|
pub struct DefaultSetup {
|
|
pub connector: Rc<TestConnector>,
|
|
pub output: Rc<OutputNode>,
|
|
pub kb: Rc<TestBackendKb>,
|
|
pub mouse: Rc<TestBackendMouse>,
|
|
pub seat: Rc<WlSeatGlobal>,
|
|
}
|
|
|
|
impl DefaultSetup {
|
|
pub fn move_to(&self, x: i32, y: i32) {
|
|
let (ox, oy) = self.seat.pointer_cursor().position();
|
|
let (nx, ny) = (Fixed::from_int(x), Fixed::from_int(y));
|
|
let (dx, dy) = (nx - ox, ny - oy);
|
|
self.mouse.rel(dx.to_f64(), dy.to_f64())
|
|
}
|
|
}
|