| 1 | //! Server-side rust implementation of a Wayland protocol backend |
| 2 | |
| 3 | use std::os::unix::io::OwnedFd; |
| 4 | use std::{fmt, sync::Arc}; |
| 5 | |
| 6 | use crate::protocol::{same_interface, Interface, Message}; |
| 7 | |
| 8 | mod client; |
| 9 | mod common_poll; |
| 10 | mod handle; |
| 11 | mod registry; |
| 12 | |
| 13 | pub use crate::types::server::Credentials; |
| 14 | pub use common_poll::InnerBackend; |
| 15 | pub use handle::{InnerHandle, WeakInnerHandle}; |
| 16 | |
| 17 | use super::server::*; |
| 18 | |
| 19 | #[derive (Clone)] |
| 20 | pub struct InnerObjectId { |
| 21 | id: u32, |
| 22 | serial: u32, |
| 23 | client_id: InnerClientId, |
| 24 | interface: &'static Interface, |
| 25 | } |
| 26 | |
| 27 | impl InnerObjectId { |
| 28 | pub fn is_null(&self) -> bool { |
| 29 | self.id == 0 |
| 30 | } |
| 31 | |
| 32 | pub fn interface(&self) -> &'static Interface { |
| 33 | self.interface |
| 34 | } |
| 35 | |
| 36 | pub fn same_client_as(&self, other: &Self) -> bool { |
| 37 | self.client_id == other.client_id |
| 38 | } |
| 39 | |
| 40 | pub fn protocol_id(&self) -> u32 { |
| 41 | self.id |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | impl fmt::Display for InnerObjectId { |
| 46 | #[cfg_attr (coverage, coverage(off))] |
| 47 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 48 | write!(f, " {}@ {}[ {}]" , self.interface.name, self.id, self.client_id.id) |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | impl fmt::Debug for InnerObjectId { |
| 53 | #[cfg_attr (coverage, coverage(off))] |
| 54 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 55 | write!(f, "ObjectId( {}, {})" , self, self.serial) |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | impl PartialEq for InnerObjectId { |
| 60 | fn eq(&self, other: &Self) -> bool { |
| 61 | self.id == other.id |
| 62 | && self.serial == other.serial |
| 63 | && self.client_id == other.client_id |
| 64 | && same_interface(self.interface, b:other.interface) |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | impl std::cmp::Eq for InnerObjectId {} |
| 69 | |
| 70 | impl std::hash::Hash for InnerObjectId { |
| 71 | fn hash<H: std::hash::Hasher>(&self, state: &mut H) { |
| 72 | self.id.hash(state); |
| 73 | self.serial.hash(state); |
| 74 | self.client_id.hash(state); |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | /// An id of a client connected to the server. |
| 79 | #[derive (Clone, Debug, PartialEq, Eq, Hash)] |
| 80 | pub struct InnerClientId { |
| 81 | id: u32, |
| 82 | serial: u32, |
| 83 | } |
| 84 | |
| 85 | impl InnerClientId { |
| 86 | fn as_u64(&self) -> u64 { |
| 87 | ((self.id as u64) << 32) + self.serial as u64 |
| 88 | } |
| 89 | |
| 90 | fn from_u64(t: u64) -> Self { |
| 91 | Self { id: (t >> 32) as u32, serial: t as u32 } |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | /// The ID of a global |
| 96 | #[derive (Clone, Debug, PartialEq, Eq, Hash)] |
| 97 | pub struct InnerGlobalId { |
| 98 | id: u32, |
| 99 | serial: u32, |
| 100 | } |
| 101 | |
| 102 | #[derive (Debug)] |
| 103 | pub(crate) struct Data<D: 'static> { |
| 104 | user_data: Arc<dyn ObjectData<D>>, |
| 105 | serial: u32, |
| 106 | } |
| 107 | |
| 108 | impl<D> Clone for Data<D> { |
| 109 | #[cfg_attr (coverage, coverage(off))] |
| 110 | fn clone(&self) -> Self { |
| 111 | Self { user_data: self.user_data.clone(), serial: self.serial } |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | struct UninitObjectData; |
| 116 | |
| 117 | impl<D> ObjectData<D> for UninitObjectData { |
| 118 | #[cfg_attr (coverage, coverage(off))] |
| 119 | fn request( |
| 120 | self: Arc<Self>, |
| 121 | _: &Handle, |
| 122 | _: &mut D, |
| 123 | _: ClientId, |
| 124 | msg: Message<ObjectId, OwnedFd>, |
| 125 | ) -> Option<Arc<dyn ObjectData<D>>> { |
| 126 | panic!("Received a message on an uninitialized object: {:?}" , msg); |
| 127 | } |
| 128 | |
| 129 | #[cfg_attr (coverage, coverage(off))] |
| 130 | fn destroyed(self: Arc<Self>, _: &Handle, _: &mut D, _: ClientId, _: ObjectId) {} |
| 131 | |
| 132 | #[cfg_attr (coverage, coverage(off))] |
| 133 | fn debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| 134 | f.debug_struct(name:"UninitObjectData" ).finish() |
| 135 | } |
| 136 | } |
| 137 | |