1
0
Fork 0
forked from wry/wry

autocommit 2022-04-10 18:26:13 CEST

This commit is contained in:
Julian Orth 2022-04-10 18:26:13 +02:00
parent af152f7f3e
commit 6b3316e920
26 changed files with 514 additions and 82 deletions

View file

@ -1,7 +1,9 @@
use {
crate::{
backend,
backend::{ConnectorId, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId},
async_engine::{AsyncError, SpawnedFuture, Timer},
backend::{
self, ConnectorId, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId,
},
compositor::MAX_EXTENTS,
ifs::wl_seat::{SeatId, WlSeatGlobal},
state::{ConnectorData, DeviceHandlerData, OutputData, State},
@ -32,8 +34,9 @@ use {
},
libloading::Library,
log::Level,
std::{cell::Cell, rc::Rc},
std::{cell::Cell, rc::Rc, time::Duration},
thiserror::Error,
uapi::c,
};
pub(super) struct ConfigProxyHandler {
@ -47,12 +50,31 @@ pub(super) struct ConfigProxyHandler {
pub next_id: NumCell<u64>,
pub keymaps: CopyHashMap<Keymap, Rc<XkbKeymap>>,
pub bufs: Stack<Vec<u8>>,
pub workspace_ids: NumCell<u64>,
pub workspaces_by_name: CopyHashMap<Rc<String>, u64>,
pub workspaces_by_id: CopyHashMap<u64, Rc<String>>,
pub timer_ids: NumCell<u64>,
pub timers_by_name: CopyHashMap<Rc<String>, Rc<TimerData>>,
pub timers_by_id: CopyHashMap<u64, Rc<TimerData>>,
}
pub(super) struct TimerData {
timer: Timer,
id: u64,
name: Rc<String>,
_handler: SpawnedFuture<()>,
}
impl ConfigProxyHandler {
pub fn do_drop(&self) {
self.dropped.set(true);
self.timers_by_name.clear();
self.timers_by_id.clear();
}
pub fn send(&self, msg: &ServerMessage) {
let mut buf = self.bufs.pop().unwrap_or_default();
buf.clear();
@ -132,6 +154,79 @@ impl ConfigProxyHandler {
Ok(())
}
fn handle_set_status(&self, status: &str) {
self.state.set_status(status);
}
fn get_timer(&self, timer: jay_config::Timer) -> Result<Rc<TimerData>, CphError> {
match self.timers_by_id.get(&timer.0) {
Some(t) => Ok(t),
_ => Err(CphError::TimerDoesNotExist(timer)),
}
}
fn handle_remove_timer(&self, timer: jay_config::Timer) -> Result<(), CphError> {
let timer = self.get_timer(timer)?;
self.timers_by_id.remove(&timer.id);
self.timers_by_name.remove(&timer.name);
Ok(())
}
fn handle_program_timer(
&self,
timer: jay_config::Timer,
initial: Option<Duration>,
periodic: Option<Duration>,
) -> Result<(), CphError> {
let timer = self.get_timer(timer)?;
timer.timer.program(initial, periodic)?;
Ok(())
}
fn handle_get_timer(self: &Rc<Self>, name: &str) -> Result<(), CphError> {
let name = Rc::new(name.to_owned());
if let Some(t) = self.timers_by_name.get(&name) {
self.respond(Response::GetTimer {
timer: jay_config::Timer(t.id),
});
return Ok(());
}
let id = self.timer_ids.fetch_add(1);
let timer = self.state.eng.timer(c::CLOCK_BOOTTIME)?;
let handler = {
let timer = timer.clone();
let slf = self.clone();
self.state.eng.spawn(async move {
loop {
match timer.expired().await {
Ok(_) => slf.send(&ServerMessage::TimerExpired {
timer: jay_config::Timer(id),
}),
Err(e) => {
log::error!("Could not wait for timer expiration: {}", ErrorFmt(e));
if let Some(timer) = slf.timers_by_id.remove(&id) {
slf.timers_by_name.remove(&timer.name);
}
return;
}
}
}
})
};
let td = Rc::new(TimerData {
timer,
id,
name: name.clone(),
_handler: handler,
});
self.timers_by_name.set(name.clone(), td.clone());
self.timers_by_id.set(id, td.clone());
self.respond(Response::GetTimer {
timer: jay_config::Timer(id),
});
Ok(())
}
fn handle_close(&self, seat: Seat) -> Result<(), CphError> {
let seat = self.get_seat(seat)?;
seat.close();
@ -361,6 +456,7 @@ impl ConfigProxyHandler {
return Err(CphError::InvalidConnectorPosition(x, y));
}
let old_pos = connector.node.global.pos.get();
connector.node.set_position(x, y);
let seats = self.state.globals.seats.lock();
for seat in seats.values() {
if seat.get_output().id == connector.node.id {
@ -371,7 +467,6 @@ impl ConfigProxyHandler {
);
}
}
connector.node.set_position(x, y);
Ok(())
}
@ -642,13 +737,13 @@ impl ConfigProxyHandler {
self.state.theme.underline_color.set(color.into());
}
pub fn handle_request(&self, msg: &[u8]) {
pub fn handle_request(self: &Rc<Self>, msg: &[u8]) {
if let Err(e) = self.handle_request_(msg) {
log::error!("Could not handle client request: {}", ErrorFmt(e));
}
}
fn handle_request_(&self, msg: &[u8]) -> Result<(), CphError> {
fn handle_request_(self: &Rc<Self>, msg: &[u8]) -> Result<(), CphError> {
let (request, _) = match bincode::decode_from_slice::<ClientMessage, _>(msg, bincode_ops())
{
Ok(msg) => msg,
@ -770,6 +865,18 @@ impl ConfigProxyHandler {
.handle_connector_set_position(connector, x, y)
.wrn("connector_set_position")?,
ClientMessage::Close { seat } => self.handle_close(seat).wrn("close")?,
ClientMessage::SetStatus { status } => self.handle_set_status(status),
ClientMessage::GetTimer { name } => self.handle_get_timer(name).wrn("get_timer")?,
ClientMessage::RemoveTimer { timer } => {
self.handle_remove_timer(timer).wrn("remove_timer")?
}
ClientMessage::ProgramTimer {
timer,
initial,
periodic,
} => self
.handle_program_timer(timer, initial, periodic)
.wrn("program_timer")?,
}
Ok(())
}
@ -801,6 +908,8 @@ enum CphError {
DeviceDoesNotExist(InputDevice),
#[error("Connector {0:?} does not exist")]
ConnectorDoesNotExist(Connector),
#[error("Timer {0:?} does not exist")]
TimerDoesNotExist(jay_config::Timer),
#[error("Connector {0:?} does not exist or is not connected")]
OutputDoesNotExist(Connector),
#[error("{0}x{1} is not a valid connector position")]
@ -817,6 +926,8 @@ enum CphError {
ParsingFailed(#[source] DecodeError),
#[error("Could not process a `{0}` request")]
FailedRequest(&'static str, #[source] Box<Self>),
#[error(transparent)]
AsyncError(#[from] AsyncError),
}
trait WithRequestName {