simple_window/common/protocols_data/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    type Data: 'static;
171
172    /// compositor releases buffer
173    ///
174    /// Sent when this wl_buffer is no longer used by the compositor.
175    /// The client is now free to reuse or destroy this buffer and its
176    /// backing storage.
177    ///
178    /// If a client receives a release event before the frame callback
179    /// requested in the same wl_surface.commit that attaches this
180    /// wl_buffer to a surface, then the client is immediately free to
181    /// reuse the buffer and its backing storage, and does not need a
182    /// second buffer for the next surface content update. Typically
183    /// this is possible, when the compositor maintains a copy of the
184    /// wl_surface contents, e.g. as a GL texture. This is an important
185    /// optimization for GL(ES) compositors with wl_shm clients.
186    #[inline]
187    fn release(&self, _data: &mut Self::Data, _slf: &WlBufferRef) {}
188}
189
190impl WlBufferEventHandler for private::NoOpEventHandler {
191    type Data = ();
192}
193
194// SAFETY: - INTERFACE is a valid wl_interface
195//         - mutable_type always returns the same value
196unsafe impl<H> EventHandler for private::EventHandler<H>
197where
198    H: WlBufferEventHandler,
199{
200    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
201
202    #[inline]
203    fn mutable_type() -> Option<(TypeId, &'static str)> {
204        let id = TypeId::of::<H::Data>();
205        let name = std::any::type_name::<H::Data>();
206        Some((id, name))
207    }
208
209    #[allow(unused_variables)]
210    unsafe fn handle_event(
211        &self,
212        queue: &Queue,
213        data: *mut u8,
214        slf: &UntypedBorrowedProxy,
215        opcode: u32,
216        args: *mut wl_argument,
217    ) {
218        // SAFETY: This function requires that slf has the interface INTERFACE
219        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlBufferRef>(slf) };
220        // SAFETY: This function requires that data is `&mut T` where `T`
221        //         has the type id returned by `Self::mutable_type`, i.e.,
222        //         `T = H::Data`.
223        let data: &mut H::Data = unsafe { &mut *data.cast() };
224        match opcode {
225            0 => {
226                self.0.release(data, slf);
227            }
228            _ => {
229                invalid_opcode("wl_buffer", opcode);
230            }
231        }
232    }
233}
234
235impl<H> CreateEventHandler<H> for private::ProxyApi
236where
237    H: WlBufferEventHandler,
238{
239    type EventHandler = private::EventHandler<H>;
240
241    #[inline]
242    fn create_event_handler(handler: H) -> Self::EventHandler {
243        private::EventHandler(handler)
244    }
245}
246
247/// Functional event handlers.
248pub mod event_handlers {
249    use super::*;
250
251    /// Event handler for release events.
252    pub struct Release<T, F>(F, PhantomData<fn(&mut T)>);
253    impl<T, F> WlBufferEventHandler for Release<T, F>
254    where
255        T: 'static,
256        F: Fn(&mut T, &WlBufferRef),
257    {
258        type Data = T;
259
260        #[inline]
261        fn release(&self, _data: &mut T, _slf: &WlBufferRef) {
262            self.0(_data, _slf)
263        }
264    }
265
266    impl WlBuffer {
267        /// Creates an event handler for release events.
268        ///
269        /// The event handler ignores all other events.
270        #[allow(dead_code)]
271        pub fn on_release<T, F>(f: F) -> Release<T, F>
272        where
273            T: 'static,
274            F: Fn(&mut T, &WlBufferRef),
275        {
276            Release(f, PhantomData)
277        }
278    }
279}