wl_client/proxy/
low_level.rs

1//! Low-level proxy APIs.
2//!
3//! This module contains low-level APIs that are usually only used by `wl-client-builder` in
4//! generated protocol bindings.
5
6pub(crate) use owned::{OwnedProxyRegistry, destruction::ProxyDataDestruction};
7use {
8    crate::{
9        ffi::wl_proxy,
10        proxy::{BorrowedProxy, OwnedProxy, get_owned},
11    },
12    std::{
13        mem::{self, ManuallyDrop},
14        ptr::NonNull,
15    },
16};
17pub use {
18    borrowed::{UntypedBorrowedProxy, UntypedBorrowedProxyWrapper},
19    owned::{EventHandler, UntypedOwnedProxy, UntypedOwnedProxyWrapper},
20};
21
22pub(super) mod borrowed;
23pub(crate) mod owned;
24#[cfg(test)]
25mod tests;
26
27/// A type that can create an event handler.
28///
29/// This type is usually implemented by [`OwnedProxy::Api`] to turn an object implementing
30/// safe event callbacks into an event handler that can handle raw libwayland events.
31///
32/// This type is usually implemented by bindings that are automatically generated with the
33/// `wl-client-builder` crate.
34pub trait CreateEventHandler<T> {
35    type EventHandler: EventHandler;
36
37    /// Creates a new event handler.
38    fn create_event_handler(handler: T) -> Self::EventHandler;
39}
40
41#[inline]
42pub(crate) fn check_dispatching_proxy(proxy: Option<NonNull<wl_proxy>>) -> NonNull<wl_proxy> {
43    match proxy {
44        None => {
45            #[cold]
46            fn not_null() -> ! {
47                panic!("Proxy has already been destroyed");
48            }
49            not_null();
50        }
51        Some(p) => p,
52    }
53}
54
55#[inline]
56pub(crate) fn check_new_proxy(proxy: *mut wl_proxy) -> NonNull<wl_proxy> {
57    if let Some(proxy) = NonNull::new(proxy) {
58        proxy
59    } else {
60        #[cold]
61        fn not_null() -> ! {
62            panic!("new wl_proxy is null");
63        }
64        not_null();
65    }
66}
67
68/// Returns the borrowed version of an owned proxy.
69///
70/// This is a low-level API that you probably don't have to use unless you are writing
71/// protocol wrappers by hand.
72///
73/// `wl-client-builder` uses this function to implement the `Deref` trait.
74///
75/// # Example
76///
77/// ```
78/// # use wl_client::{proxy, Libwayland};
79/// # use wl_client::test_protocols::core::wl_display::{WlDisplay, WlDisplayRef};
80/// #
81/// let lib = Libwayland::open().unwrap();
82/// let con = lib.connect_to_default_display().unwrap();
83/// let queue = con.create_queue(c"queue name");
84///
85/// let display: WlDisplay = queue.display();
86/// let display_ref: &WlDisplayRef = proxy::low_level::deref(&display);
87/// ```
88pub fn deref<P>(proxy: &P) -> &P::Borrowed
89where
90    P: OwnedProxy,
91{
92    let borrowed: &UntypedBorrowedProxy = get_owned(proxy);
93    // SAFETY: borrowed has the interface P:WL_INTERFACE = P::Borrowed::Owned::WL_INTERFACE
94    unsafe { from_untyped_borrowed(borrowed) }
95}
96
97/// Creates a well-typed, borrowed proxy.
98///
99/// This is a low-level API that you probably don't have to use unless you are writing
100/// protocol wrappers by hand.
101///
102/// # Safety
103///
104/// - The proxy must have an interface compatible with `P::Owned::WL_INTERFACE`.
105#[inline]
106pub unsafe fn from_untyped_borrowed<P>(proxy: &UntypedBorrowedProxy) -> &P
107where
108    P: BorrowedProxy,
109{
110    // SAFETY: - Since the interface of the proxy is compatible with
111    //           P::Owned::WL_INTERFACE, BorrowedProxy requires that this transmute is
112    //           safe.
113    unsafe { mem::transmute::<&UntypedBorrowedProxy, &P>(proxy) }
114}
115
116/// Creates a well-typed, owned proxy.
117///
118/// This is a low-level API that you probably don't have to use unless you are writing
119/// protocol wrappers by hand.
120///
121/// # Safety
122///
123/// - The proxy must have an interface compatible with `P::WL_INTERFACE`.
124#[inline]
125pub unsafe fn from_untyped_owned<P>(proxy: UntypedOwnedProxy) -> P
126where
127    P: OwnedProxy,
128{
129    let proxy = ManuallyDrop::new(proxy);
130    // SAFETY: - Since the interface of the proxy is compatible with P::WL_INTERFACE,
131    //           OwnedProxy requires that this transmute is safe.
132    unsafe { mem::transmute_copy::<UntypedOwnedProxy, P>(&*proxy) }
133}