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}