autocommit 2022-01-08 16:57:40 CET
This commit is contained in:
parent
f8e7557d1d
commit
33549184d4
42 changed files with 2072 additions and 190 deletions
133
src/globals.rs
133
src/globals.rs
|
|
@ -1,20 +1,21 @@
|
|||
use crate::client::{Client, ClientError, DynEventFormatter, WlEvent};
|
||||
use crate::ifs::wl_compositor::WlCompositorError;
|
||||
use crate::ifs::wl_output::WlOutputError;
|
||||
use crate::ifs::wl_output::{WlOutputError, WlOutputGlobal};
|
||||
use crate::ifs::wl_registry::WlRegistry;
|
||||
use crate::ifs::wl_seat::WlSeatError;
|
||||
use crate::ifs::wl_seat::{WlSeatError, WlSeatGlobal};
|
||||
use crate::ifs::wl_shm::WlShmError;
|
||||
use crate::ifs::wl_subcompositor::WlSubcompositorError;
|
||||
use crate::ifs::xdg_wm_base::XdgWmBaseError;
|
||||
use crate::object::{Interface, ObjectId};
|
||||
use crate::utils::copyhashmap::CopyHashMap;
|
||||
use crate::{NumCell, State};
|
||||
use crate::{NumCell, State, WlCompositorGlobal, WlDataDeviceManagerGlobal, WlShmGlobal, WlSubcompositorGlobal, XdgWmBaseGlobal};
|
||||
use ahash::AHashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
use crate::ifs::wl_data_device_manager::WlDataDeviceManagerError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum GlobalError {
|
||||
|
|
@ -34,6 +35,10 @@ pub enum GlobalError {
|
|||
WlOutputError(#[source] Box<WlOutputError>),
|
||||
#[error("An error occurred in a wl_seat")]
|
||||
WlSeatError(#[source] Box<WlSeatError>),
|
||||
#[error("The output with id {0} does not exist")]
|
||||
OutputDoesNotExist(GlobalName),
|
||||
#[error("An error occurred in a wl_data_device_manager")]
|
||||
WlDataDeviceManagerError(#[source] Box<WlDataDeviceManagerError>),
|
||||
}
|
||||
|
||||
efrom!(GlobalError, WlCompositorError, WlCompositorError);
|
||||
|
|
@ -42,6 +47,7 @@ efrom!(GlobalError, WlSubcompositorError, WlSubcompositorError);
|
|||
efrom!(GlobalError, XdgWmBaseError, XdgWmBaseError);
|
||||
efrom!(GlobalError, WlOutputError, WlOutputError);
|
||||
efrom!(GlobalError, WlSeatError, WlSeatError);
|
||||
efrom!(GlobalError, WlDataDeviceManagerError, WlDataDeviceManagerError);
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct GlobalName(u32);
|
||||
|
|
@ -73,6 +79,7 @@ pub trait GlobalBind {
|
|||
|
||||
pub trait Global: GlobalBind {
|
||||
fn name(&self) -> GlobalName;
|
||||
fn singleton(&self) -> bool;
|
||||
fn interface(&self) -> Interface;
|
||||
fn version(&self) -> u32;
|
||||
fn pre_remove(&self);
|
||||
|
|
@ -82,6 +89,7 @@ pub trait Global: GlobalBind {
|
|||
pub struct Globals {
|
||||
next_name: NumCell<u32>,
|
||||
registry: CopyHashMap<GlobalName, Rc<dyn Global>>,
|
||||
outputs: CopyHashMap<GlobalName, Rc<WlOutputGlobal>>,
|
||||
}
|
||||
|
||||
impl Globals {
|
||||
|
|
@ -89,6 +97,7 @@ impl Globals {
|
|||
Self {
|
||||
next_name: NumCell::new(1),
|
||||
registry: CopyHashMap::new(),
|
||||
outputs: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +109,7 @@ impl Globals {
|
|||
GlobalName(id)
|
||||
}
|
||||
|
||||
pub fn insert_no_broadcast<'a>(&'a self, global: Rc<dyn Global>) {
|
||||
fn insert_no_broadcast<'a>(&'a self, global: Rc<dyn Global>) {
|
||||
self.insert_no_broadcast_(&global);
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +117,7 @@ impl Globals {
|
|||
self.registry.set(global.name(), global.clone());
|
||||
}
|
||||
|
||||
pub async fn insert<'a>(&'a self, state: &'a State, global: Rc<dyn Global>) {
|
||||
async fn insert<'a>(&'a self, state: &'a State, global: Rc<dyn Global>) {
|
||||
self.insert_no_broadcast_(&global);
|
||||
self.broadcast(state, |r| r.global(&global)).await;
|
||||
}
|
||||
|
|
@ -117,15 +126,11 @@ impl Globals {
|
|||
self.take(name, false)
|
||||
}
|
||||
|
||||
pub async fn remove(
|
||||
&self,
|
||||
state: &State,
|
||||
name: GlobalName,
|
||||
) -> Result<Rc<dyn Global>, GlobalError> {
|
||||
pub async fn remove(&self, state: &State, name: GlobalName) -> Result<(), GlobalError> {
|
||||
let global = self.take(name, true)?;
|
||||
global.pre_remove();
|
||||
self.broadcast(state, |r| r.global_remove(name)).await;
|
||||
Ok(global)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn notify_all(
|
||||
|
|
@ -134,11 +139,19 @@ impl Globals {
|
|||
registry: &Rc<WlRegistry>,
|
||||
) -> Result<(), GlobalError> {
|
||||
let globals = self.registry.lock();
|
||||
for global in globals.values() {
|
||||
if let Err(e) = client.event(registry.global(global)).await {
|
||||
return Err(GlobalError::SendAllError(Box::new(e)));
|
||||
}
|
||||
macro_rules! emit {
|
||||
($singleton:expr) => {
|
||||
for global in globals.values() {
|
||||
if global.singleton() == $singleton {
|
||||
if let Err(e) = client.event(registry.global(global)).await {
|
||||
return Err(GlobalError::SendAllError(Box::new(e)));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
emit!(true);
|
||||
emit!(false);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -173,4 +186,94 @@ impl Globals {
|
|||
None => Err(GlobalError::GlobalDoesNotExist(name)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_output(&self, output: GlobalName) -> Result<Rc<WlOutputGlobal>, GlobalError> {
|
||||
match self.outputs.get(&output) {
|
||||
Some(o) => Ok(o),
|
||||
_ => Err(GlobalError::OutputDoesNotExist(output)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AddGlobal<T> {
|
||||
type RemoveGlobal<'a>: Future<Output = Result<(), GlobalError>> + 'a;
|
||||
type AddGlobal<'a>: Future<Output = ()> + 'a;
|
||||
|
||||
fn add_global<'a>(&'a self, state: &'a State, global: &'a Rc<T>) -> Self::AddGlobal<'a>;
|
||||
|
||||
fn add_global_no_broadcast(&self, global: &Rc<T>);
|
||||
|
||||
fn remove_global<'a>(&'a self, state: &'a State, global: &'a T) -> Self::RemoveGlobal<'a>;
|
||||
}
|
||||
|
||||
macro_rules! simple_add_global {
|
||||
($ty:ty) => {
|
||||
impl AddGlobal<$ty> for Globals {
|
||||
type RemoveGlobal<'a> = impl Future<Output = Result<(), GlobalError>> + 'a;
|
||||
type AddGlobal<'a> = impl Future<Output = ()> + 'a;
|
||||
|
||||
fn add_global<'a>(
|
||||
&'a self,
|
||||
state: &'a State,
|
||||
global: &'a Rc<$ty>,
|
||||
) -> Self::AddGlobal<'a> {
|
||||
self.insert(state, global.clone())
|
||||
}
|
||||
|
||||
fn add_global_no_broadcast(&self, global: &Rc<$ty>) {
|
||||
self.insert_no_broadcast(global.clone());
|
||||
}
|
||||
|
||||
fn remove_global<'a>(
|
||||
&'a self,
|
||||
state: &'a State,
|
||||
global: &'a $ty,
|
||||
) -> Self::RemoveGlobal<'a> {
|
||||
self.remove(state, global.name())
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
simple_add_global!(WlSeatGlobal);
|
||||
simple_add_global!(WlCompositorGlobal);
|
||||
simple_add_global!(WlShmGlobal);
|
||||
simple_add_global!(WlSubcompositorGlobal);
|
||||
simple_add_global!(XdgWmBaseGlobal);
|
||||
simple_add_global!(WlDataDeviceManagerGlobal);
|
||||
|
||||
macro_rules! dedicated_add_global {
|
||||
($ty:ty, $field:ident) => {
|
||||
impl AddGlobal<$ty> for Globals {
|
||||
type RemoveGlobal<'a> = impl Future<Output = Result<(), GlobalError>> + 'a;
|
||||
type AddGlobal<'a> = impl Future<Output = ()> + 'a;
|
||||
|
||||
fn add_global<'a>(
|
||||
&'a self,
|
||||
state: &'a State,
|
||||
global: &'a Rc<$ty>,
|
||||
) -> Self::AddGlobal<'a> {
|
||||
async move {
|
||||
self.insert(state, global.clone()).await;
|
||||
self.$field.set(global.name(), global.clone());
|
||||
}
|
||||
}
|
||||
|
||||
fn add_global_no_broadcast(&self, global: &Rc<$ty>) {
|
||||
self.insert_no_broadcast(global.clone());
|
||||
self.$field.set(global.name(), global.clone());
|
||||
}
|
||||
|
||||
fn remove_global<'a>(
|
||||
&'a self,
|
||||
state: &'a State,
|
||||
global: &'a $ty,
|
||||
) -> Self::RemoveGlobal<'a> {
|
||||
self.$field.remove(&global.name());
|
||||
self.remove(state, global.name())
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
dedicated_add_global!(WlOutputGlobal, outputs);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue