1use std::{any::Any, sync::Arc};
2
3use wayland_backend::{
4 protocol::ProtocolError,
5 server::{ClientData, ClientId, DisconnectReason, InvalidId, ObjectData},
6};
7
8use crate::{Dispatch, DisplayHandle, Resource, dispatch::ResourceData};
9
10#[derive(Clone, Debug)]
12pub struct Client {
13 pub(crate) id: ClientId,
14 pub(crate) data: Arc<dyn ClientData>,
15}
16
17impl Client {
18 pub(crate) fn from_id(handle: &DisplayHandle, id: ClientId) -> Result<Self, InvalidId> {
19 let data = handle.handle.get_client_data(id.clone())?;
20 Ok(Self { id, data })
21 }
22
23 pub fn id(&self) -> ClientId {
25 self.id.clone()
26 }
27
28 pub fn get_data<Data: ClientData + 'static>(&self) -> Option<&Data> {
32 (&*self.data as &dyn Any).downcast_ref()
33 }
34
35 pub fn get_credentials(
43 &self,
44 handle: &DisplayHandle,
45 ) -> Result<crate::backend::Credentials, InvalidId> {
46 handle.handle.get_client_credentials(self.id.clone())
47 }
48
49 pub fn create_resource<I, U, D>(
55 &self,
56 handle: &DisplayHandle,
57 version: u32,
58 user_data: U,
59 ) -> Result<I, InvalidId>
60 where
61 I: Resource + 'static,
62 U: Dispatch<I, D> + Send + Sync + 'static,
63 D: 'static,
64 {
65 let id = handle.handle.create_object::<D>(
66 self.id.clone(),
67 I::interface(),
68 version,
69 Arc::new(ResourceData::<I, U>::new(user_data)),
70 )?;
71 I::from_id(handle, id)
72 }
73
74 pub fn create_resource_from_objdata<I: Resource + 'static, D: 'static>(
83 &self,
84 handle: &DisplayHandle,
85 version: u32,
86 obj_data: Arc<dyn ObjectData<D>>,
87 ) -> Result<I, InvalidId> {
88 let id =
89 handle.handle.create_object::<D>(self.id.clone(), I::interface(), version, obj_data)?;
90 I::from_id(handle, id)
91 }
92
93 pub fn object_from_protocol_id<I: Resource + 'static>(
98 &self,
99 handle: &DisplayHandle,
100 protocol_id: u32,
101 ) -> Result<I, InvalidId> {
102 let object_id =
103 handle.handle.object_for_protocol_id(self.id.clone(), I::interface(), protocol_id)?;
104 I::from_id(handle, object_id)
105 }
106
107 pub fn kill(&self, handle: &DisplayHandle, error: ProtocolError) {
109 handle.handle.kill_client(self.id.clone(), DisconnectReason::ProtocolError(error))
110 }
111
112 #[cfg(feature = "libwayland_1_22")]
114 pub fn global_name(
115 &self,
116 handle: &DisplayHandle,
117 global: crate::backend::GlobalId,
118 ) -> Option<u32> {
119 handle.handle.global_name(global, self.id.clone())
120 }
121
122 #[cfg(feature = "libwayland_1_23")]
124 pub fn set_max_buffer_size(&self, handle: &DisplayHandle, max_buffer_size: usize) {
125 handle.handle.set_client_max_buffer_size(self.id.clone(), max_buffer_size);
126 }
127}
128
129impl PartialEq for Client {
130 fn eq(&self, other: &Self) -> bool {
131 self.id == other.id
132 }
133}