1
0
Fork 0
forked from wry/wry

autocommit 2022-02-15 22:53:12 CET

This commit is contained in:
Julian Orth 2022-02-15 22:53:12 +01:00
parent 290225190a
commit cacd49d15a
33 changed files with 884 additions and 220 deletions

View file

@ -71,7 +71,7 @@ fn bind_socket(fd: i32, xdr: &str) -> Result<u32, AcceptorError> {
}
impl Acceptor {
pub fn install(global: &Rc<State>) -> Result<(), AcceptorError> {
pub fn install(global: &Rc<State>) -> Result<String, AcceptorError> {
let xrd = match std::env::var("XDG_RUNTIME_DIR") {
Ok(d) => d,
Err(_) => return Err(AcceptorError::XrdNotSet),
@ -87,7 +87,7 @@ impl Acceptor {
let socket_id = bind_socket(fd.raw(), &xrd)?;
let socket_path = socket_path(&xrd, socket_id);
log::info!("bound to socket {}", socket_path);
let unlinker = Unlinker(socket_path);
let unlinker = Unlinker(socket_path.clone());
if let Err(e) = uapi::listen(fd.raw(), 4096) {
return Err(AcceptorError::ListenFailed(e.into()));
}
@ -99,7 +99,7 @@ impl Acceptor {
global: global.clone(),
});
global.el.insert(id, Some(acc.fd.raw()), c::EPOLLIN, acc)?;
Ok(())
Ok(socket_path)
}
}

View file

@ -1,4 +1,7 @@
use crate::backend::{BackendEvent, Keyboard, KeyboardEvent, KeyboardId, KeyState, Mouse, MouseEvent, MouseId, Output, OutputId, ScrollAxis};
use crate::backend::{
BackendEvent, KeyState, Keyboard, KeyboardEvent, KeyboardId, Mouse, MouseEvent, MouseId,
Output, OutputId, ScrollAxis,
};
use crate::drm::drm::{Drm, DrmError};
use crate::drm::gbm::{GbmDevice, GbmError, GBM_BO_USE_RENDERING};
use crate::drm::{ModifiedFormat, INVALID_MODIFIER};

View file

@ -1,19 +1,19 @@
mod handler;
use crate::backend::{KeyboardId, MouseId};
use crate::config::handler::ConfigProxyHandler;
use crate::ifs::wl_seat::SeatId;
use crate::utils::ptr_ext::PtrExt;
use crate::{NumCell, State};
use i4config::_private::ipc::{InitMessage, Request, V1InitMessage};
use i4config::_private::ipc::{InitMessage, ServerMessage, V1InitMessage};
use i4config::_private::{bincode_ops, ConfigEntry, VERSION};
use i4config::keyboard::ModifiedKeySym;
use i4config::{InputDevice, Keyboard, Mouse, Seat};
use libloading::Library;
use std::cell::Cell;
use std::ptr;
use std::rc::Rc;
use thiserror::Error;
use i4config::{InputDevice, Keyboard, Mouse, Seat};
use crate::config::handler::ConfigProxyHandler;
use crate::ifs::wl_seat::{SeatId};
#[derive(Debug, Error)]
pub enum ConfigError {
@ -29,7 +29,7 @@ pub struct ConfigProxy {
impl ConfigProxy {
pub fn invoke_shortcut(&self, seat: SeatId, modsym: &ModifiedKeySym) {
self.handler.send(&Request::InvokeShortcut {
self.handler.send(&ServerMessage::InvokeShortcut {
seat: Seat(seat.raw() as _),
mods: modsym.mods,
sym: modsym.sym,
@ -37,25 +37,25 @@ impl ConfigProxy {
}
pub fn new_keyboard(&self, kb: KeyboardId) {
self.handler.send(&Request::NewInputDevice {
self.handler.send(&ServerMessage::NewInputDevice {
device: InputDevice::Keyboard(Keyboard(kb.raw() as _)),
});
}
pub fn new_mouse(&self, mouse: MouseId) {
self.handler.send(&Request::NewInputDevice {
self.handler.send(&ServerMessage::NewInputDevice {
device: InputDevice::Mouse(Mouse(mouse.raw() as _)),
});
}
pub fn del_keyboard(&self, kb: KeyboardId) {
self.handler.send(&Request::DelInputDevice {
self.handler.send(&ServerMessage::DelInputDevice {
device: InputDevice::Keyboard(Keyboard(kb.raw() as _)),
});
}
pub fn del_mouse(&self, mouse: MouseId) {
self.handler.send(&Request::DelInputDevice {
self.handler.send(&ServerMessage::DelInputDevice {
device: InputDevice::Mouse(Mouse(mouse.raw() as _)),
});
}
@ -110,7 +110,7 @@ impl ConfigProxy {
);
data.client_data.set(client_data);
}
data.send(&Request::Configure);
data.send(&ServerMessage::Configure);
Self { handler: data }
}

View file

@ -1,16 +1,3 @@
use std::cell::{Cell};
use std::rc::Rc;
use bincode::error::DecodeError;
use libloading::Library;
use log::Level;
use thiserror::Error;
use i4config::_private::bincode_ops;
use i4config::_private::ipc::{Request, Response};
use i4config::keyboard::keymap::Keymap;
use i4config::{Axis, Direction, InputDevice, Keyboard, LogLevel, Mouse, Seat};
use i4config::keyboard::mods::Modifiers;
use i4config::keyboard::syms::KeySym;
use crate::{ErrorFmt, NumCell, State};
use crate::backend::{KeyboardId, MouseId};
use crate::ifs::wl_seat::WlSeatGlobal;
use crate::state::DeviceHandlerData;
@ -19,6 +6,19 @@ use crate::utils::copyhashmap::CopyHashMap;
use crate::utils::debug_fn::debug_fn;
use crate::utils::stack::Stack;
use crate::xkbcommon::XkbKeymap;
use crate::{ErrorFmt, NumCell, State};
use bincode::error::DecodeError;
use i4config::_private::bincode_ops;
use i4config::_private::ipc::{ClientMessage, Response, ServerMessage};
use i4config::keyboard::keymap::Keymap;
use i4config::keyboard::mods::Modifiers;
use i4config::keyboard::syms::KeySym;
use i4config::{Axis, Direction, InputDevice, Keyboard, LogLevel, Mouse, Seat};
use libloading::Library;
use log::Level;
use std::cell::Cell;
use std::rc::Rc;
use thiserror::Error;
pub(super) struct ConfigProxyHandler {
pub client_data: Cell<*const u8>,
@ -34,7 +34,7 @@ pub(super) struct ConfigProxyHandler {
}
impl ConfigProxyHandler {
pub fn send(&self, msg: &Request) {
pub fn send(&self, msg: &ServerMessage) {
let mut buf = self.bufs.pop().unwrap_or_default();
buf.clear();
bincode::encode_into_std_write(msg, &mut buf, bincode_ops()).unwrap();
@ -48,7 +48,13 @@ impl ConfigProxyHandler {
self.next_id.fetch_add(1)
}
fn handle_log_request(&self, level: LogLevel, msg: &str, file: Option<&str>, line: Option<u32>) -> Result<(), LogError> {
fn handle_log_request(
&self,
level: LogLevel,
msg: &str,
file: Option<&str>,
line: Option<u32>,
) -> Result<(), LogError> {
let level = match level {
LogLevel::Error => Level::Error,
LogLevel::Warn => Level::Warn,
@ -75,10 +81,10 @@ impl ConfigProxyHandler {
let global_name = self.state.globals.name();
let seat = WlSeatGlobal::new(global_name, name, &self.state);
self.state.globals.add_global(&self.state, &seat);
self.send(&Request::Response {
self.send(&ServerMessage::Response {
response: Response::CreateSeat {
seat: Seat(seat.id().raw() as _),
}
},
});
Ok(())
}
@ -90,11 +96,11 @@ impl ConfigProxyHandler {
self.keymaps.set(id, keymap);
(id, Ok(()))
}
_ => {
(Keymap::INVALID, Err(ParseKeymapError::ParsingFailed))
}
_ => (Keymap::INVALID, Err(ParseKeymapError::ParsingFailed)),
};
self.send(&Request::Response { response: Response::ParseKeymap { keymap } });
self.send(&ServerMessage::Response {
response: Response::ParseKeymap { keymap },
});
res
}
@ -118,16 +124,18 @@ impl ConfigProxyHandler {
fn handle_get_repeat_rate(&self, seat: Seat) -> Result<(), SeatGetRepeatRateError> {
let seat = self.get_seat(seat)?;
let (rate, delay) = seat.get_rate();
self.send(&Request::Response {
response: Response::GetRepeatRate {
rate,
delay,
},
self.send(&ServerMessage::Response {
response: Response::GetRepeatRate { rate, delay },
});
Ok(())
}
fn handle_set_repeat_rate(&self, seat: Seat, rate: i32, delay: i32) -> Result<(), SeatSetRepeatRateError> {
fn handle_set_repeat_rate(
&self,
seat: Seat,
rate: i32,
delay: i32,
) -> Result<(), SeatSetRepeatRateError> {
let seat = self.get_seat(seat)?;
if rate < 0 {
return Err(SeatSetRepeatRateError::NegativeRate);
@ -139,14 +147,23 @@ impl ConfigProxyHandler {
Ok(())
}
fn get_device_handler_data(&self, device: InputDevice) -> Result<Rc<DeviceHandlerData>, CphError> {
fn get_device_handler_data(
&self,
device: InputDevice,
) -> Result<Rc<DeviceHandlerData>, CphError> {
let data = match device {
InputDevice::Keyboard(kb) => {
self.state.kb_handlers.borrow_mut().get(&KeyboardId::from_raw(kb.0 as _)).map(|d| d.data.clone())
},
InputDevice::Mouse(mouse) => {
self.state.mouse_handlers.borrow_mut().get(&MouseId::from_raw(mouse.0 as _)).map(|d| d.data.clone())
}
InputDevice::Keyboard(kb) => self
.state
.kb_handlers
.borrow_mut()
.get(&KeyboardId::from_raw(kb.0 as _))
.map(|d| d.data.clone()),
InputDevice::Mouse(mouse) => self
.state
.mouse_handlers
.borrow_mut()
.get(&MouseId::from_raw(mouse.0 as _))
.map(|d| d.data.clone()),
};
match data {
Some(d) => Ok(d),
@ -184,10 +201,13 @@ impl ConfigProxyHandler {
fn handle_get_split(&self, seat: Seat) -> Result<(), GetSplitError> {
let seat = self.get_seat(seat)?;
self.send(&Request::Response {
self.send(&ServerMessage::Response {
response: Response::GetSplit {
axis: seat.get_split().unwrap_or(ContainerSplit::Horizontal).into(),
}
axis: seat
.get_split()
.unwrap_or(ContainerSplit::Horizontal)
.into(),
},
});
Ok(())
}
@ -198,14 +218,19 @@ impl ConfigProxyHandler {
Ok(())
}
fn handle_add_shortcut(&self, seat: Seat, mods: Modifiers, sym: KeySym) -> Result<(), AddShortcutError> {
fn handle_add_shortcut(
&self,
seat: Seat,
mods: Modifiers,
sym: KeySym,
) -> Result<(), AddShortcutError> {
let seat = self.get_seat(seat)?;
seat.add_shortcut(mods, sym);
Ok(())
}
fn handle_get_input_devices(&self) -> Result<(), GetInputDevicesError> {
let mut res = vec!();
let mut res = vec![];
{
let devs = self.state.kb_handlers.borrow_mut();
for dev in devs.values() {
@ -218,7 +243,7 @@ impl ConfigProxyHandler {
res.push(InputDevice::Mouse(Mouse(dev.id.raw() as _)));
}
}
self.send(&Request::Response {
self.send(&ServerMessage::Response {
response: Response::GetInputDevices { devices: res },
});
Ok(())
@ -232,12 +257,21 @@ impl ConfigProxyHandler {
.map(|seat| Seat::from_raw(seat.id().raw() as _))
.collect()
};
self.send(&Request::Response {
self.send(&ServerMessage::Response {
response: Response::GetSeats { seats },
});
Ok(())
}
fn handle_run(&self, prog: &str, args: Vec<String>, env: Vec<(String, String)>) -> Result<(), RunError> {
let forker = match self.state.forker.get() {
Some(f) => f,
_ => return Err(RunError::NoForker),
};
forker.spawn(prog.to_string(), args, env);
Ok(())
}
pub fn handle_request(&self, msg: &[u8]) {
if let Err(e) = self.handle_request_(msg) {
log::error!("Could not handle client request: {}", ErrorFmt(e));
@ -245,36 +279,40 @@ impl ConfigProxyHandler {
}
fn handle_request_(&self, msg: &[u8]) -> Result<(), CphError> {
let (request, _) = match bincode::decode_from_slice::<Request, _>(msg, bincode_ops()) {
let (request, _) = match bincode::decode_from_slice::<ClientMessage, _>(msg, bincode_ops())
{
Ok(msg) => msg,
Err(e) => return Err(CphError::ParsingFailed(e)),
};
match request {
Request::Log {
ClientMessage::Log {
level,
msg,
file,
line,
} => self.handle_log_request(level, msg, file, line)?,
Request::CreateSeat { name } => self.handle_create_seat(name)?,
Request::ParseKeymap { keymap } => self.handle_parse_keymap(keymap)?,
Request::SeatSetKeymap { seat, keymap } => self.handle_set_keymap(seat, keymap)?,
Request::SeatGetRepeatRate { seat } => self.handle_get_repeat_rate(seat)?,
Request::SeatSetRepeatRate { seat, rate, delay } => self.handle_set_repeat_rate(seat, rate, delay)?,
Request::SetSeat { device, seat } => self.handle_set_seat(device, seat)?,
Request::GetSplit { seat } => self.handle_get_split(seat)?,
Request::SetSplit { seat, axis } => self.handle_set_split(seat, axis)?,
Request::AddShortcut {
seat,
mods,
sym,
} => self.handle_add_shortcut(seat, mods, sym)?,
Request::RemoveShortcut { .. } => {}
Request::Focus { seat, direction } => self.handle_focus(seat, direction)?,
Request::Move { seat, direction } => {}
Request::GetInputDevices => self.handle_get_input_devices()?,
Request::GetSeats => self.handle_get_seats()?,
m => return Err(CphError::UnexpectedMessage(format!("{:?}", m))),
ClientMessage::CreateSeat { name } => self.handle_create_seat(name)?,
ClientMessage::ParseKeymap { keymap } => self.handle_parse_keymap(keymap)?,
ClientMessage::SeatSetKeymap { seat, keymap } => {
self.handle_set_keymap(seat, keymap)?
}
ClientMessage::SeatGetRepeatRate { seat } => self.handle_get_repeat_rate(seat)?,
ClientMessage::SeatSetRepeatRate { seat, rate, delay } => {
self.handle_set_repeat_rate(seat, rate, delay)?
}
ClientMessage::SetSeat { device, seat } => self.handle_set_seat(device, seat)?,
ClientMessage::GetSplit { seat } => self.handle_get_split(seat)?,
ClientMessage::SetSplit { seat, axis } => self.handle_set_split(seat, axis)?,
ClientMessage::AddShortcut { seat, mods, sym } => {
self.handle_add_shortcut(seat, mods, sym)?
}
ClientMessage::RemoveShortcut { .. } => {}
ClientMessage::Focus { seat, direction } => self.handle_focus(seat, direction)?,
ClientMessage::Move { seat, direction } => {}
ClientMessage::GetInputDevices => self.handle_get_input_devices()?,
ClientMessage::GetSeats => self.handle_get_seats()?,
ClientMessage::RemoveSeat { .. } => {}
ClientMessage::Run { prog, args, env } => self.handle_run(prog, args, env)?,
}
Ok(())
}
@ -308,6 +346,8 @@ enum CphError {
SetSplitError(#[from] SetSplitError),
#[error("Could not process a `get_split` request")]
GetSplitError(#[from] GetSplitError),
#[error("Could not process a `run` request")]
RunError(#[from] RunError),
#[error("Device {0:?} does not exist")]
DeviceDoesNotExist(InputDevice),
#[error("Device {0:?} does not exist")]
@ -321,14 +361,10 @@ enum CphError {
}
#[derive(Debug, Error)]
enum LogError {
}
enum LogError {}
#[derive(Debug, Error)]
enum CreateSeatError {
}
enum CreateSeatError {}
#[derive(Debug, Error)]
enum ParseKeymapError {
@ -351,14 +387,10 @@ enum AddShortcutError {
efrom!(AddShortcutError, CphError);
#[derive(Debug, Error)]
enum GetInputDevicesError {
}
enum GetInputDevicesError {}
#[derive(Debug, Error)]
enum GetSeatsError {
}
enum GetSeatsError {}
#[derive(Debug, Error)]
enum SeatSetKeymapError {
@ -405,3 +437,9 @@ enum GetSplitError {
CphError(#[from] Box<CphError>),
}
efrom!(GetSplitError, CphError);
#[derive(Debug, Error)]
enum RunError {
#[error("The ol' forker is not available")]
NoForker,
}

344
src/forker.rs Normal file
View file

@ -0,0 +1,344 @@
mod clone3;
use crate::async_engine::{AsyncFd, SpawnedFuture};
use crate::forker::clone3::{fork_with_pidfd, Forked};
use crate::utils::buffd::{BufFdIn, BufFdOut};
use crate::utils::copyhashmap::CopyHashMap;
use crate::utils::vec_ext::VecExt;
use crate::{AsyncEngine, AsyncQueue, ErrorFmt, EventLoop, State, Wheel};
use bincode::{Decode, Encode};
use i4config::_private::bincode_ops;
use log::Level;
use parking_lot::Mutex;
use std::cell::Cell;
use std::ffi::OsStr;
use std::io::Read;
use std::io::Write;
use std::os::unix::ffi::OsStrExt;
use std::rc::Rc;
use thiserror::Error;
use uapi::{c, pipe2, IntoUstr, OwnedFd, UstrPtr};
pub struct ForkerProxy {
pidfd: Rc<OwnedFd>,
pid: c::pid_t,
socket: Rc<OwnedFd>,
task_in: Cell<Option<SpawnedFuture<()>>>,
task_out: Cell<Option<SpawnedFuture<()>>>,
task_proc: Cell<Option<SpawnedFuture<()>>>,
outgoing: AsyncQueue<ServerMessage>,
}
#[derive(Debug, Error)]
pub enum ForkerError {
#[error("Could not create a socketpair")]
Socketpair(#[source] std::io::Error),
#[error("Could not fork")]
Fork(#[source] std::io::Error),
}
impl ForkerProxy {
pub fn create() -> Result<Self, ForkerError> {
let (parent, child) = match uapi::socketpair(
c::AF_UNIX,
c::SOCK_STREAM | c::SOCK_CLOEXEC | c::SOCK_NONBLOCK,
0,
) {
Ok(o) => o,
Err(e) => return Err(ForkerError::Socketpair(e.into())),
};
match fork_with_pidfd(false)? {
Forked::Parent { pid, pidfd } => Ok(ForkerProxy {
pidfd: Rc::new(pidfd),
pid,
socket: Rc::new(parent),
task_in: Cell::new(None),
task_out: Cell::new(None),
task_proc: Cell::new(None),
outgoing: Default::default(),
}),
Forked::Child { .. } => Forker::handle(child),
}
}
pub fn install(self: &Rc<Self>, state: &Rc<State>) {
state.forker.set(Some(self.clone()));
let socket = state.eng.fd(&self.socket).unwrap();
self.task_proc.set(Some(
state.eng.spawn(self.clone().check_process(state.clone())),
));
self.task_in
.set(Some(state.eng.spawn(self.clone().incoming(socket.clone()))));
self.task_out.set(Some(
state
.eng
.spawn(self.clone().outgoing(state.clone(), socket.clone())),
));
}
pub fn setenv(&self, key: &[u8], val: &[u8]) {
self.outgoing.push(ServerMessage::SetEnv {
var: key.to_vec(),
val: val.to_vec(),
})
}
pub fn spawn(&self, prog: String, args: Vec<String>, env: Vec<(String, String)>) {
self.outgoing.push(ServerMessage::Spawn {
prog,
args,
env,
})
}
async fn incoming(self: Rc<Self>, socket: AsyncFd) {
let mut buffd = BufFdIn::new(socket);
let mut buf = vec![];
loop {
let mut len = 0usize;
if let Err(e) = buffd.read_full(&mut len).await {
log::error!("Cannot read from the ol' forker: {}", ErrorFmt(e));
self.task_in.take();
return;
}
buf.clear();
buf.reserve(len);
let space = buf.split_at_spare_mut_ext().1;
buffd.read_full(&mut space[..len]).await.unwrap();
unsafe {
buf.set_len(len);
}
let (msg, _) =
bincode::decode_from_slice::<ForkerMessage, _>(&buf, bincode_ops()).unwrap();
self.handle_msg(msg);
}
}
fn handle_msg(&self, msg: ForkerMessage) {
match msg {
ForkerMessage::Log { level, msg } => self.handle_log(level, &msg),
}
}
fn handle_log(&self, level: usize, msg: &str) {
let level = match level {
1 => Level::Error,
2 => Level::Warn,
3 => Level::Info,
4 => Level::Debug,
5 => Level::Trace,
_ => Level::Error,
};
log::log!(level, "{}", msg);
}
async fn outgoing(self: Rc<Self>, state: Rc<State>, socket: AsyncFd) {
let mut buffd = BufFdOut::new(socket);
let mut buf = vec![];
let mut fds = vec![];
loop {
let msg = self.outgoing.pop().await;
buf.clear();
buf.extend_from_slice(uapi::as_bytes(&0usize));
let len = bincode::encode_into_std_write(&msg, &mut buf, bincode_ops()).unwrap();
let _ = (&mut buf[..]).write_all(uapi::as_bytes(&len));
if let Err(e) = buffd.flush2(&buf, &mut fds).await {
log::error!("Could not write to the ol' forker: {}", ErrorFmt(e));
state.forker.set(None);
self.task_out.take();
return;
}
}
}
async fn check_process(self: Rc<Self>, state: Rc<State>) {
let pidfd = state.eng.fd(&self.pidfd).unwrap();
let _ = pidfd.readable().await;
let _ = uapi::waitpid(self.pid, 0);
log::error!("The ol' forker died. Cannot spawn further processes.");
state.forker.set(None);
self.task_out.take();
self.task_proc.take();
}
}
#[derive(Encode, Decode)]
enum ServerMessage {
SetEnv { var: Vec<u8>, val: Vec<u8> },
Spawn { prog: String, args: Vec<String>, env: Vec<(String, String)> },
}
#[derive(Encode, Decode)]
enum ForkerMessage {
Log { level: usize, msg: String },
}
struct Forker {
socket: AsyncFd,
ae: Rc<AsyncEngine>,
outgoing: AsyncQueue<ForkerMessage>,
pending_spawns: CopyHashMap<c::pid_t, SpawnedFuture<()>>,
}
impl Forker {
fn handle(mut socket: OwnedFd) -> ! {
std::env::set_var("XDG_SESSION_TYPE", "wayland");
std::env::remove_var("DISPLAY");
std::env::remove_var("WAYLAND_DISPLAY");
setup_deathsig();
reset_signals();
socket = setup_fds(socket);
std::panic::set_hook({
let socket = Mutex::new(uapi::fcntl_dupfd_cloexec(socket.raw(), 0).unwrap());
Box::new(move |pi| {
let msg = ForkerMessage::Log {
level: log::Level::Error as _,
msg: format!("The ol' forker panicked: {}", pi),
};
let msg = bincode::encode_to_vec(&msg, bincode_ops()).unwrap();
let _ = socket.lock().write_all(&msg);
})
});
let el = EventLoop::new().unwrap();
let wheel = Wheel::install(&el).unwrap();
let ae = AsyncEngine::install(&el, &wheel).unwrap();
let forker = Rc::new(Forker {
socket: ae.fd(&Rc::new(socket)).unwrap(),
ae: ae.clone(),
outgoing: Default::default(),
pending_spawns: Default::default(),
});
let _f1 = ae.spawn(forker.clone().incoming());
let _f2 = ae.spawn(forker.clone().outgoing());
let _ = el.run();
unreachable!();
}
async fn outgoing(self: Rc<Self>) {
let mut buffd = BufFdOut::new(self.socket.clone());
let mut buf = vec![];
let mut fds = vec![];
loop {
let msg = self.outgoing.pop().await;
buf.clear();
buf.extend_from_slice(uapi::as_bytes(&0usize));
let len = bincode::encode_into_std_write(&msg, &mut buf, bincode_ops()).unwrap();
let _ = (&mut buf[..]).write_all(uapi::as_bytes(&len));
buffd.flush2(&buf, &mut fds).await.unwrap();
}
}
async fn incoming(self: Rc<Self>) {
let mut buffd = BufFdIn::new(self.socket.clone());
let mut buf = vec![];
loop {
let mut len = 0usize;
buffd.read_full(&mut len).await.unwrap();
buf.clear();
buf.reserve(len);
let space = buf.split_at_spare_mut_ext().1;
buffd.read_full(&mut space[..len]).await.unwrap();
unsafe {
buf.set_len(len);
}
let (msg, _) =
bincode::decode_from_slice::<ServerMessage, _>(&buf, bincode_ops()).unwrap();
self.handle_msg(msg);
}
}
fn handle_msg(self: &Rc<Self>, msg: ServerMessage) {
match msg {
ServerMessage::SetEnv { var, val } => self.handle_set_env(&var, &val),
ServerMessage::Spawn { prog, args, env } => self.handle_spawn(prog, args, env),
}
}
fn handle_set_env(self: &Rc<Self>, var: &[u8], val: &[u8]) {
std::env::set_var(OsStr::from_bytes(var), OsStr::from_bytes(val));
}
fn handle_spawn(self: &Rc<Self>, prog: String, args: Vec<String>, env: Vec<(String, String)>) {
let (mut read, mut write) = pipe2(c::O_CLOEXEC).unwrap();
let res = match fork_with_pidfd(false) {
Ok(o) => o,
Err(e) => {
self.outgoing.push(ForkerMessage::Log {
level: log::Level::Error as usize,
msg: ErrorFmt(e).to_string(),
});
return;
}
};
match res {
Forked::Parent { pidfd, pid } => {
drop(write);
let slf = self.clone();
let spawn = self.ae.spawn(async move {
let pidfd = slf.ae.fd(&Rc::new(pidfd)).unwrap();
let _ = pidfd.readable().await;
let mut s = String::new();
let _ = read.read_to_string(&mut s);
if s.len() > 0 {
slf.outgoing.push(ForkerMessage::Log {
level: log::Level::Error as _,
msg: format!("Could not spawn `{}`: {}", prog, s),
});
}
slf.pending_spawns.remove(&pid);
});
self.pending_spawns.set(pid, spawn);
}
Forked::Child { .. } => {
unsafe {
c::signal(c::SIGCHLD, c::SIG_DFL);
}
for (key, val) in env {
std::env::set_var(&key, &val);
}
let prog = prog.into_ustr();
let mut argsnt = UstrPtr::new();
argsnt.push(&prog);
for arg in args {
argsnt.push(arg);
}
if let Err(e) = uapi::execvp(&prog, &argsnt) {
let _ = write.write_all(std::io::Error::from(e).to_string().as_bytes());
}
std::process::exit(1);
}
}
}
}
fn setup_fds(mut socket: OwnedFd) -> OwnedFd {
if socket.raw() != 0 {
uapi::dup3(socket.unwrap(), 0, 0).unwrap();
socket = OwnedFd::new(0);
}
uapi::close_range(1, c::c_uint::MAX, 0).unwrap();
uapi::dup3(socket.raw(), 3, c::O_CLOEXEC).unwrap();
socket = OwnedFd::new(3);
let fd = uapi::open("/dev/null", c::O_RDWR, 0).unwrap().unwrap();
assert!(fd == 0);
uapi::dup2(0, 1).unwrap();
uapi::dup2(0, 2).unwrap();
socket
}
fn reset_signals() {
const NSIG: c::c_int = 64;
unsafe {
for sig in 1..=NSIG {
c::signal(sig, c::SIG_DFL);
}
c::signal(c::SIGCHLD, c::SIG_IGN);
}
}
fn setup_deathsig() {
unsafe {
let res = c::prctl(c::PR_SET_PDEATHSIG, c::SIGKILL as c::c_ulong);
uapi::map_err!(res).unwrap();
}
}

56
src/forker/clone3.rs Normal file
View file

@ -0,0 +1,56 @@
use crate::forker::ForkerError;
use std::mem;
use uapi::{c, OwnedFd};
#[derive(Default, Copy, Clone)]
#[allow(non_camel_case_types, dead_code)]
struct clone_args {
flags: u64,
pidfd: u64,
child_tid: u64,
parent_tid: u64,
exit_signal: u64,
stack: u64,
stack_size: u64,
tls: u64,
set_tid: u64,
set_tid_size: u64,
cgroup: u64,
}
pub enum Forked {
Parent { pid: c::pid_t, pidfd: OwnedFd },
Child { pidfd: Option<OwnedFd> },
}
pub fn fork_with_pidfd(pidfd_for_child: bool) -> Result<Forked, ForkerError> {
let mut pidfd: c::c_int = 0;
let mut args = clone_args {
flags: c::CLONE_PIDFD as u64,
pidfd: (&mut pidfd as *mut c::c_int) as _,
..Default::default()
};
let mut child_pidfd = None;
if pidfd_for_child {
child_pidfd = Some(uapi::pidfd_open(uapi::getpid(), 0).unwrap());
}
unsafe {
let pid = c::syscall(
c::SYS_clone3,
&mut args as *const _ as usize,
mem::size_of::<clone_args>(),
);
if let Err(e) = uapi::map_err!(pid) {
return Err(ForkerError::Fork(e.into()));
}
let res = if pid == 0 {
Forked::Child { pidfd: child_pidfd }
} else {
Forked::Parent {
pid: pid as _,
pidfd: OwnedFd::new(pidfd),
}
};
Ok(res)
}
}

View file

@ -4,6 +4,7 @@ pub mod wl_keyboard;
pub mod wl_pointer;
pub mod wl_touch;
use crate::async_engine::SpawnedFuture;
use crate::client::{Client, ClientError, ClientId};
use crate::cursor::{Cursor, KnownCursor};
use crate::fixed::Fixed;
@ -38,6 +39,7 @@ use crate::{ErrorFmt, NumCell, State};
use ahash::{AHashMap, AHashSet};
pub use event_handling::NodeSeatState;
use i4config::keyboard::mods::Modifiers;
use i4config::Direction;
use std::cell::{Cell, RefCell};
use std::collections::hash_map::Entry;
use std::mem;
@ -45,8 +47,6 @@ use std::ops::DerefMut;
use std::rc::Rc;
use thiserror::Error;
use uapi::{c, Errno, OwnedFd};
use i4config::{ Direction};
use crate::async_engine::SpawnedFuture;
const POINTER: u32 = 1;
const KEYBOARD: u32 = 2;
@ -119,11 +119,7 @@ pub struct WlSeatGlobal {
}
impl WlSeatGlobal {
pub fn new(
name: GlobalName,
seat_name: &str,
state: &Rc<State>,
) -> Rc<Self> {
pub fn new(name: GlobalName, seat_name: &str, state: &Rc<State>) -> Rc<Self> {
let slf = Rc::new(Self {
id: state.seat_ids.next(),
name,
@ -167,7 +163,8 @@ impl WlSeatGlobal {
}
pub fn mark_last_active(self: &Rc<Self>) {
self.queue_link.set(Some(self.state.seat_queue.add_last(self.clone())));
self.queue_link
.set(Some(self.state.seat_queue.add_last(self.clone())));
}
pub fn set_keymap(&self, keymap: &Rc<XkbKeymap>) {
@ -464,7 +461,11 @@ impl WlSeat {
self.client.add_client_obj(&p)?;
self.keyboards.set(req.id, p.clone());
let keymap = self.global.kb_map.get();
p.send_keymap(wl_keyboard::XKB_V1, self.keymap_fd(&keymap)?, keymap.map_len as _);
p.send_keymap(
wl_keyboard::XKB_V1,
self.keymap_fd(&keymap)?,
keymap.map_len as _,
);
if self.version >= REPEAT_INFO_SINCE {
let (rate, delay) = self.global.repeat_rate.get();
p.send_repeat_info(rate, delay);
@ -484,12 +485,7 @@ impl WlSeat {
let mut pos = 0;
while pos < target {
let rem = target - pos;
let res = uapi::sendfile(
fd.raw(),
keymap.map.raw(),
Some(&mut pos),
rem as usize,
);
let res = uapi::sendfile(fd.raw(), keymap.map.raw(), Some(&mut pos), rem as usize);
match res {
Ok(_) | Err(Errno(c::EINTR)) => {}
Err(e) => return Err(WlKeyboardError::KeymapCopy(e.into())),

View file

@ -1,4 +1,4 @@
use crate::backend::{KeyboardEvent, KeyState, MouseEvent, OutputId, ScrollAxis};
use crate::backend::{KeyState, KeyboardEvent, MouseEvent, OutputId, ScrollAxis};
use crate::client::{Client, ClientId};
use crate::fixed::Fixed;
use crate::ifs::ipc;
@ -6,7 +6,7 @@ use crate::ifs::ipc::wl_data_device::WlDataDevice;
use crate::ifs::ipc::zwp_primary_selection_device_v1::ZwpPrimarySelectionDeviceV1;
use crate::ifs::wl_seat::wl_keyboard::WlKeyboard;
use crate::ifs::wl_seat::wl_pointer::{WlPointer, POINTER_FRAME_SINCE_VERSION};
use crate::ifs::wl_seat::{wl_keyboard, wl_pointer, Dnd, WlSeat, WlSeatGlobal, SeatId};
use crate::ifs::wl_seat::{wl_keyboard, wl_pointer, Dnd, SeatId, WlSeat, WlSeatGlobal};
use crate::ifs::wl_surface::xdg_surface::xdg_popup::XdgPopup;
use crate::ifs::wl_surface::xdg_surface::xdg_toplevel::XdgToplevel;
use crate::ifs::wl_surface::xdg_surface::XdgSurface;

View file

@ -8,7 +8,7 @@ use crate::wire::wl_keyboard::*;
use crate::wire::{WlKeyboardId, WlSurfaceId};
use std::rc::Rc;
use thiserror::Error;
use uapi::{OwnedFd};
use uapi::OwnedFd;
pub const REPEAT_INFO_SINCE: u32 = 4;

View file

@ -2,6 +2,7 @@ pub mod cursor;
pub mod wl_subsurface;
pub mod xdg_surface;
use crate::backend::{KeyState, ScrollAxis};
use crate::client::{Client, ClientError, RequestParser};
use crate::fixed::Fixed;
use crate::ifs::wl_buffer::WlBuffer;
@ -25,14 +26,13 @@ use crate::wire::{WlOutputId, WlSurfaceId};
use crate::xkbcommon::ModifierState;
use crate::NumCell;
use ahash::AHashMap;
use i4config::Direction;
use std::cell::{Cell, RefCell};
use std::fmt::{Debug, Formatter};
use std::mem;
use std::ops::{Deref, DerefMut};
use std::rc::Rc;
use thiserror::Error;
use i4config::{ Direction};
use crate::backend::{KeyState, ScrollAxis};
#[allow(dead_code)]
const INVALID_SCALE: u32 = 0;

View file

@ -21,11 +21,11 @@ use crate::utils::smallmap::SmallMap;
use crate::wire::xdg_surface::*;
use crate::wire::{WlSurfaceId, XdgPopupId, XdgSurfaceId};
use crate::NumCell;
use i4config::Direction;
use std::cell::Cell;
use std::fmt::Debug;
use std::rc::Rc;
use thiserror::Error;
use i4config::{Direction};
#[allow(dead_code)]
const NOT_CONSTRUCTED: u32 = 1;

View file

@ -19,6 +19,7 @@ use crate::wire::xdg_toplevel::*;
use crate::wire::XdgToplevelId;
use crate::{bugs, NumCell};
use ahash::{AHashMap, AHashSet};
use i4config::Direction;
use num_derive::FromPrimitive;
use std::cell::{Cell, RefCell};
use std::fmt::{Debug, Formatter};
@ -26,7 +27,6 @@ use std::mem;
use std::ops::Deref;
use std::rc::Rc;
use thiserror::Error;
use i4config::{Direction};
#[derive(Copy, Clone, Debug, FromPrimitive)]
pub enum ResizeEdge {

View file

@ -13,6 +13,7 @@ use crate::backends::xorg::{XorgBackend, XorgBackendError};
use crate::client::Clients;
use crate::clientmem::ClientMemError;
use crate::event_loop::EventLoopError;
use crate::forker::ForkerError;
use crate::globals::Globals;
use crate::ifs::wl_compositor::WlCompositorGlobal;
use crate::ifs::wl_shm::WlShmGlobal;
@ -29,6 +30,7 @@ use crate::utils::errorfmt::ErrorFmt;
use crate::utils::numcell::NumCell;
use crate::utils::queue::AsyncQueue;
use crate::wheel::WheelError;
use crate::xkbcommon::XkbContext;
use acceptor::Acceptor;
use async_engine::AsyncEngine;
use event_loop::EventLoop;
@ -38,7 +40,6 @@ use std::ops::Deref;
use std::rc::Rc;
use thiserror::Error;
use wheel::Wheel;
use crate::xkbcommon::XkbContext;
#[macro_use]
mod macros;
@ -56,6 +57,7 @@ mod cursor;
mod drm;
mod event_loop;
mod fixed;
mod forker;
mod format;
mod globals;
mod ifs;
@ -104,9 +106,12 @@ enum MainError {
XorgBackendError(#[from] XorgBackendError),
#[error("The render backend caused an error")]
RenderError(#[from] RenderError),
#[error("The ol' forker caused an error")]
ForkerError(#[from] ForkerError),
}
fn main_() -> Result<(), MainError> {
let forker = Rc::new(forker::ForkerProxy::create()?);
leaks::init();
render::init()?;
clientmem::init()?;
@ -119,6 +124,7 @@ fn main_() -> Result<(), MainError> {
let node_ids = NodeIds::default();
let state = Rc::new(State {
xkb_ctx,
forker: Default::default(),
default_keymap: xkb_keymap,
eng: engine.clone(),
el: el.clone(),
@ -145,11 +151,13 @@ fn main_() -> Result<(), MainError> {
mouse_ids: Default::default(),
kb_handlers: Default::default(),
});
forker.install(&state);
let config = config::ConfigProxy::default(&state);
state.config.set(Some(Rc::new(config)));
let _global_event_handler = engine.spawn(tasks::handle_backend_events(state.clone()));
let _slow_client_handler = engine.spawn(tasks::handle_slow_clients(state.clone()));
Acceptor::install(&state)?;
let socket_path = Acceptor::install(&state)?;
forker.setenv(b"WAYLAND_DISPLAY", socket_path.as_bytes());
let _backend = XorgBackend::new(&state)?;
el.run()?;
state.clients.clear();

View file

@ -1,9 +1,12 @@
use crate::async_engine::{AsyncEngine, SpawnedFuture};
use crate::backend::{BackendEvent, KeyboardId, KeyboardIds, MouseId, MouseIds, OutputId, OutputIds};
use crate::backend::{
BackendEvent, KeyboardId, KeyboardIds, MouseId, MouseIds, OutputId, OutputIds,
};
use crate::client::{Client, Clients};
use crate::config::ConfigProxy;
use crate::cursor::ServerCursors;
use crate::event_loop::EventLoop;
use crate::forker::ForkerProxy;
use crate::globals::{Globals, GlobalsError, WaylandGlobal};
use crate::ifs::wl_output::WlOutputGlobal;
use crate::ifs::wl_seat::{SeatIds, WlSeatGlobal};
@ -15,14 +18,15 @@ use crate::utils::copyhashmap::CopyHashMap;
use crate::utils::linkedlist::LinkedList;
use crate::utils::numcell::NumCell;
use crate::utils::queue::AsyncQueue;
use crate::xkbcommon::XkbKeymap;
use crate::{ErrorFmt, Wheel, XkbContext};
use ahash::AHashMap;
use std::cell::{Cell, RefCell};
use std::rc::Rc;
use crate::xkbcommon::XkbKeymap;
pub struct State {
pub xkb_ctx: XkbContext,
pub forker: CloneCell<Option<Rc<ForkerProxy>>>,
pub default_keymap: Rc<XkbKeymap>,
pub eng: Rc<AsyncEngine>,
pub el: Rc<EventLoop>,
@ -53,13 +57,13 @@ pub struct State {
pub struct MouseData {
pub handler: SpawnedFuture<()>,
pub id: MouseId,
pub data: Rc<DeviceHandlerData>
pub data: Rc<DeviceHandlerData>,
}
pub struct KeyboardData {
pub handler: SpawnedFuture<()>,
pub id: KeyboardId,
pub data: Rc<DeviceHandlerData>
pub data: Rc<DeviceHandlerData>,
}
pub struct DeviceHandlerData {

View file

@ -1,8 +1,8 @@
use crate::backend::{BackendEvent, Output};
use crate::tasks::device;
use crate::tasks::output::OutputHandler;
use crate::State;
use std::rc::Rc;
use crate::tasks::device;
pub struct BackendEventHandler {
pub state: Rc<State>,

View file

@ -1,11 +1,11 @@
use crate::async_engine::SpawnedFuture;
use crate::backend::{Keyboard, KeyboardEvent, Mouse, MouseEvent};
use crate::config::ConfigProxy;
use crate::ifs::wl_seat::WlSeatGlobal;
use crate::state::{DeviceHandlerData, KeyboardData, MouseData};
use crate::utils::asyncevent::AsyncEvent;
use crate::State;
use std::rc::Rc;
use crate::async_engine::SpawnedFuture;
use crate::config::ConfigProxy;
use crate::state::{DeviceHandlerData, KeyboardData, MouseData};
pub trait DeviceApi: 'static {
type Event;
@ -40,11 +40,14 @@ impl DeviceApi for dyn Keyboard {
}
fn add(&self, state: &State, handler: SpawnedFuture<()>, data: Rc<DeviceHandlerData>) {
state.kb_handlers.borrow_mut().insert(self.id(), KeyboardData {
handler,
id: self.id(),
data,
});
state.kb_handlers.borrow_mut().insert(
self.id(),
KeyboardData {
handler,
id: self.id(),
data,
},
);
}
fn remove(&self, state: &State) {
@ -80,11 +83,14 @@ impl DeviceApi for dyn Mouse {
}
fn add(&self, state: &State, handler: SpawnedFuture<()>, data: Rc<DeviceHandlerData>) {
state.mouse_handlers.borrow_mut().insert(self.id(), MouseData {
handler,
id: self.id(),
data,
});
state.mouse_handlers.borrow_mut().insert(
self.id(),
MouseData {
handler,
id: self.id(),
data,
},
);
}
fn remove(&self, state: &State) {

View file

@ -1,7 +1,7 @@
mod backend;
mod device;
mod output;
mod slow_clients;
mod device;
use crate::tasks::backend::BackendEventHandler;
use crate::tasks::slow_clients::SlowClientHandler;

View file

@ -1,7 +1,7 @@
use crate::backend::{KeyState};
use crate::backend::KeyState;
use crate::cursor::KnownCursor;
use crate::fixed::Fixed;
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal, BTN_LEFT, SeatId};
use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT};
use crate::rect::Rect;
use crate::render::Renderer;
use crate::tree::{FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode};
@ -9,12 +9,12 @@ use crate::utils::clonecell::CloneCell;
use crate::utils::linkedlist::{LinkedList, LinkedNode, NodeRef};
use crate::{NumCell, State};
use ahash::AHashMap;
use i4config::{Axis, Direction};
use std::cell::{Cell, RefCell};
use std::fmt::{Debug, Formatter};
use std::mem;
use std::ops::DerefMut;
use std::rc::Rc;
use i4config::{Axis, Direction};
#[allow(dead_code)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
@ -462,7 +462,12 @@ impl Node for ContainerNode {
}
}
fn move_focus_from_child(&self, seat: &Rc<WlSeatGlobal>, child: &dyn Node, direction: Direction) {
fn move_focus_from_child(
&self,
seat: &Rc<WlSeatGlobal>,
child: &dyn Node,
direction: Direction,
) {
let children = self.child_nodes.borrow_mut();
let child = match children.get(&child.id()) {
Some(c) => c,
@ -473,7 +478,9 @@ impl Node for ContainerNode {
ContainerSplit::Vertical => matches!(direction, Direction::Up | Direction::Down),
};
if !in_line {
self.parent.get().move_focus_from_child(seat, self, direction);
self.parent
.get()
.move_focus_from_child(seat, self, direction);
return;
}
let prev = match direction {
@ -484,12 +491,14 @@ impl Node for ContainerNode {
};
let sibling = match prev {
true => child.prev(),
false => child.next()
false => child.next(),
};
let sibling = match sibling {
Some(s) => s,
None => {
self.parent.get().move_focus_from_child(seat, self, direction);
self.parent
.get()
.move_focus_from_child(seat, self, direction);
return;
}
};

View file

@ -13,11 +13,11 @@ use crate::utils::linkedlist::{LinkedList, LinkedNode};
use crate::xkbcommon::ModifierState;
use crate::NumCell;
pub use container::*;
use i4config::Direction;
use std::cell::{Cell, RefCell};
use std::fmt::{Debug, Display, Formatter};
use std::ops::Deref;
use std::rc::Rc;
use i4config::{Direction};
pub use workspace::*;
mod container;
@ -93,7 +93,12 @@ pub trait Node {
let _ = direction;
}
fn move_focus_from_child(&self, seat: &Rc<WlSeatGlobal>, child: &dyn Node, direction: Direction) {
fn move_focus_from_child(
&self,
seat: &Rc<WlSeatGlobal>,
child: &dyn Node,
direction: Direction,
) {
let _ = seat;
let _ = direction;
let _ = child;

View file

@ -94,7 +94,6 @@ impl BufFdOut {
) -> Result<(), BufFdError> {
while buf.read_pos < buf.write_pos {
if self.flush_sync(buf)? {
self.fd.writable().await?;
if timeout.is_none() {
*timeout = Some(self.fd.eng().timeout(5000)?.fuse());
}
@ -157,6 +156,60 @@ impl BufFdOut {
}
Ok(false)
}
pub async fn flush2(&mut self, buf: &[u8], fds: &mut Vec<OwnedFd>) -> Result<(), BufFdError> {
let mut read_pos = 0;
while read_pos < buf.len() {
if self.flush_sync2(&mut read_pos, buf, fds)? {
self.fd.writable().await?;
}
}
Ok(())
}
fn flush_sync2(
&mut self,
read_pos: &mut usize,
buf: &[u8],
fds: &mut Vec<OwnedFd>,
) -> Result<bool, BufFdError> {
let mut cmsg_len = 0;
let mut fds_opt = None;
if fds.len() > 0 {
self.fd_ids.clear();
self.fd_ids.extend(fds.iter().map(|f| f.raw()));
let hdr = c::cmsghdr {
cmsg_len: 0,
cmsg_level: c::SOL_SOCKET,
cmsg_type: c::SCM_RIGHTS,
};
let mut cmsg_buf = &mut self.cmsg_buf[..];
cmsg_len = uapi::cmsg_write(&mut cmsg_buf, hdr, &self.fd_ids[..]).unwrap();
fds_opt = Some(fds);
}
while *read_pos < buf.len() {
let buf = &buf[*read_pos..];
let hdr = uapi::Msghdr {
iov: slice::from_ref(&buf),
control: Some(&self.cmsg_buf[..cmsg_len]),
name: uapi::sockaddr_none_ref(),
};
let bytes_sent =
match uapi::sendmsg(self.fd.raw(), &hdr, c::MSG_DONTWAIT | c::MSG_NOSIGNAL) {
Ok(b) => {
if let Some(fds) = fds_opt.take() {
fds.clear();
}
b
}
Err(Errno(c::EAGAIN)) => return Ok(true),
Err(Errno(c::ECONNRESET)) => return Err(BufFdError::Closed),
Err(e) => return Err(BufFdError::Io(e.into())),
};
*read_pos += bytes_sent;
}
Ok(false)
}
}
impl Drop for OutBuffer {

View file

@ -15,7 +15,7 @@ impl<K, V> Default for CopyHashMap<K, V> {
}
}
impl<K: Eq + Hash, V: Clone> CopyHashMap<K, V> {
impl<K: Eq + Hash, V> CopyHashMap<K, V> {
pub fn new() -> Self {
Self::default()
}
@ -24,7 +24,10 @@ impl<K: Eq + Hash, V: Clone> CopyHashMap<K, V> {
self.map.borrow_mut().insert(k, v);
}
pub fn get(&self, k: &K) -> Option<V> {
pub fn get(&self, k: &K) -> Option<V>
where
V: Clone,
{
self.map.borrow_mut().get(k).cloned()
}

View file

@ -219,7 +219,8 @@ impl<T> NodeRef<T> {
}
fn peer<F>(&self, peer: F) -> Option<NodeRef<T>>
where F: FnOnce(&NodeData<T>) -> &Cell<NonNull<NodeData<T>>>,
where
F: FnOnce(&NodeData<T>) -> &Cell<NonNull<NodeData<T>>>,
{
unsafe {
let data = self.data.as_ref();

View file

@ -10,5 +10,5 @@ pub mod numcell;
pub mod ptr_ext;
pub mod queue;
pub mod smallmap;
pub mod vec_ext;
pub mod stack;
pub mod vec_ext;

View file

@ -10,6 +10,12 @@ pub struct AsyncQueue<T> {
waiters: RefCell<Vec<Waker>>,
}
impl<T> Default for AsyncQueue<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> AsyncQueue<T> {
pub fn new() -> Self {
Self {

View file

@ -1,5 +1,5 @@
use std::cell::UnsafeCell;
use crate::utils::ptr_ext::MutPtrExt;
use std::cell::UnsafeCell;
pub struct Stack<T> {
vec: UnsafeCell<Vec<T>>,
@ -21,8 +21,6 @@ impl<T> Stack<T> {
}
pub fn pop(&self) -> Option<T> {
unsafe {
self.vec.get().deref_mut().pop()
}
unsafe { self.vec.get().deref_mut().pop() }
}
}

View file

@ -124,8 +124,7 @@ impl XkbContext {
}
fn raw_to_map(raw: *mut xkb_keymap) -> Result<Rc<XkbKeymap>, XkbCommonError> {
let res =
unsafe { xkb_keymap_get_as_string(raw, XKB_KEYMAP_FORMAT_TEXT_V1.raw() as _) };
let res = unsafe { xkb_keymap_get_as_string(raw, XKB_KEYMAP_FORMAT_TEXT_V1.raw() as _) };
if res.is_null() {
unsafe {
xkb_keymap_unref(raw);
@ -143,7 +142,8 @@ impl XkbContext {
uapi::fcntl_add_seals(
memfd.raw(),
c::F_SEAL_SEAL | c::F_SEAL_GROW | c::F_SEAL_SHRINK | c::F_SEAL_WRITE,
).unwrap();
)
.unwrap();
Ok(Rc::new(XkbKeymap {
keymap: raw,
map: Rc::new(memfd),
@ -153,7 +153,13 @@ impl XkbContext {
pub fn keymap_from_str(&self, s: &str) -> Result<Rc<XkbKeymap>, XkbCommonError> {
unsafe {
let keymap = xkb_keymap_new_from_buffer(self.context, s.as_bytes().as_ptr(), s.len(), XKB_KEYMAP_FORMAT_TEXT_V1.raw(), 0);
let keymap = xkb_keymap_new_from_buffer(
self.context,
s.as_bytes().as_ptr(),
s.len(),
XKB_KEYMAP_FORMAT_TEXT_V1.raw(),
0,
);
if keymap.is_null() {
return Err(XkbCommonError::KeymapFromBuffer);
}