1
0
Fork 0
forked from wry/wry

autocommit 2022-01-06 19:08:32 CET

This commit is contained in:
Julian Orth 2022-01-06 19:08:32 +01:00
parent cbbc41a463
commit 4a939477a2
51 changed files with 3438 additions and 207 deletions

View file

@ -1,10 +1,13 @@
use crate::async_engine::{AsyncError, AsyncFd, SpawnedFuture};
use crate::client::objects::Objects;
use crate::ifs::wl_buffer::{WlBuffer, WlBufferError, WlBufferId};
use crate::ifs::wl_callback::WlCallback;
use crate::ifs::wl_compositor::{WlCompositorError, WlCompositorObj};
use crate::ifs::wl_display::{WlDisplay, WlDisplayError};
use crate::ifs::wl_output::{WlOutputError, WlOutputObj};
use crate::ifs::wl_region::{WlRegion, WlRegionError, WlRegionId};
use crate::ifs::wl_registry::{WlRegistry, WlRegistryError, WlRegistryId};
use crate::ifs::wl_seat::{WlSeatError, WlSeatObj};
use crate::ifs::wl_shm::{WlShmError, WlShmObj};
use crate::ifs::wl_shm_pool::{WlShmPool, WlShmPoolError};
use crate::ifs::wl_subcompositor::{WlSubcompositorError, WlSubcompositorObj};
@ -30,7 +33,6 @@ use std::mem;
use std::rc::Rc;
use thiserror::Error;
use uapi::OwnedFd;
use crate::ifs::wl_buffer::{WlBuffer, WlBufferError};
mod objects;
mod tasks;
@ -57,6 +59,8 @@ pub enum ClientError {
ClientDoesNotExist(ClientId),
#[error("There is no wl_region with id {0}")]
RegionDoesNotExist(WlRegionId),
#[error("There is no wl_buffer with id {0}")]
BufferDoesNotExist(WlBufferId),
#[error("There is no wl_surface with id {0}")]
SurfaceDoesNotExist(WlSurfaceId),
#[error("There is no xdg_surface with id {0}")]
@ -105,6 +109,10 @@ pub enum ClientError {
XdgWmBaseError(#[source] Box<XdgWmBaseError>),
#[error("An error occurred in a `wl_buffer`")]
WlBufferError(#[source] Box<WlBufferError>),
#[error("An error occurred in a `wl_output`")]
WlOutputError(#[source] Box<WlOutputError>),
#[error("An error occurred in a `wl_seat`")]
WlSeatError(#[source] Box<WlSeatError>),
#[error("Object {0} is not a display")]
NotADisplay(ObjectId),
}
@ -125,6 +133,8 @@ efrom!(ClientError, XdgWmBaseError, XdgWmBaseError);
efrom!(ClientError, XdgToplevelError, XdgToplevelError);
efrom!(ClientError, XdgPopupError, XdgPopupError);
efrom!(ClientError, WlBufferError, WlBufferError);
efrom!(ClientError, WlOutputError, WlOutputError);
efrom!(ClientError, WlSeatError, WlSeatError);
impl ClientError {
fn peer_closed(&self) -> bool {
@ -146,7 +156,7 @@ impl Display for ClientId {
pub struct Clients {
next_client_id: NumCell<u64>,
clients: RefCell<AHashMap<ClientId, ClientHolder>>,
pub clients: RefCell<AHashMap<ClientId, ClientHolder>>,
shutdown_clients: RefCell<AHashMap<ClientId, ClientHolder>>,
}
@ -186,6 +196,7 @@ impl Clients {
events: AsyncQueue::new(),
shutdown: Cell::new(Some(send)),
shutdown_sent: Cell::new(false),
dispatch_frame_requests: AsyncQueue::new(),
});
let display = Rc::new(WlDisplay::new(&data));
*data.objects.display.borrow_mut() = Some(display.clone());
@ -234,14 +245,16 @@ impl Drop for Clients {
}
}
struct ClientHolder {
data: Rc<Client>,
pub struct ClientHolder {
pub data: Rc<Client>,
_handler: SpawnedFuture<()>,
}
impl Drop for ClientHolder {
fn drop(&mut self) {
self.data.objects.destroy();
self.data.events.clear();
self.data.dispatch_frame_requests.clear();
}
}
@ -256,7 +269,7 @@ pub trait RequestParser<'a>: Debug + Sized {
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError>;
}
enum WlEvent {
pub enum WlEvent {
Flush,
Shutdown,
Event(Box<dyn EventFormatter>),
@ -266,10 +279,11 @@ pub struct Client {
pub id: ClientId,
pub state: Rc<State>,
socket: AsyncFd,
objects: Objects,
pub objects: Objects,
events: AsyncQueue<WlEvent>,
shutdown: Cell<Option<OneshotTx<()>>>,
shutdown_sent: Cell<bool>,
pub dispatch_frame_requests: AsyncQueue<Rc<WlCallback>>,
}
const MAX_PENDING_EVENTS: usize = 100;
@ -342,11 +356,20 @@ impl Client {
self.event2(WlEvent::Event(event)).await
}
pub async fn flush(&self) -> Result<(), ClientError> {
self.event2(WlEvent::Flush).await
}
async fn event2(&self, event: WlEvent) -> Result<(), ClientError> {
self.events.push(event);
self.check_queue_size().await
}
pub fn event2_locked(&self, event: WlEvent) -> bool {
self.events.push(event);
self.events.size() > MAX_PENDING_EVENTS
}
pub async fn check_queue_size(&self) -> Result<(), ClientError> {
if self.events.size() > MAX_PENDING_EVENTS {
self.state.eng.yield_now().await;
@ -359,6 +382,13 @@ impl Client {
Ok(())
}
pub fn get_buffer(&self, id: WlBufferId) -> Result<Rc<WlBuffer>, ClientError> {
match self.objects.buffers.get(&id) {
Some(r) => Ok(r),
_ => Err(ClientError::BufferDoesNotExist(id)),
}
}
pub fn get_region(&self, id: WlRegionId) -> Result<Rc<WlRegion>, ClientError> {
match self.objects.regions.get(&id) {
Some(r) => Ok(r),
@ -453,7 +483,8 @@ simple_add_obj!(WlSubsurface);
simple_add_obj!(XdgPositioner);
simple_add_obj!(XdgToplevel);
simple_add_obj!(XdgPopup);
simple_add_obj!(WlBuffer);
simple_add_obj!(WlOutputObj);
simple_add_obj!(WlSeatObj);
macro_rules! dedicated_add_obj {
($ty:ty, $field:ident) => {
@ -477,3 +508,4 @@ dedicated_add_obj!(WlRegion, regions);
dedicated_add_obj!(WlSurface, surfaces);
dedicated_add_obj!(XdgWmBaseObj, xdg_wm_bases);
dedicated_add_obj!(XdgSurface, xdg_surfaces);
dedicated_add_obj!(WlBuffer, buffers);

View file

@ -1,4 +1,5 @@
use crate::client::{Client, ClientError};
use crate::ifs::wl_buffer::{WlBuffer, WlBufferId};
use crate::ifs::wl_display::WlDisplay;
use crate::ifs::wl_region::{WlRegion, WlRegionId};
use crate::ifs::wl_registry::{WlRegistry, WlRegistryId};
@ -19,6 +20,7 @@ pub struct Objects {
pub surfaces: CopyHashMap<WlSurfaceId, Rc<WlSurface>>,
pub xdg_surfaces: CopyHashMap<XdgSurfaceId, Rc<XdgSurface>>,
pub regions: CopyHashMap<WlRegionId, Rc<WlRegion>>,
pub buffers: CopyHashMap<WlBufferId, Rc<WlBuffer>>,
pub xdg_wm_bases: CopyHashMap<XdgWmBaseId, Rc<XdgWmBaseObj>>,
ids: RefCell<Vec<usize>>,
}
@ -35,6 +37,7 @@ impl Objects {
surfaces: Default::default(),
xdg_surfaces: Default::default(),
regions: Default::default(),
buffers: Default::default(),
xdg_wm_bases: Default::default(),
ids: RefCell::new(vec![]),
}
@ -54,6 +57,7 @@ impl Objects {
self.surfaces.clear();
self.xdg_wm_bases.clear();
self.xdg_surfaces.clear();
self.buffers.clear();
}
fn id<T>(&self, client_data: &Client) -> Result<T, ClientError>
@ -106,9 +110,10 @@ impl Objects {
}
pub async fn remove_obj(&self, client_data: &Client, id: ObjectId) -> Result<(), ClientError> {
if self.registry.remove(&id).is_none() {
return Err(ClientError::UnknownId);
}
let _obj = match self.registry.remove(&id) {
Some(o) => o,
_ => return Err(ClientError::UnknownId),
};
if id.raw() >= MIN_SERVER_ID {
let offset = (id.raw() - MIN_SERVER_ID) as usize;
let pos = offset / SEG_SIZE;

View file

@ -1,4 +1,4 @@
use crate::client::{Client, ClientError, WlEvent};
use crate::client::{AddObj, Client, ClientError, WlEvent};
use crate::object::ObjectId;
use crate::utils::buffd::{BufFdIn, BufFdOut, MsgFormatter, MsgParser};
use crate::utils::oneshot::OneshotRx;
@ -10,12 +10,15 @@ use std::rc::Rc;
pub async fn client(data: Rc<Client>, shutdown: OneshotRx<()>) {
let mut recv = data.state.eng.spawn(receive(data.clone())).fuse();
let mut dispatch_fr = data.state.eng.spawn(dispatch_fr(data.clone())).fuse();
let _send = data.state.eng.spawn(send(data.clone()));
select! {
_ = recv => { },
_ = dispatch_fr => { },
_ = shutdown.fuse() => { },
}
drop(recv);
drop(dispatch_fr);
if !data.shutdown_sent.get() {
data.events.push(WlEvent::Shutdown);
}
@ -25,12 +28,36 @@ pub async fn client(data: Rc<Client>, shutdown: OneshotRx<()>) {
log::error!("Could not shut down client {} within 5 seconds", data.id.0);
}
Err(e) => {
log::error!("Could not create a timeout: {:#}", e);
log::error!("Could not create a timeout: {:#}", anyhow!(e));
}
}
data.state.clients.kill(data.id);
}
async fn dispatch_fr(data: Rc<Client>) {
loop {
let mut fr = data.dispatch_frame_requests.pop().await;
loop {
if let Err(e) = data.event(fr.done()).await {
log::error!("Could not dispatch frame event: {:#}", anyhow!(e));
return;
}
if let Err(e) = data.remove_obj(&*fr).await {
log::error!("Could not remove frame object: {:#}", anyhow!(e));
return;
}
fr = match data.dispatch_frame_requests.try_pop() {
Some(f) => f,
_ => break,
};
}
if let Err(e) = data.event2(WlEvent::Flush).await {
log::error!("Could not dispatch frame event: {:#}", anyhow!(e));
return;
}
}
}
async fn receive(data: Rc<Client>) {
let display = data.display().unwrap();
let recv = async {