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
89pub trait GlobalDispatch<I: Resource, State> {
94 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 fn can_view(&self, _client: &Client) -> bool {
118 true
119 }
120}