1use std::os::unix::io::OwnedFd;
2use std::sync::Arc;
3
4use wayland_backend::server::{
5 ClientData, ClientId, GlobalHandler, GlobalId, Handle, ObjectData, ObjectId,
6};
7
8use crate::{Client, DataInit, DisplayHandle, New, Resource};
9
10pub(crate) struct GlobalData<I, U, D> {
11 pub(crate) data: U,
12 pub(crate) _types: std::marker::PhantomData<(I, D)>,
13}
14
15unsafe impl<I, D, U: Send + Sync> Send for GlobalData<I, U, D> {}
16unsafe impl<I, D, U: Send + Sync> Sync for GlobalData<I, U, D> {}
17
18impl<I: Resource + 'static, D: 'static, U: GlobalDispatch<I, D> + Send + Sync + 'static>
19 GlobalHandler<D> for GlobalData<I, U, D>
20{
21 fn can_view(&self, id: ClientId, data: &Arc<dyn ClientData>, _: GlobalId) -> bool {
22 let client = Client { id, data: data.clone() };
23 self.data.can_view(&client)
24 }
25
26 fn bind(
27 self: Arc<Self>,
28 handle: &Handle,
29 data: &mut D,
30 client_id: ClientId,
31 _: GlobalId,
32 object_id: ObjectId,
33 ) -> Arc<dyn ObjectData<D>> {
34 let handle = DisplayHandle::from(handle.clone());
35 let client = Client::from_id(&handle, client_id).expect("Dead client in bind ?!");
36 let resource = <I as Resource>::from_id(&handle, object_id)
37 .expect("Wrong object_id in GlobalHandler ?!");
38
39 let mut new_data = None;
40 let mut protocol_error = None;
41
42 self.data.bind(
43 data,
44 &handle,
45 &client,
46 New::wrap(resource.clone()),
47 &mut DataInit { store: &mut new_data, error: &mut protocol_error },
48 );
49
50 match new_data {
51 Some(data) => data,
52 None => match protocol_error {
53 Some((code, msg)) => {
54 resource.post_error(code, msg);
55 Arc::new(ProtocolErrorData)
56 }
57
58 None => panic!(
59 "Bind callback for interface {} did not init new instance.",
60 I::interface().name
61 ),
62 },
63 }
64 }
65}
66
67struct ProtocolErrorData;
68
69impl<D> ObjectData<D> for ProtocolErrorData {
70 fn request(
71 self: Arc<Self>,
72 _handle: &Handle,
73 _data: &mut D,
74 _client_id: ClientId,
75 _msg: wayland_backend::protocol::Message<ObjectId, OwnedFd>,
76 ) -> Option<Arc<dyn ObjectData<D>>> {
77 None
78 }
79
80 fn destroyed(
81 self: Arc<Self>,
82 _handle: &Handle,
83 _data: &mut D,
84 _client_id: ClientId,
85 _object_id: ObjectId,
86 ) {
87 }
88}
89
90pub trait GlobalDispatch<I: Resource, State> {
95 fn bind(
100 &self,
101 state: &mut State,
102 handle: &DisplayHandle,
103 client: &Client,
104 resource: New<I>,
105 data_init: &mut DataInit<'_, State>,
106 );
107
108 fn can_view(&self, _client: &Client) -> bool {
119 true
120 }
121}