Skip to main content

wayland_server/
global.rs

1use std::sync::Arc;
2
3use wayland_backend::server::{
4    ClientData, ClientId, GlobalHandler, GlobalId, Handle, ObjectData, ObjectId,
5};
6
7use crate::{Client, DataInit, DisplayHandle, New, Resource};
8
9pub(crate) struct GlobalData<I, U, D> {
10    pub(crate) data: U,
11    pub(crate) _types: std::marker::PhantomData<(I, D)>,
12}
13
14unsafe impl<I, D, U: Send + Sync> Send for GlobalData<I, U, D> {}
15unsafe impl<I, D, U: Send + Sync> Sync for GlobalData<I, U, D> {}
16
17impl<I: Resource + 'static, D: 'static, U: GlobalDispatch<I, D> + Send + Sync + 'static>
18    GlobalHandler<D> for GlobalData<I, U, D>
19{
20    fn can_view(&self, id: &ClientId, data: &Arc<dyn ClientData>, _: &GlobalId) -> bool {
21        let client = Client { id: id.clone(), data: data.clone() };
22        self.data.can_view(&client)
23    }
24
25    fn bind(
26        self: Arc<Self>,
27        handle: &Handle,
28        data: &mut D,
29        client_id: &ClientId,
30        _: &GlobalId,
31        object_id: &ObjectId,
32    ) -> Arc<dyn ObjectData<D>> {
33        let handle = DisplayHandle::from(handle.clone());
34        let client = Client::from_id(&handle, client_id.clone()).expect("Dead client in bind ?!");
35        let resource = <I as Resource>::from_id(&handle, object_id.clone())
36            .expect("Wrong object_id in GlobalHandler ?!");
37
38        let mut new_data = None;
39        let mut protocol_error = None;
40
41        self.data.bind(
42            data,
43            &handle,
44            &client,
45            New::wrap(resource.clone()),
46            &mut DataInit { store: &mut new_data, error: &mut protocol_error },
47        );
48
49        match new_data {
50            Some(data) => data,
51            None => match protocol_error {
52                Some((code, msg)) => {
53                    resource.post_error(code, msg);
54                    Arc::new(ProtocolErrorData)
55                }
56
57                None => panic!(
58                    "Bind callback for interface {} did not init new instance.",
59                    I::interface().name
60                ),
61            },
62        }
63    }
64}
65
66struct ProtocolErrorData;
67
68impl<D> ObjectData<D> for ProtocolErrorData {
69    fn request(
70        self: Arc<Self>,
71        _handle: &Handle,
72        _data: &mut D,
73        _client_id: &ClientId,
74        _msg: wayland_backend::protocol::OwnedMessage<ObjectId>,
75    ) -> Option<Arc<dyn ObjectData<D>>> {
76        None
77    }
78
79    fn destroyed(
80        self: Arc<Self>,
81        _handle: &Handle,
82        _data: &mut D,
83        _client_id: &ClientId,
84        _object_id: &ObjectId,
85    ) {
86    }
87}
88
89/// A trait which provides an implementation for handling advertisement of a global to clients with some type
90/// of associated user data.
91///
92/// Its behavior is similar to the [`Dispatch`][crate::Dispatch] trait.
93pub trait GlobalDispatch<I: Resource, State> {
94    /// Called when a client has bound this global.
95    ///
96    /// The return value of this function should contain user data to associate the object created by the
97    /// client.
98    fn bind(
99        &self,
100        state: &mut State,
101        handle: &DisplayHandle,
102        client: &Client,
103        resource: New<I>,
104        data_init: &mut DataInit<'_, State>,
105    );
106
107    /// Checks if the global should be advertised to some client.
108    ///
109    /// The implementation of this function determines whether a client may see and bind some global. If this
110    /// function returns false, the client will not be told the global exists and attempts to bind the global
111    /// will raise a protocol error.
112    ///
113    /// One use of this function is implementing privileged protocols such as XWayland keyboard grabbing
114    /// which must only be used by XWayland.
115    ///
116    /// The default implementation allows all clients to see the global.
117    fn can_view(&self, _client: &Client) -> bool {
118        true
119    }
120}