#![forbid(improper_ctypes, unsafe_op_in_unsafe_fn)]
#![cfg_attr(docsrs, feature(doc_cfg))]
use std::{
fmt,
hash::{Hash, Hasher},
os::unix::io::OwnedFd,
};
use wayland_backend::{
protocol::{Interface, Message},
server::{InvalidId, ObjectId, WeakHandle},
};
mod client;
mod dispatch;
mod display;
mod global;
mod socket;
pub use client::Client;
pub use dispatch::{DataInit, Dispatch, New, ResourceData};
pub use display::{Display, DisplayHandle};
pub use global::GlobalDispatch;
pub use socket::{BindError, ListeningSocket};
pub mod backend {
pub use wayland_backend::protocol;
pub use wayland_backend::server::{
Backend, ClientData, ClientId, Credentials, DisconnectReason, GlobalHandler, GlobalId,
Handle, InitError, InvalidId, ObjectData, ObjectId, WeakHandle,
};
pub use wayland_backend::smallvec;
}
pub use wayland_backend::protocol::WEnum;
#[allow(missing_docs)]
pub mod protocol {
use self::__interfaces::*;
use crate as wayland_server;
pub mod __interfaces {
wayland_scanner::generate_interfaces!("wayland.xml");
}
wayland_scanner::generate_server_code!("wayland.xml");
}
#[cfg(feature = "log")]
#[allow(unused_imports)]
use log::{debug as log_debug, error as log_error, info as log_info, warn as log_warn};
#[cfg(not(feature = "log"))]
#[allow(unused_imports)]
use std::{
eprintln as log_error, eprintln as log_warn, eprintln as log_info, eprintln as log_debug,
};
pub trait Resource: Clone + std::fmt::Debug + Sized {
type Event<'a>;
type Request;
fn interface() -> &'static Interface;
fn id(&self) -> ObjectId;
fn client(&self) -> Option<Client> {
let handle = self.handle().upgrade()?;
let client_id = handle.get_client(self.id()).ok()?;
let dh = DisplayHandle::from(handle);
Client::from_id(&dh, client_id).ok()
}
fn version(&self) -> u32;
#[inline]
fn is_alive(&self) -> bool {
if let Some(handle) = self.handle().upgrade() {
handle.object_info(self.id()).is_ok()
} else {
false
}
}
fn data<U: 'static>(&self) -> Option<&U>;
fn object_data(&self) -> Option<&std::sync::Arc<dyn std::any::Any + Send + Sync>>;
fn handle(&self) -> &backend::WeakHandle;
fn from_id(dh: &DisplayHandle, id: ObjectId) -> Result<Self, InvalidId>;
fn send_event(&self, evt: Self::Event<'_>) -> Result<(), InvalidId>;
#[inline]
fn post_error(&self, code: impl Into<u32>, error: impl Into<String>) {
if let Some(dh) = self.handle().upgrade().map(DisplayHandle::from) {
dh.post_error(self, code.into(), error.into());
}
}
fn parse_request(
dh: &DisplayHandle,
msg: Message<ObjectId, OwnedFd>,
) -> Result<(Self, Self::Request), DispatchError>;
fn write_event<'a>(
&self,
dh: &DisplayHandle,
req: Self::Event<'a>,
) -> Result<Message<ObjectId, std::os::unix::io::BorrowedFd<'a>>, InvalidId>;
#[inline]
fn downgrade(&self) -> Weak<Self> {
Weak { handle: self.handle().clone(), id: self.id(), _iface: std::marker::PhantomData }
}
#[doc(hidden)]
fn __set_object_data(
&mut self,
odata: std::sync::Arc<dyn std::any::Any + Send + Sync + 'static>,
);
}
#[derive(Debug)]
pub enum DispatchError {
BadMessage {
sender_id: ObjectId,
interface: &'static str,
opcode: u16,
},
}
impl std::error::Error for DispatchError {}
impl fmt::Display for DispatchError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DispatchError::BadMessage { sender_id, interface, opcode } => {
write!(f, "Bad message for object {interface}@{sender_id} on opcode {opcode}",)
}
}
}
}
#[derive(Debug, Clone)]
pub struct Weak<I> {
handle: WeakHandle,
id: ObjectId,
_iface: std::marker::PhantomData<I>,
}
impl<I: Resource> Weak<I> {
#[inline]
pub fn upgrade(&self) -> Result<I, InvalidId> {
let handle = self.handle.upgrade().ok_or(InvalidId)?;
handle.object_info(self.id.clone())?;
let d_handle = DisplayHandle::from(handle);
I::from_id(&d_handle, self.id.clone())
}
#[inline]
pub fn is_alive(&self) -> bool {
let Some(handle) = self.handle.upgrade() else {
return false;
};
handle.object_info(self.id.clone()).is_ok()
}
pub fn id(&self) -> ObjectId {
self.id.clone()
}
}
impl<I> PartialEq for Weak<I> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl<I> Eq for Weak<I> {}
impl<I> Hash for Weak<I> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state);
}
}
impl<I: Resource> PartialEq<I> for Weak<I> {
#[inline]
fn eq(&self, other: &I) -> bool {
self.id == other.id()
}
}