simple_window/common/protocols/wayland/
wl_shm_pool.rs

1//! a shared memory pool
2//!
3//! The wl_shm_pool object encapsulates a piece of memory shared
4//! between the compositor and client.  Through the wl_shm_pool
5//! object, the client can allocate shared memory wl_buffer objects.
6//! All objects created through the same pool share the same
7//! underlying mapped memory. Reusing the mapped memory avoids the
8//! setup/teardown overhead and is useful when interactively resizing
9//! a surface or for many small buffers.
10
11use {super::super::all_types::*, ::wl_client::builder::prelude::*};
12
13static INTERFACE: wl_interface = wl_interface {
14    name: c"wl_shm_pool".as_ptr(),
15    version: 2,
16    method_count: 3,
17    methods: {
18        static MESSAGES: [wl_message; 3] = [
19            wl_message {
20                name: c"create_buffer".as_ptr(),
21                signature: c"niiiiu".as_ptr(),
22                types: {
23                    static TYPES: [Option<&'static wl_interface>; 6] =
24                        [Some(WlBuffer::WL_INTERFACE), None, None, None, None, None];
25                    TYPES.as_ptr().cast()
26                },
27            },
28            wl_message {
29                name: c"destroy".as_ptr(),
30                signature: c"".as_ptr(),
31                types: {
32                    static TYPES: [Option<&'static wl_interface>; 0] = [];
33                    TYPES.as_ptr().cast()
34                },
35            },
36            wl_message {
37                name: c"resize".as_ptr(),
38                signature: c"i".as_ptr(),
39                types: {
40                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
41                    TYPES.as_ptr().cast()
42                },
43            },
44        ];
45        MESSAGES.as_ptr()
46    },
47    event_count: 0,
48    events: ptr::null(),
49};
50
51/// An owned wl_shm_pool proxy.
52///
53/// See the documentation of [the module][self] for the interface description.
54#[derive(Clone, Eq, PartialEq)]
55#[repr(transparent)]
56pub struct WlShmPool {
57    /// This proxy has the interface INTERFACE.
58    proxy: UntypedOwnedProxy,
59}
60
61/// A borrowed wl_shm_pool proxy.
62///
63/// See the documentation of [the module][self] for the interface description.
64#[derive(Eq, PartialEq)]
65#[repr(transparent)]
66pub struct WlShmPoolRef {
67    /// This proxy has the interface INTERFACE.
68    proxy: UntypedBorrowedProxy,
69}
70
71// SAFETY: WlShmPool is a transparent wrapper around UntypedOwnedProxy
72unsafe impl UntypedOwnedProxyWrapper for WlShmPool {}
73
74// SAFETY: - INTERFACE is a valid wl_interface
75//         - The only invariant is that self.proxy has a compatible interface
76unsafe impl OwnedProxy for WlShmPool {
77    const INTERFACE: &'static str = "wl_shm_pool";
78    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
79    const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
80        private::EventHandler(private::NoOpEventHandler);
81    const MAX_VERSION: u32 = 2;
82
83    type Borrowed = WlShmPoolRef;
84    type Api = private::ProxyApi;
85    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
86}
87
88// SAFETY: WlShmPoolRef is a transparent wrapper around UntypedBorrowedProxy
89unsafe impl UntypedBorrowedProxyWrapper for WlShmPoolRef {}
90
91// SAFETY: - The only invariant is that self.proxy has a compatible interface
92unsafe impl BorrowedProxy for WlShmPoolRef {
93    type Owned = WlShmPool;
94}
95
96impl Deref for WlShmPool {
97    type Target = WlShmPoolRef;
98
99    fn deref(&self) -> &Self::Target {
100        proxy::low_level::deref(self)
101    }
102}
103
104mod private {
105    pub struct ProxyApi;
106
107    #[allow(dead_code)]
108    pub struct EventHandler<H>(pub(super) H);
109
110    #[allow(dead_code)]
111    pub struct NoOpEventHandler;
112}
113
114impl Debug for WlShmPool {
115    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
116        write!(f, "wl_shm_pool#{}", self.proxy.id())
117    }
118}
119
120impl Debug for WlShmPoolRef {
121    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
122        write!(f, "wl_shm_pool#{}", self.proxy.id())
123    }
124}
125
126impl PartialEq<WlShmPoolRef> for WlShmPool {
127    fn eq(&self, other: &WlShmPoolRef) -> bool {
128        self.proxy == other.proxy
129    }
130}
131
132impl PartialEq<WlShmPool> for WlShmPoolRef {
133    fn eq(&self, other: &WlShmPool) -> bool {
134        self.proxy == other.proxy
135    }
136}
137
138#[allow(dead_code)]
139impl WlShmPool {
140    /// Since when the create_buffer request is available.
141    #[allow(dead_code)]
142    pub const REQ__CREATE_BUFFER__SINCE: u32 = 1;
143
144    /// create a buffer from the pool
145    ///
146    /// Create a wl_buffer object from the pool.
147    ///
148    /// The buffer is created offset bytes into the pool and has
149    /// width and height as specified.  The stride argument specifies
150    /// the number of bytes from the beginning of one row to the beginning
151    /// of the next.  The format is the pixel format of the buffer and
152    /// must be one of those advertised through the wl_shm.format event.
153    ///
154    /// A buffer will keep a reference to the pool it was created from
155    /// so it is valid to destroy the pool immediately after creating
156    /// a buffer from it.
157    ///
158    /// # Arguments
159    ///
160    /// - `offset`: buffer byte offset within the pool
161    /// - `width`: buffer width, in pixels
162    /// - `height`: buffer height, in pixels
163    /// - `stride`: number of bytes from the beginning of one row to the beginning of the next row
164    /// - `format`: buffer pixel format
165    #[inline]
166    pub fn create_buffer(
167        &self,
168        offset: i32,
169        width: i32,
170        height: i32,
171        stride: i32,
172        format: WlShmFormat,
173    ) -> WlBuffer {
174        let (arg1, arg2, arg3, arg4, arg5) = (offset, width, height, stride, format);
175        let mut args = [
176            wl_argument { n: 0 },
177            wl_argument { i: arg1 },
178            wl_argument { i: arg2 },
179            wl_argument { i: arg3 },
180            wl_argument { i: arg4 },
181            wl_argument { u: arg5.0 },
182        ];
183        // SAFETY: - self.proxy has the interface INTERFACE
184        //         - 0 < INTERFACE.method_count = 3
185        //         - the request signature is `niiiiu`
186        //         - OwnedProxy::WL_INTERFACE is always a valid interface
187        let data = unsafe {
188            self.proxy
189                .send_constructor::<false>(0, &mut args, WlBuffer::WL_INTERFACE, None)
190        };
191        // SAFETY: data has the interface WlBuffer::WL_INTERFACE
192        unsafe { proxy::low_level::from_untyped_owned(data) }
193    }
194
195    /// Since when the destroy request is available.
196    #[allow(dead_code)]
197    pub const REQ__DESTROY__SINCE: u32 = 1;
198
199    /// destroy the pool
200    ///
201    /// Destroy the shared memory pool.
202    ///
203    /// The mmapped memory will be released when all
204    /// buffers that have been created from this pool
205    /// are gone.
206    #[inline]
207    pub fn destroy(&self) {
208        let mut args = [];
209        // SAFETY: - self.proxy has the interface INTERFACE
210        //         - 1 < INTERFACE.method_count = 3
211        //         - the request signature is ``
212        unsafe {
213            self.proxy.send_destructor(1, &mut args);
214        }
215    }
216}
217
218#[allow(dead_code)]
219impl WlShmPoolRef {
220    /// create a buffer from the pool
221    ///
222    /// Create a wl_buffer object from the pool.
223    ///
224    /// The buffer is created offset bytes into the pool and has
225    /// width and height as specified.  The stride argument specifies
226    /// the number of bytes from the beginning of one row to the beginning
227    /// of the next.  The format is the pixel format of the buffer and
228    /// must be one of those advertised through the wl_shm.format event.
229    ///
230    /// A buffer will keep a reference to the pool it was created from
231    /// so it is valid to destroy the pool immediately after creating
232    /// a buffer from it.
233    ///
234    /// # Arguments
235    ///
236    /// - `_queue`: The queue that the returned proxy is assigned to.
237    /// - `offset`: buffer byte offset within the pool
238    /// - `width`: buffer width, in pixels
239    /// - `height`: buffer height, in pixels
240    /// - `stride`: number of bytes from the beginning of one row to the beginning of the next row
241    /// - `format`: buffer pixel format
242    #[inline]
243    pub fn create_buffer(
244        &self,
245        _queue: &Queue,
246        offset: i32,
247        width: i32,
248        height: i32,
249        stride: i32,
250        format: WlShmFormat,
251    ) -> WlBuffer {
252        let (arg1, arg2, arg3, arg4, arg5) = (offset, width, height, stride, format);
253        let mut args = [
254            wl_argument { n: 0 },
255            wl_argument { i: arg1 },
256            wl_argument { i: arg2 },
257            wl_argument { i: arg3 },
258            wl_argument { i: arg4 },
259            wl_argument { u: arg5.0 },
260        ];
261        // SAFETY: - self.proxy has the interface INTERFACE
262        //         - 0 < INTERFACE.method_count = 3
263        //         - the request signature is `niiiiu`
264        //         - OwnedProxy::WL_INTERFACE is always a valid interface
265        let data = unsafe {
266            self.proxy
267                .send_constructor(_queue, 0, &mut args, WlBuffer::WL_INTERFACE, None)
268        };
269        // SAFETY: data has the interface WlBuffer::WL_INTERFACE
270        unsafe { proxy::low_level::from_untyped_owned(data) }
271    }
272
273    /// change the size of the pool mapping
274    ///
275    /// This request will cause the server to remap the backing memory
276    /// for the pool from the file descriptor passed when the pool was
277    /// created, but using the new size.  This request can only be
278    /// used to make the pool bigger.
279    ///
280    /// This request only changes the amount of bytes that are mmapped
281    /// by the server and does not touch the file corresponding to the
282    /// file descriptor passed at creation time. It is the client's
283    /// responsibility to ensure that the file is at least as big as
284    /// the new pool size.
285    ///
286    /// # Arguments
287    ///
288    /// - `size`: new size of the pool, in bytes
289    #[inline]
290    pub fn resize(&self, size: i32) {
291        let (arg0,) = (size,);
292        let mut args = [wl_argument { i: arg0 }];
293        // SAFETY: - self.proxy has the interface INTERFACE
294        //         - 2 < INTERFACE.method_count = 3
295        //         - the request signature is `i`
296        unsafe {
297            self.proxy.send_request(2, &mut args);
298        }
299    }
300}
301
302/// An event handler for [WlShmPool] proxies.
303#[allow(dead_code)]
304pub trait WlShmPoolEventHandler {}
305
306impl WlShmPoolEventHandler for private::NoOpEventHandler {}
307
308// SAFETY: - INTERFACE is a valid wl_interface
309unsafe impl<H> EventHandler for private::EventHandler<H>
310where
311    H: WlShmPoolEventHandler,
312{
313    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
314
315    #[allow(unused_variables)]
316    unsafe fn handle_event(
317        &self,
318        queue: &Queue,
319        data: *mut u8,
320        slf: &UntypedBorrowedProxy,
321        opcode: u32,
322        args: *mut wl_argument,
323    ) {
324        invalid_opcode("wl_shm_pool", opcode);
325    }
326}
327
328impl<H> CreateEventHandler<H> for private::ProxyApi
329where
330    H: WlShmPoolEventHandler,
331{
332    type EventHandler = private::EventHandler<H>;
333
334    #[inline]
335    fn create_event_handler(handler: H) -> Self::EventHandler {
336        private::EventHandler(handler)
337    }
338}
339
340/// Functional event handlers.
341pub mod event_handlers {
342    use super::*;
343
344    impl WlShmPool {}
345}