1
0
Fork 0
forked from wry/wry

autocommit 2022-03-09 17:51:17 CET

This commit is contained in:
Julian Orth 2022-03-09 17:51:17 +01:00
parent 4df6b559b7
commit 0399772467
35 changed files with 429 additions and 423 deletions

View file

@ -1,5 +1,5 @@
use crate::backend::{BackendEvent, Output};
use crate::tasks::device;
use crate::tasks::input_device;
use crate::tasks::output::OutputHandler;
use crate::State;
use std::rc::Rc;
@ -19,8 +19,7 @@ impl BackendEventHandler {
fn handle_event(&mut self, event: BackendEvent) {
match event {
BackendEvent::NewOutput(output) => self.handle_new_output(output),
BackendEvent::NewMouse(s) => device::handle(&self.state, s),
BackendEvent::NewKeyboard(s) => device::handle(&self.state, s),
BackendEvent::NewInputDevice(s) => input_device::handle(&self.state, s),
}
}

View file

@ -1,174 +0,0 @@
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;
pub trait DeviceApi: 'static {
type Event;
fn on_change(&self, cb: Rc<dyn Fn()>);
fn announce(&self, config: &ConfigProxy);
fn announce_del(&self, config: &ConfigProxy);
fn removed(&self) -> bool;
fn add(self: &Rc<Self>, state: &State, handler: SpawnedFuture<()>, data: Rc<DeviceHandlerData>);
fn remove(&self, state: &State);
fn event(&self) -> Option<Self::Event>;
fn send(seat: &Rc<WlSeatGlobal>, event: Self::Event);
}
impl DeviceApi for dyn Keyboard {
type Event = KeyboardEvent;
fn on_change(&self, cb: Rc<dyn Fn()>) {
self.on_change(cb);
}
fn announce(&self, config: &ConfigProxy) {
config.new_keyboard(self.id());
}
fn announce_del(&self, config: &ConfigProxy) {
config.del_keyboard(self.id());
}
fn removed(&self) -> bool {
self.removed()
}
fn add(
self: &Rc<Self>,
state: &State,
handler: SpawnedFuture<()>,
data: Rc<DeviceHandlerData>,
) {
state.kb_handlers.borrow_mut().insert(
self.id(),
KeyboardData {
handler,
id: self.id(),
kb: self.clone(),
data,
},
);
}
fn remove(&self, state: &State) {
state.kb_handlers.borrow_mut().remove(&self.id());
}
fn event(&self) -> Option<Self::Event> {
self.event()
}
fn send(seat: &Rc<WlSeatGlobal>, event: Self::Event) {
seat.kb_event(event);
}
}
impl DeviceApi for dyn Mouse {
type Event = MouseEvent;
fn on_change(&self, cb: Rc<dyn Fn()>) {
self.on_change(cb);
}
fn announce(&self, config: &ConfigProxy) {
config.new_mouse(self.id());
}
fn announce_del(&self, config: &ConfigProxy) {
config.del_mouse(self.id());
}
fn removed(&self) -> bool {
self.removed()
}
fn add(
self: &Rc<Self>,
state: &State,
handler: SpawnedFuture<()>,
data: Rc<DeviceHandlerData>,
) {
state.mouse_handlers.borrow_mut().insert(
self.id(),
MouseData {
handler,
id: self.id(),
data,
},
);
}
fn remove(&self, state: &State) {
state.mouse_handlers.borrow_mut().remove(&self.id());
}
fn event(&self) -> Option<Self::Event> {
self.event()
}
fn send(seat: &Rc<WlSeatGlobal>, event: Self::Event) {
seat.mouse_event(event);
}
}
pub fn handle<T: DeviceApi + ?Sized>(state: &Rc<State>, dev: Rc<T>) {
let data = Rc::new(DeviceHandlerData {
seat: Default::default(),
});
let oh = DeviceHandler {
state: state.clone(),
dev: dev.clone(),
data: data.clone(),
};
let handler = state.eng.spawn(oh.handle());
dev.add(&state, handler, data);
}
pub struct DeviceHandler<T: DeviceApi + ?Sized> {
pub state: Rc<State>,
pub dev: Rc<T>,
pub data: Rc<DeviceHandlerData>,
}
impl<T: DeviceApi + ?Sized> DeviceHandler<T> {
pub async fn handle(self) {
let ae = Rc::new(AsyncEvent::default());
{
let ae = ae.clone();
self.dev.on_change(Rc::new(move || ae.trigger()));
}
if let Some(config) = self.state.config.get() {
self.dev.announce(&config);
}
loop {
if self.dev.removed() {
break;
}
if let Some(seat) = self.data.seat.get() {
let mut any_events = false;
while let Some(event) = self.dev.event() {
T::send(&seat, event);
any_events = true;
}
if any_events {
seat.mark_last_active();
}
} else {
while self.dev.event().is_some() {
// nothing
}
}
ae.triggered().await;
}
if let Some(config) = self.state.config.get() {
self.dev.announce_del(&config);
}
self.dev.remove(&self.state);
}
}

69
src/tasks/input_device.rs Normal file
View file

@ -0,0 +1,69 @@
use crate::backend::{InputDevice};
use crate::state::{DeviceHandlerData, InputDeviceData};
use crate::utils::asyncevent::AsyncEvent;
use crate::State;
use std::rc::Rc;
pub fn handle(state: &Rc<State>, dev: Rc<dyn InputDevice>) {
let data = Rc::new(DeviceHandlerData {
seat: Default::default(),
});
let oh = DeviceHandler {
state: state.clone(),
dev: dev.clone(),
data: data.clone(),
};
let handler = state.eng.spawn(oh.handle());
state.input_device_handlers.borrow_mut().insert(
dev.id(),
InputDeviceData {
handler,
id: dev.id(),
device: dev.clone(),
data,
},
);
}
pub struct DeviceHandler {
pub state: Rc<State>,
pub dev: Rc<dyn InputDevice>,
pub data: Rc<DeviceHandlerData>,
}
impl DeviceHandler {
pub async fn handle(self) {
let ae = Rc::new(AsyncEvent::default());
{
let ae = ae.clone();
self.dev.on_change(Rc::new(move || ae.trigger()));
}
if let Some(config) = self.state.config.get() {
config.new_input_device(self.dev.id());
}
loop {
if self.dev.removed() {
break;
}
if let Some(seat) = self.data.seat.get() {
let mut any_events = false;
while let Some(event) = self.dev.event() {
seat.event(event);
any_events = true;
}
if any_events {
seat.mark_last_active();
}
} else {
while self.dev.event().is_some() {
// nothing
}
}
ae.triggered().await;
}
if let Some(config) = self.state.config.get() {
config.del_input_device(self.dev.id());
}
self.state.input_device_handlers.borrow_mut().remove(&self.dev.id());
}
}

View file

@ -1,12 +1,14 @@
mod backend;
mod device;
mod input_device;
mod output;
mod slow_clients;
mod start_backend;
use crate::tasks::backend::BackendEventHandler;
use crate::tasks::slow_clients::SlowClientHandler;
use crate::State;
use std::rc::Rc;
pub use start_backend::start_backend;
pub async fn handle_backend_events(state: Rc<State>) {
let mut beh = BackendEventHandler { state };

View file

@ -0,0 +1,17 @@
use std::future::pending;
use std::rc::Rc;
use crate::{ErrorFmt, metal, State, XorgBackend};
pub async fn start_backend(state: Rc<State>) {
log::info!("Trying to start X backend");
let e = match XorgBackend::new(&state) {
Ok(_b) => pending().await,
Err(e) => e,
};
log::warn!("Could not start X backend: {}", ErrorFmt(e));
log::info!("Trying to start metal backend");
let e = metal::run(state.clone()).await;
log::error!("Metal backend failed: {}", ErrorFmt(e));
log::warn!("Shutting down");
state.el.stop();
}