simple_window/common/protocols/wayland/
wl_buffer.rs

1//! content for a wl_surface
2//!
3//! A buffer provides the content for a wl_surface. Buffers are
4//! created through factory interfaces such as wl_shm, wp_linux_buffer_params
5//! (from the linux-dmabuf protocol extension) or similar. It has a width and
6//! a height and can be attached to a wl_surface, but the mechanism by which a
7//! client provides and updates the contents is defined by the buffer factory
8//! interface.
9//!
10//! Color channels are assumed to be electrical rather than optical (in other
11//! words, encoded with a transfer function) unless otherwise specified. If
12//! the buffer uses a format that has an alpha channel, the alpha channel is
13//! assumed to be premultiplied into the electrical color channel values
14//! (after transfer function encoding) unless otherwise specified.
15//!
16//! Note, because wl_buffer objects are created from multiple independent
17//! factory interfaces, the wl_buffer interface is frozen at version 1.
18
19use {super::super::all_types::*, ::wl_client::builder::prelude::*};
20
21static INTERFACE: wl_interface = wl_interface {
22    name: c"wl_buffer".as_ptr(),
23    version: 1,
24    method_count: 1,
25    methods: {
26        static MESSAGES: [wl_message; 1] = [wl_message {
27            name: c"destroy".as_ptr(),
28            signature: c"".as_ptr(),
29            types: {
30                static TYPES: [Option<&'static wl_interface>; 0] = [];
31                TYPES.as_ptr().cast()
32            },
33        }];
34        MESSAGES.as_ptr()
35    },
36    event_count: 1,
37    events: {
38        static MESSAGES: [wl_message; 1] = [wl_message {
39            name: c"release".as_ptr(),
40            signature: c"".as_ptr(),
41            types: {
42                static TYPES: [Option<&'static wl_interface>; 0] = [];
43                TYPES.as_ptr().cast()
44            },
45        }];
46        MESSAGES.as_ptr()
47    },
48};
49
50/// An owned wl_buffer proxy.
51///
52/// See the documentation of [the module][self] for the interface description.
53#[derive(Clone, Eq, PartialEq)]
54#[repr(transparent)]
55pub struct WlBuffer {
56    /// This proxy has the interface INTERFACE.
57    proxy: UntypedOwnedProxy,
58}
59
60/// A borrowed wl_buffer proxy.
61///
62/// See the documentation of [the module][self] for the interface description.
63#[derive(Eq, PartialEq)]
64#[repr(transparent)]
65pub struct WlBufferRef {
66    /// This proxy has the interface INTERFACE.
67    proxy: UntypedBorrowedProxy,
68}
69
70// SAFETY: WlBuffer is a transparent wrapper around UntypedOwnedProxy
71unsafe impl UntypedOwnedProxyWrapper for WlBuffer {}
72
73// SAFETY: - INTERFACE is a valid wl_interface
74//         - The only invariant is that self.proxy has a compatible interface
75unsafe impl OwnedProxy for WlBuffer {
76    const INTERFACE: &'static str = "wl_buffer";
77    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
78    const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
79        private::EventHandler(private::NoOpEventHandler);
80    const MAX_VERSION: u32 = 1;
81
82    type Borrowed = WlBufferRef;
83    type Api = private::ProxyApi;
84    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
85}
86
87// SAFETY: WlBufferRef is a transparent wrapper around UntypedBorrowedProxy
88unsafe impl UntypedBorrowedProxyWrapper for WlBufferRef {}
89
90// SAFETY: - The only invariant is that self.proxy has a compatible interface
91unsafe impl BorrowedProxy for WlBufferRef {
92    type Owned = WlBuffer;
93}
94
95impl Deref for WlBuffer {
96    type Target = WlBufferRef;
97
98    fn deref(&self) -> &Self::Target {
99        proxy::low_level::deref(self)
100    }
101}
102
103mod private {
104    pub struct ProxyApi;
105
106    #[allow(dead_code)]
107    pub struct EventHandler<H>(pub(super) H);
108
109    #[allow(dead_code)]
110    pub struct NoOpEventHandler;
111}
112
113impl Debug for WlBuffer {
114    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
115        write!(f, "wl_buffer#{}", self.proxy.id())
116    }
117}
118
119impl Debug for WlBufferRef {
120    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
121        write!(f, "wl_buffer#{}", self.proxy.id())
122    }
123}
124
125impl PartialEq<WlBufferRef> for WlBuffer {
126    fn eq(&self, other: &WlBufferRef) -> bool {
127        self.proxy == other.proxy
128    }
129}
130
131impl PartialEq<WlBuffer> for WlBufferRef {
132    fn eq(&self, other: &WlBuffer) -> bool {
133        self.proxy == other.proxy
134    }
135}
136
137#[allow(dead_code)]
138impl WlBuffer {
139    /// Since when the destroy request is available.
140    #[allow(dead_code)]
141    pub const REQ__DESTROY__SINCE: u32 = 1;
142
143    /// destroy a buffer
144    ///
145    /// Destroy a buffer. If and how you need to release the backing
146    /// storage is defined by the buffer factory interface.
147    ///
148    /// For possible side-effects to a surface, see wl_surface.attach.
149    #[inline]
150    pub fn destroy(&self) {
151        let mut args = [];
152        // SAFETY: - self.proxy has the interface INTERFACE
153        //         - 0 < INTERFACE.method_count = 1
154        //         - the request signature is ``
155        unsafe {
156            self.proxy.send_destructor(0, &mut args);
157        }
158    }
159}
160
161impl WlBuffer {
162    /// Since when the release event is available.
163    #[allow(dead_code)]
164    pub const EVT__RELEASE__SINCE: u32 = 1;
165}
166
167/// An event handler for [WlBuffer] proxies.
168#[allow(dead_code)]
169pub trait WlBufferEventHandler {
170    /// compositor releases buffer
171    ///
172    /// Sent when this wl_buffer is no longer used by the compositor.
173    /// The client is now free to reuse or destroy this buffer and its
174    /// backing storage.
175    ///
176    /// If a client receives a release event before the frame callback
177    /// requested in the same wl_surface.commit that attaches this
178    /// wl_buffer to a surface, then the client is immediately free to
179    /// reuse the buffer and its backing storage, and does not need a
180    /// second buffer for the next surface content update. Typically
181    /// this is possible, when the compositor maintains a copy of the
182    /// wl_surface contents, e.g. as a GL texture. This is an important
183    /// optimization for GL(ES) compositors with wl_shm clients.
184    #[inline]
185    fn release(&self, _slf: &WlBufferRef) {}
186}
187
188impl WlBufferEventHandler for private::NoOpEventHandler {}
189
190// SAFETY: - INTERFACE is a valid wl_interface
191unsafe impl<H> EventHandler for private::EventHandler<H>
192where
193    H: WlBufferEventHandler,
194{
195    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
196
197    #[allow(unused_variables)]
198    unsafe fn handle_event(
199        &self,
200        queue: &Queue,
201        data: *mut u8,
202        slf: &UntypedBorrowedProxy,
203        opcode: u32,
204        args: *mut wl_argument,
205    ) {
206        // SAFETY: This function requires that slf has the interface INTERFACE
207        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlBufferRef>(slf) };
208        match opcode {
209            0 => {
210                self.0.release(slf);
211            }
212            _ => {
213                invalid_opcode("wl_buffer", opcode);
214            }
215        }
216    }
217}
218
219impl<H> CreateEventHandler<H> for private::ProxyApi
220where
221    H: WlBufferEventHandler,
222{
223    type EventHandler = private::EventHandler<H>;
224
225    #[inline]
226    fn create_event_handler(handler: H) -> Self::EventHandler {
227        private::EventHandler(handler)
228    }
229}
230
231/// Functional event handlers.
232pub mod event_handlers {
233    use super::*;
234
235    /// Event handler for release events.
236    pub struct Release<F>(F);
237    impl<F> WlBufferEventHandler for Release<F>
238    where
239        F: Fn(&WlBufferRef),
240    {
241        #[inline]
242        fn release(&self, _slf: &WlBufferRef) {
243            self.0(_slf)
244        }
245    }
246
247    impl WlBuffer {
248        /// Creates an event handler for release events.
249        ///
250        /// The event handler ignores all other events.
251        #[allow(dead_code)]
252        pub fn on_release<F>(f: F) -> Release<F>
253        where
254            F: Fn(&WlBufferRef),
255        {
256            Release(f)
257        }
258    }
259}