Trait wayland_backend::rs::server::GlobalHandler
source · pub trait GlobalHandler<D>: DowncastSync {
fn bind(
self: Arc<Self>,
handle: &Handle,
data: &mut D,
client_id: ClientId,
global_id: GlobalId,
object_id: ObjectId
) -> Arc<dyn ObjectData<D>>;
fn can_view(
&self,
_client_id: ClientId,
_client_data: &Arc<dyn ClientData>,
_global_id: GlobalId
) -> bool { ... }
fn debug(&self, f: &mut Formatter<'_>) -> Result { ... }
}
Expand description
A trait representing the handling of new bound globals
Required Methods§
Provided Methods§
sourcefn can_view(
&self,
_client_id: ClientId,
_client_data: &Arc<dyn ClientData>,
_global_id: GlobalId
) -> bool
fn can_view(
&self,
_client_id: ClientId,
_client_data: &Arc<dyn ClientData>,
_global_id: GlobalId
) -> bool
Check if given client is allowed to interact with given global
If this function returns false, the client will not be notified of the existence of this global, and any attempt to bind it will result in a protocol error as if the global did not exist.
Default implementation always return true.
Examples found in repository?
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
pub(crate) fn check_bind(
&self,
client: &Client<D>,
name: u32,
interface_name: &CStr,
version: u32,
) -> Option<(&'static Interface, InnerGlobalId, Arc<dyn GlobalHandler<D>>)> {
if name == 0 || version == 0 {
return None;
}
let target_global = self.globals.get((name - 1) as usize).and_then(|o| o.as_ref())?;
if target_global.interface.name.as_bytes() != interface_name.to_bytes() {
return None;
}
if target_global.version < version {
return None;
}
if !target_global.handler.can_view(
ClientId { id: client.id.clone() },
&client.data,
GlobalId { id: target_global.id.clone() },
) {
return None;
}
Some((target_global.interface, target_global.id.clone(), target_global.handler.clone()))
}
pub(crate) fn cleanup(&mut self, dead_clients: &[ClientId]) {
self.known_registries
.retain(|obj_id| !dead_clients.iter().any(|cid| cid.id == obj_id.client_id))
}
pub(crate) fn disable_global(&mut self, id: InnerGlobalId, clients: &mut ClientStore<D>) {
let global = match self.globals.get_mut(id.id as usize - 1) {
Some(&mut Some(ref mut g)) if g.id == id => g,
_ => return,
};
// Do nothing if the global is already disabled
if !global.disabled {
global.disabled = true;
// send the global_remove
for registry in self.known_registries.iter().cloned() {
if let Ok(client) = clients.get_client_mut(registry.client_id.clone()) {
let _ =
send_global_remove_to(client, global, ObjectId { id: registry.clone() });
}
}
}
}
pub(crate) fn remove_global(&mut self, id: InnerGlobalId, clients: &mut ClientStore<D>) {
// disable the global if not already disabled
self.disable_global(id.clone(), clients);
// now remove it if the id is still valid
if let Some(place) = self.globals.get_mut(id.id as usize - 1) {
if place.as_ref().map(|g| g.id == id).unwrap_or(false) {
*place = None;
}
}
}
pub(crate) fn new_registry(
&mut self,
registry: InnerObjectId,
client: &mut Client<D>,
) -> Result<(), InvalidId> {
self.send_all_globals_to(registry.clone(), client)?;
self.known_registries.push(registry);
Ok(())
}
pub(crate) fn send_all_globals_to(
&self,
registry: InnerObjectId,
client: &mut Client<D>,
) -> Result<(), InvalidId> {
for global in self.globals.iter().flat_map(|opt| opt.as_ref()) {
if !global.disabled
&& global.handler.can_view(
ClientId { id: client.id.clone() },
&client.data,
GlobalId { id: global.id.clone() },
)
{
// fail the whole send on error, there is no point in trying further on a failing client
send_global_to(client, global, ObjectId { id: registry.clone() })?;
}
}
Ok(())
}
pub(crate) fn send_global_to_all(
&self,
global_id: InnerGlobalId,
clients: &mut ClientStore<D>,
) -> Result<(), InvalidId> {
let global = self.get_global(global_id)?;
if global.disabled {
return Err(InvalidId);
}
for registry in self.known_registries.iter().cloned() {
if let Ok(client) = clients.get_client_mut(registry.client_id.clone()) {
if !global.disabled
&& global.handler.can_view(
ClientId { id: client.id.clone() },
&client.data,
GlobalId { id: global.id.clone() },
)
{
// don't fail the whole send for a single erroring client
let _ = send_global_to(client, global, ObjectId { id: registry.clone() });
}
}
}
Ok(())
}
Implementations§
source§impl<D> dyn GlobalHandler<D>where
D: Any + 'static,
impl<D> dyn GlobalHandler<D>where
D: Any + 'static,
sourcepub fn is<__T: GlobalHandler<D>>(&self) -> bool
pub fn is<__T: GlobalHandler<D>>(&self) -> bool
Returns true if the trait object wraps an object of type __T
.
sourcepub fn downcast<__T: GlobalHandler<D>>(
self: Box<Self>
) -> Result<Box<__T>, Box<Self>>
pub fn downcast<__T: GlobalHandler<D>>(
self: Box<Self>
) -> Result<Box<__T>, Box<Self>>
Returns a boxed object from a boxed trait object if the underlying object is of type
__T
. Returns the original boxed trait if it isn’t.
sourcepub fn downcast_rc<__T: GlobalHandler<D>>(
self: Rc<Self>
) -> Result<Rc<__T>, Rc<Self>>
pub fn downcast_rc<__T: GlobalHandler<D>>(
self: Rc<Self>
) -> Result<Rc<__T>, Rc<Self>>
Returns an Rc
-ed object from an Rc
-ed trait object if the underlying object is of
type __T
. Returns the original Rc
-ed trait if it isn’t.
sourcepub fn downcast_ref<__T: GlobalHandler<D>>(&self) -> Option<&__T>
pub fn downcast_ref<__T: GlobalHandler<D>>(&self) -> Option<&__T>
Returns a reference to the object within the trait object if it is of type __T
, or
None
if it isn’t.
sourcepub fn downcast_mut<__T: GlobalHandler<D>>(&mut self) -> Option<&mut __T>
pub fn downcast_mut<__T: GlobalHandler<D>>(&mut self) -> Option<&mut __T>
Returns a mutable reference to the object within the trait object if it is of type
__T
, or None
if it isn’t.
sourcepub fn downcast_arc<__T>(self: Arc<Self>) -> Result<Arc<__T>, Arc<Self>>where
__T: Any + Send + Sync + GlobalHandler<D>,
pub fn downcast_arc<__T>(self: Arc<Self>) -> Result<Arc<__T>, Arc<Self>>where
__T: Any + Send + Sync + GlobalHandler<D>,
Returns an Arc
-ed object from an Arc
-ed trait object if the underlying object is of
type __T
. Returns the original Arc
-ed trait if it isn’t.