1use {
4 crate::{
5 client::Client,
6 endpoint::Endpoint,
7 handler::{HandlerAccessError, HandlerMut, HandlerRef},
8 protocols::ObjectInterface,
9 state::State,
10 },
11 error_reporter::Report,
12 std::{
13 any::Any,
14 cell::{Cell, RefCell},
15 collections::{VecDeque, hash_map::Entry},
16 fmt::Debug,
17 os::fd::OwnedFd,
18 rc::{Rc, Weak},
19 },
20 thiserror::Error,
21};
22
23#[cfg(test)]
24mod tests;
25
26pub(crate) trait ObjectPrivate: Any {
27 fn new(state: &Rc<State>, version: u32) -> Rc<Self>
28 where
29 Self: Sized;
30 fn delete_id(self: Rc<Self>) -> Result<(), (ObjectError, Rc<dyn Object>)>;
31 fn handle_request(
32 self: Rc<Self>,
33 client: &Rc<Client>,
34 msg: &[u32],
35 fds: &mut VecDeque<Rc<OwnedFd>>,
36 ) -> Result<(), ObjectError>;
37 fn handle_event(
38 self: Rc<Self>,
39 server: &Endpoint,
40 msg: &[u32],
41 fds: &mut VecDeque<Rc<OwnedFd>>,
42 ) -> Result<(), ObjectError>;
43 fn get_request_name(&self, id: u32) -> Option<&'static str>;
44 fn get_event_name(&self, id: u32) -> Option<&'static str>;
45}
46
47#[expect(private_bounds)]
51pub trait Object: Debug + ObjectPrivate {
52 fn core(&self) -> &ObjectCore;
54 fn unset_handler(&self);
61 fn get_handler_any_ref(&self) -> Result<HandlerRef<'_, dyn Any>, HandlerAccessError>;
63 fn get_handler_any_mut(&self) -> Result<HandlerMut<'_, dyn Any>, HandlerAccessError>;
65}
66
67pub trait ConcreteObject: Object {
69 const XML_VERSION: u32;
71 const INTERFACE: ObjectInterface;
73 const INTERFACE_NAME: &str;
75}
76
77pub trait ObjectCoreApi {
79 fn state(&self) -> &Rc<State>;
81
82 fn client(&self) -> Option<Rc<Client>>;
84
85 fn create_child<P>(&self) -> Rc<P>
100 where
101 P: Object;
102
103 fn interface(&self) -> ObjectInterface;
105
106 fn version(&self) -> u32;
108
109 fn unique_id(&self) -> u64;
113
114 fn client_id(&self) -> Option<u32>;
116
117 fn server_id(&self) -> Option<u32>;
119
120 fn delete_id(&self);
125
126 fn try_delete_id(&self) -> Result<(), ObjectError>;
131
132 fn set_forward_to_client(&self, enabled: bool);
136
137 fn set_forward_to_server(&self, enabled: bool);
141}
142
143impl ObjectCoreApi for ObjectCore {
144 fn state(&self) -> &Rc<State> {
145 &self.state
146 }
147
148 fn client(&self) -> Option<Rc<Client>> {
149 self.client.borrow().clone()
150 }
151
152 fn create_child<P>(&self) -> Rc<P>
153 where
154 P: Object,
155 {
156 self.state.create_object::<P>(self.version)
157 }
158
159 fn interface(&self) -> ObjectInterface {
160 self.interface
161 }
162
163 fn version(&self) -> u32 {
164 self.version
165 }
166
167 fn unique_id(&self) -> u64 {
168 self.id
169 }
170
171 fn client_id(&self) -> Option<u32> {
172 self.client_obj_id.get()
173 }
174
175 fn server_id(&self) -> Option<u32> {
176 self.server_obj_id.get()
177 }
178
179 fn delete_id(&self) {
180 if let Err(e) = self.try_delete_id() {
181 log::warn!("Could not release a client id: {}", Report::new(e));
182 }
183 }
184
185 fn try_delete_id(&self) -> Result<(), ObjectError> {
186 if !self.awaiting_delete_id.replace(false) {
187 if self.client.borrow().is_some() {
188 return Err(ObjectError(ObjectErrorKind::NotAwaitingDeleteId));
189 }
190 return Ok(());
191 }
192 let Some(id) = self.client_obj_id.take() else {
193 return Ok(());
194 };
195 self.client_id.take();
196 let Some(client) = self.client.take() else {
197 return Ok(());
198 };
199 let object = client.endpoint.objects.borrow_mut().remove(&id);
200 drop(object);
201 client.display.try_send_delete_id(id)
202 }
203
204 fn set_forward_to_client(&self, enabled: bool) {
205 self.forward_to_client.set(enabled);
206 }
207
208 fn set_forward_to_server(&self, enabled: bool) {
209 self.forward_to_server.set(enabled);
210 }
211}
212
213impl<T> ObjectCoreApi for T
214where
215 T: Object + ?Sized,
216{
217 fn state(&self) -> &Rc<State> {
218 self.core().state()
219 }
220
221 fn client(&self) -> Option<Rc<Client>> {
222 self.core().client()
223 }
224
225 fn create_child<P>(&self) -> Rc<P>
226 where
227 P: Object,
228 {
229 self.core().create_child()
230 }
231
232 fn interface(&self) -> ObjectInterface {
233 self.core().interface()
234 }
235
236 fn version(&self) -> u32 {
237 self.core().version()
238 }
239
240 fn unique_id(&self) -> u64 {
241 self.core().unique_id()
242 }
243
244 fn client_id(&self) -> Option<u32> {
245 self.core().client_id()
246 }
247
248 fn server_id(&self) -> Option<u32> {
249 self.core().server_id()
250 }
251
252 fn delete_id(&self) {
253 self.core().delete_id()
254 }
255
256 fn try_delete_id(&self) -> Result<(), ObjectError> {
257 self.core().try_delete_id()
258 }
259
260 fn set_forward_to_client(&self, enabled: bool) {
261 self.core().set_forward_to_client(enabled);
262 }
263
264 fn set_forward_to_server(&self, enabled: bool) {
265 self.core().set_forward_to_server(enabled);
266 }
267}
268
269pub trait ObjectUtils: Object {
271 fn try_get_handler_ref<T>(&self) -> Result<HandlerRef<'_, T>, HandlerAccessError>
273 where
274 T: 'static,
275 {
276 let handler = self.get_handler_any_ref()?;
277 handler
278 .downcast_ref::<T>()
279 .ok_or(HandlerAccessError::InvalidType)?;
280 Ok(HandlerRef::map(handler, |h| unsafe {
282 &*(h as *const dyn Any as *const T)
283 }))
284 }
285
286 fn get_handler_ref<T>(&self) -> HandlerRef<'_, T>
290 where
291 T: 'static,
292 {
293 self.try_get_handler_ref().map_err(Report::new).unwrap()
294 }
295
296 fn try_get_handler_mut<T>(&self) -> Result<HandlerMut<'_, T>, HandlerAccessError>
298 where
299 T: 'static,
300 {
301 let mut handler = self.get_handler_any_mut()?;
302 handler
303 .downcast_mut::<T>()
304 .ok_or(HandlerAccessError::InvalidType)?;
305 Ok(HandlerMut::map(handler, |h| unsafe {
307 &mut *(h as *mut dyn Any as *mut T)
308 }))
309 }
310
311 fn get_handler_mut<T>(&self) -> HandlerMut<'_, T>
315 where
316 T: 'static,
317 {
318 self.try_get_handler_mut().map_err(Report::new).unwrap()
319 }
320}
321
322impl<T> ObjectUtils for T where T: Object + ?Sized {}
323
324pub trait ObjectRcUtils {
326 fn try_downcast<T>(&self) -> Option<Rc<T>>
328 where
329 T: ConcreteObject;
330
331 fn downcast<T>(&self) -> Rc<T>
335 where
336 T: ConcreteObject;
337}
338
339impl ObjectRcUtils for Rc<dyn Object> {
340 fn try_downcast<T>(&self) -> Option<Rc<T>>
341 where
342 T: ConcreteObject,
343 {
344 (self.clone() as Rc<dyn Any>).downcast().ok()
345 }
346
347 fn downcast<T>(&self) -> Rc<T>
348 where
349 T: ConcreteObject,
350 {
351 let Some(t) = self.try_downcast() else {
352 panic!(
353 "Tried to downcast {} to {}",
354 self.interface().name(),
355 T::INTERFACE_NAME,
356 );
357 };
358 t
359 }
360}
361
362pub struct ObjectCore {
366 pub(crate) state: Rc<State>,
367 id: u64,
368 pub(crate) interface: ObjectInterface,
369 pub(crate) version: u32,
370 pub(crate) forward_to_client: Cell<bool>,
371 pub(crate) forward_to_server: Cell<bool>,
372 pub(crate) awaiting_delete_id: Cell<bool>,
373 pub(crate) server_obj_id: Cell<Option<u32>>,
374 pub(crate) client_obj_id: Cell<Option<u32>>,
375 pub(crate) client_id: Cell<Option<u64>>,
376 pub(crate) client: RefCell<Option<Rc<Client>>>,
377}
378
379#[derive(Debug, Error)]
380pub(crate) enum IdError {
381 #[error("the state is already destroyed")]
382 StateDestroyed,
383 #[error("the client is already destroyed")]
384 ClientDestroyed,
385 #[error("object already has the server id {0}")]
386 HasServerId(u32),
387 #[error("the state does not have a server")]
388 NoServer,
389 #[error("there are no server ids available")]
390 NoServerSpace,
391 #[error("the id {0} is too small to be a server id")]
392 NotServerId(u32),
393 #[error("the server id {0} is already in use")]
394 ServerIdInUse(u32),
395 #[error("object already has the client id {0}")]
396 HasClientId(u32),
397 #[error("there are no client ids available")]
398 NoClientSpace,
399 #[error("the id {0} is too large to be a client id")]
400 NotClientId(u32),
401 #[error("the client id {0} is already in use")]
402 ClientIdInUse(u32),
403}
404
405const MIN_SERVER_ID: u32 = 0xff000000;
406
407impl ObjectCore {
408 pub(crate) fn new(
409 state: &Rc<State>,
410 slf: Weak<dyn Object>,
411 interface: ObjectInterface,
412 version: u32,
413 ) -> Self {
414 let object_id = state.next_object_id.get();
415 state.next_object_id.set(object_id + 1);
416 state.all_objects.borrow_mut().insert(object_id, slf);
417 Self {
418 state: state.clone(),
419 id: object_id,
420 interface,
421 version,
422 forward_to_client: Cell::new(state.forward_to_client.get()),
423 forward_to_server: Cell::new(state.forward_to_server.get()),
424 awaiting_delete_id: Default::default(),
425 server_obj_id: Default::default(),
426 client_obj_id: Default::default(),
427 client_id: Default::default(),
428 client: Default::default(),
429 }
430 }
431
432 fn check_server_destroyed(&self) -> Result<(), IdError> {
433 if self.state.destroyed.get() {
434 return Err(IdError::StateDestroyed);
435 }
436 Ok(())
437 }
438
439 pub(crate) fn generate_server_id(&self, slf: Rc<dyn Object>) -> Result<(), IdError> {
440 self.check_server_destroyed()?;
441 if let Some(id) = self.server_obj_id.get() {
442 return Err(IdError::HasServerId(id));
443 }
444 let Some(server) = &self.state.server else {
445 return Err(IdError::NoServer);
446 };
447 let id = server.idl.acquire();
448 if id >= MIN_SERVER_ID {
449 server.idl.release(id);
450 return Err(IdError::NoServerSpace);
451 }
452 self.server_obj_id.set(Some(id));
453 server.objects.borrow_mut().insert(id, slf);
454 Ok(())
455 }
456
457 pub(crate) fn set_server_id(&self, id: u32, slf: Rc<dyn Object>) -> Result<(), IdError> {
458 if id < MIN_SERVER_ID {
459 return Err(IdError::NotServerId(id));
460 }
461 self.set_server_id_unchecked(id, slf)
462 }
463
464 pub(crate) fn set_server_id_unchecked(
465 &self,
466 id: u32,
467 slf: Rc<dyn Object>,
468 ) -> Result<(), IdError> {
469 self.check_server_destroyed()?;
470 let Some(server) = &self.state.server else {
471 return Err(IdError::NoServer);
472 };
473 let objects = &mut *server.objects.borrow_mut();
474 let Entry::Vacant(entry) = objects.entry(id) else {
475 return Err(IdError::ServerIdInUse(id));
476 };
477 entry.insert(slf);
478 self.server_obj_id.set(Some(id));
479 Ok(())
480 }
481
482 fn check_client_destroyed(&self, client: &Client) -> Result<(), IdError> {
483 if client.destroyed.get() {
484 return Err(IdError::ClientDestroyed);
485 }
486 Ok(())
487 }
488
489 pub(crate) fn generate_client_id(
490 &self,
491 client: &Rc<Client>,
492 slf: Rc<dyn Object>,
493 ) -> Result<(), IdError> {
494 self.check_client_destroyed(client)?;
495 if let Some(id) = self.client_obj_id.get() {
496 return Err(IdError::HasClientId(id));
497 }
498 let id = client.endpoint.idl.acquire();
499 let Some(id) = MIN_SERVER_ID.checked_add(id) else {
500 client.endpoint.idl.release(id);
501 return Err(IdError::NoClientSpace);
502 };
503 client.endpoint.objects.borrow_mut().insert(id, slf);
504 self.set_client_id_(client, id);
505 Ok(())
506 }
507
508 pub(crate) fn set_client_id(
509 &self,
510 client: &Rc<Client>,
511 id: u32,
512 slf: Rc<dyn Object>,
513 ) -> Result<(), IdError> {
514 self.check_client_destroyed(client)?;
515 if id >= MIN_SERVER_ID {
516 return Err(IdError::NotClientId(id));
517 }
518 let objects = &mut *client.endpoint.objects.borrow_mut();
519 let Entry::Vacant(entry) = objects.entry(id) else {
520 return Err(IdError::ClientIdInUse(id));
521 };
522 entry.insert(slf);
523 self.set_client_id_(client, id);
524 Ok(())
525 }
526
527 fn set_client_id_(&self, client: &Rc<Client>, id: u32) {
528 self.client_obj_id.set(Some(id));
529 self.client_id.set(Some(client.endpoint.id));
530 *self.client.borrow_mut() = Some(client.clone());
531 }
532
533 pub(crate) fn handle_client_destroy(&self) {
534 let id = self.client_obj_id.get().unwrap();
535 if let Some(idl) = id.checked_sub(MIN_SERVER_ID) {
536 self.client_obj_id.take();
537 self.client_id.take();
538 let client = self.client.take().unwrap();
539 let object = client.endpoint.objects.borrow_mut().remove(&id);
540 drop(object);
541 client.endpoint.idl.release(idl);
542 } else {
543 self.awaiting_delete_id.set(true);
544 }
545 }
546
547 pub(crate) fn handle_server_destroy(&self) {
548 let id = self.server_obj_id.get().unwrap();
549 if id < MIN_SERVER_ID {
550 return;
551 }
552 self.server_obj_id.take();
553 let _object = self
554 .state
555 .server
556 .as_ref()
557 .unwrap()
558 .objects
559 .borrow_mut()
560 .remove(&id);
561 }
562}
563
564impl Drop for ObjectCore {
565 fn drop(&mut self) {
566 self.state.all_objects.borrow_mut().remove(&self.id);
567 }
568}
569
570#[derive(Debug, Error)]
572#[error(transparent)]
573pub struct ObjectError(#[from] pub(crate) ObjectErrorKind);
574
575#[derive(Debug, Error)]
576pub(crate) enum ObjectErrorKind {
577 #[error("could not generate a client id for argument {0}")]
578 GenerateClientId(&'static str, #[source] IdError),
579 #[error("could not generate a server id for argument {0}")]
580 GenerateServerId(&'static str, #[source] IdError),
581 #[error("could not assign client id {0} to argument {1}")]
582 SetClientId(u32, &'static str, #[source] IdError),
583 #[error("could not assign server id {0} to argument {1}")]
584 SetServerId(u32, &'static str, #[source] IdError),
585 #[error("client {0} has no object with id {1}")]
586 NoClientObject(u64, u32),
587 #[error("server has no object with id {0}")]
588 NoServerObject(u32),
589 #[error("argument {} has type {} but should have type {}", .0, .1.name(), .2.name())]
590 WrongObjectType(&'static str, ObjectInterface, ObjectInterface),
591 #[error("the requested version {} for interface {} is larger than the max version {}", .1, .0.name(), .0.xml_version())]
592 MaxVersion(ObjectInterface, u32),
593 #[error("the interface {0} is not supported")]
594 UnsupportedInterface(String),
595 #[error("the receiver has no server id")]
596 ReceiverNoServerId,
597 #[error("the receiver has no client")]
598 ReceiverNoClient,
599 #[error("the argument {0} is not associated with client {1}")]
600 ArgNoClientId(&'static str, u64),
601 #[error("the argument {0} has no server id")]
602 ArgNoServerId(&'static str),
603 #[error("the size of the message is {0} instead of {0}")]
604 WrongMessageSize(u32, u32),
605 #[error("unknown message id {0}")]
606 UnknownMessageId(u32),
607 #[error("the file descriptor for argument {0} is missing")]
608 MissingFd(&'static str),
609 #[error("there are trailing bytes after the message")]
610 TrailingBytes,
611 #[error("argument {0} is not present in the message")]
612 MissingArgument(&'static str),
613 #[error("argument {0} is a null string but the argument is not nullable")]
614 NullString(&'static str),
615 #[error("argument {0} is not valid UTF-8")]
616 NonUtf8(&'static str),
617 #[error("server sent error {} on object {}#{}", .2, .0.name(), .1)]
618 ServerError(ObjectInterface, u32, u32, #[source] StringError),
619 #[error("the message handler is already borrowed")]
620 HandlerBorrowed,
621 #[error("the client is not waiting for a delete_id message")]
622 NotAwaitingDeleteId,
623}
624
625#[derive(Debug, Error)]
626#[error("{0}")]
627pub(crate) struct StringError(pub String);