simple_window/common/protocols_data/viewporter/wp_viewport.rs
1//! crop and scale interface to a wl_surface
2//!
3//! An additional interface to a wl_surface object, which allows the
4//! client to specify the cropping and scaling of the surface
5//! contents.
6//!
7//! This interface works with two concepts: the source rectangle (src_x,
8//! src_y, src_width, src_height), and the destination size (dst_width,
9//! dst_height). The contents of the source rectangle are scaled to the
10//! destination size, and content outside the source rectangle is ignored.
11//! This state is double-buffered, see wl_surface.commit.
12//!
13//! The two parts of crop and scale state are independent: the source
14//! rectangle, and the destination size. Initially both are unset, that
15//! is, no scaling is applied. The whole of the current wl_buffer is
16//! used as the source, and the surface size is as defined in
17//! wl_surface.attach.
18//!
19//! If the destination size is set, it causes the surface size to become
20//! dst_width, dst_height. The source (rectangle) is scaled to exactly
21//! this size. This overrides whatever the attached wl_buffer size is,
22//! unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface
23//! has no content and therefore no size. Otherwise, the size is always
24//! at least 1x1 in surface local coordinates.
25//!
26//! If the source rectangle is set, it defines what area of the wl_buffer is
27//! taken as the source. If the source rectangle is set and the destination
28//! size is not set, then src_width and src_height must be integers, and the
29//! surface size becomes the source rectangle size. This results in cropping
30//! without scaling. If src_width or src_height are not integers and
31//! destination size is not set, the bad_size protocol error is raised when
32//! the surface state is applied.
33//!
34//! The coordinate transformations from buffer pixel coordinates up to
35//! the surface-local coordinates happen in the following order:
36//! 1. buffer_transform (wl_surface.set_buffer_transform)
37//! 2. buffer_scale (wl_surface.set_buffer_scale)
38//! 3. crop and scale (wp_viewport.set*)
39//! This means, that the source rectangle coordinates of crop and scale
40//! are given in the coordinates after the buffer transform and scale,
41//! i.e. in the coordinates that would be the surface-local coordinates
42//! if the crop and scale was not applied.
43//!
44//! If src_x or src_y are negative, the bad_value protocol error is raised.
45//! Otherwise, if the source rectangle is partially or completely outside of
46//! the non-NULL wl_buffer, then the out_of_buffer protocol error is raised
47//! when the surface state is applied. A NULL wl_buffer does not raise the
48//! out_of_buffer error.
49//!
50//! If the wl_surface associated with the wp_viewport is destroyed,
51//! all wp_viewport requests except 'destroy' raise the protocol error
52//! no_surface.
53//!
54//! If the wp_viewport object is destroyed, the crop and scale
55//! state is removed from the wl_surface. The change will be applied
56//! on the next wl_surface.commit.
57
58use {super::super::all_types::*, ::wl_client::builder::prelude::*};
59
60static INTERFACE: wl_interface = wl_interface {
61 name: c"wp_viewport".as_ptr(),
62 version: 1,
63 method_count: 3,
64 methods: {
65 static MESSAGES: [wl_message; 3] = [
66 wl_message {
67 name: c"destroy".as_ptr(),
68 signature: c"".as_ptr(),
69 types: {
70 static TYPES: [Option<&'static wl_interface>; 0] = [];
71 TYPES.as_ptr().cast()
72 },
73 },
74 wl_message {
75 name: c"set_source".as_ptr(),
76 signature: c"ffff".as_ptr(),
77 types: {
78 static TYPES: [Option<&'static wl_interface>; 4] = [None, None, None, None];
79 TYPES.as_ptr().cast()
80 },
81 },
82 wl_message {
83 name: c"set_destination".as_ptr(),
84 signature: c"ii".as_ptr(),
85 types: {
86 static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
87 TYPES.as_ptr().cast()
88 },
89 },
90 ];
91 MESSAGES.as_ptr()
92 },
93 event_count: 0,
94 events: ptr::null(),
95};
96
97/// An owned wp_viewport proxy.
98///
99/// See the documentation of [the module][self] for the interface description.
100#[derive(Clone, Eq, PartialEq)]
101#[repr(transparent)]
102pub struct WpViewport {
103 /// This proxy has the interface INTERFACE.
104 proxy: UntypedOwnedProxy,
105}
106
107/// A borrowed wp_viewport proxy.
108///
109/// See the documentation of [the module][self] for the interface description.
110#[derive(Eq, PartialEq)]
111#[repr(transparent)]
112pub struct WpViewportRef {
113 /// This proxy has the interface INTERFACE.
114 proxy: UntypedBorrowedProxy,
115}
116
117// SAFETY: WpViewport is a transparent wrapper around UntypedOwnedProxy
118unsafe impl UntypedOwnedProxyWrapper for WpViewport {}
119
120// SAFETY: - INTERFACE is a valid wl_interface
121// - The only invariant is that self.proxy has a compatible interface
122unsafe impl OwnedProxy for WpViewport {
123 const INTERFACE: &'static str = "wp_viewport";
124 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
125 const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
126 private::EventHandler(private::NoOpEventHandler);
127 const MAX_VERSION: u32 = 1;
128
129 type Borrowed = WpViewportRef;
130 type Api = private::ProxyApi;
131 type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
132}
133
134// SAFETY: WpViewportRef is a transparent wrapper around UntypedBorrowedProxy
135unsafe impl UntypedBorrowedProxyWrapper for WpViewportRef {}
136
137// SAFETY: - The only invariant is that self.proxy has a compatible interface
138unsafe impl BorrowedProxy for WpViewportRef {
139 type Owned = WpViewport;
140}
141
142impl Deref for WpViewport {
143 type Target = WpViewportRef;
144
145 fn deref(&self) -> &Self::Target {
146 proxy::low_level::deref(self)
147 }
148}
149
150mod private {
151 pub struct ProxyApi;
152
153 #[allow(dead_code)]
154 pub struct EventHandler<H>(pub(super) H);
155
156 #[allow(dead_code)]
157 pub struct NoOpEventHandler;
158}
159
160impl Debug for WpViewport {
161 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
162 write!(f, "wp_viewport#{}", self.proxy.id())
163 }
164}
165
166impl Debug for WpViewportRef {
167 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
168 write!(f, "wp_viewport#{}", self.proxy.id())
169 }
170}
171
172impl PartialEq<WpViewportRef> for WpViewport {
173 fn eq(&self, other: &WpViewportRef) -> bool {
174 self.proxy == other.proxy
175 }
176}
177
178impl PartialEq<WpViewport> for WpViewportRef {
179 fn eq(&self, other: &WpViewport) -> bool {
180 self.proxy == other.proxy
181 }
182}
183
184#[allow(dead_code)]
185impl WpViewport {
186 /// Since when the destroy request is available.
187 #[allow(dead_code)]
188 pub const REQ__DESTROY__SINCE: u32 = 1;
189
190 /// remove scaling and cropping from the surface
191 ///
192 /// The associated wl_surface's crop and scale state is removed.
193 /// The change is applied on the next wl_surface.commit.
194 #[inline]
195 pub fn destroy(&self) {
196 let mut args = [];
197 // SAFETY: - self.proxy has the interface INTERFACE
198 // - 0 < INTERFACE.method_count = 3
199 // - the request signature is ``
200 unsafe {
201 self.proxy.send_destructor(0, &mut args);
202 }
203 }
204}
205
206#[allow(dead_code)]
207impl WpViewportRef {
208 /// set the source rectangle for cropping
209 ///
210 /// Set the source rectangle of the associated wl_surface. See
211 /// wp_viewport for the description, and relation to the wl_buffer
212 /// size.
213 ///
214 /// If all of x, y, width and height are -1.0, the source rectangle is
215 /// unset instead. Any other set of values where width or height are zero
216 /// or negative, or x or y are negative, raise the bad_value protocol
217 /// error.
218 ///
219 /// The crop and scale state is double-buffered, see wl_surface.commit.
220 ///
221 /// # Arguments
222 ///
223 /// - `x`: source rectangle x
224 /// - `y`: source rectangle y
225 /// - `width`: source rectangle width
226 /// - `height`: source rectangle height
227 #[inline]
228 pub fn set_source(&self, x: Fixed, y: Fixed, width: Fixed, height: Fixed) {
229 let (arg0, arg1, arg2, arg3) = (x, y, width, height);
230 let mut args = [
231 wl_argument { f: arg0.to_wire() },
232 wl_argument { f: arg1.to_wire() },
233 wl_argument { f: arg2.to_wire() },
234 wl_argument { f: arg3.to_wire() },
235 ];
236 // SAFETY: - self.proxy has the interface INTERFACE
237 // - 1 < INTERFACE.method_count = 3
238 // - the request signature is `ffff`
239 unsafe {
240 self.proxy.send_request(1, &mut args);
241 }
242 }
243
244 /// set the surface size for scaling
245 ///
246 /// Set the destination size of the associated wl_surface. See
247 /// wp_viewport for the description, and relation to the wl_buffer
248 /// size.
249 ///
250 /// If width is -1 and height is -1, the destination size is unset
251 /// instead. Any other pair of values for width and height that
252 /// contains zero or negative values raises the bad_value protocol
253 /// error.
254 ///
255 /// The crop and scale state is double-buffered, see wl_surface.commit.
256 ///
257 /// # Arguments
258 ///
259 /// - `width`: surface width
260 /// - `height`: surface height
261 #[inline]
262 pub fn set_destination(&self, width: i32, height: i32) {
263 let (arg0, arg1) = (width, height);
264 let mut args = [wl_argument { i: arg0 }, wl_argument { i: arg1 }];
265 // SAFETY: - self.proxy has the interface INTERFACE
266 // - 2 < INTERFACE.method_count = 3
267 // - the request signature is `ii`
268 unsafe {
269 self.proxy.send_request(2, &mut args);
270 }
271 }
272}
273
274/// An event handler for [WpViewport] proxies.
275#[allow(dead_code)]
276pub trait WpViewportEventHandler {
277 type Data: 'static;
278}
279
280impl WpViewportEventHandler for private::NoOpEventHandler {
281 type Data = ();
282}
283
284// SAFETY: - INTERFACE is a valid wl_interface
285// - mutable_type always returns the same value
286unsafe impl<H> EventHandler for private::EventHandler<H>
287where
288 H: WpViewportEventHandler,
289{
290 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
291
292 #[inline]
293 fn mutable_type() -> Option<(TypeId, &'static str)> {
294 let id = TypeId::of::<H::Data>();
295 let name = std::any::type_name::<H::Data>();
296 Some((id, name))
297 }
298
299 #[allow(unused_variables)]
300 unsafe fn handle_event(
301 &self,
302 queue: &Queue,
303 data: *mut u8,
304 slf: &UntypedBorrowedProxy,
305 opcode: u32,
306 args: *mut wl_argument,
307 ) {
308 invalid_opcode("wp_viewport", opcode);
309 }
310}
311
312impl<H> CreateEventHandler<H> for private::ProxyApi
313where
314 H: WpViewportEventHandler,
315{
316 type EventHandler = private::EventHandler<H>;
317
318 #[inline]
319 fn create_event_handler(handler: H) -> Self::EventHandler {
320 private::EventHandler(handler)
321 }
322}
323
324impl WpViewport {
325 /// Since when the error.bad_value enum variant is available.
326 #[allow(dead_code)]
327 pub const ENM__ERROR_BAD_VALUE__SINCE: u32 = 1;
328 /// Since when the error.bad_size enum variant is available.
329 #[allow(dead_code)]
330 pub const ENM__ERROR_BAD_SIZE__SINCE: u32 = 1;
331 /// Since when the error.out_of_buffer enum variant is available.
332 #[allow(dead_code)]
333 pub const ENM__ERROR_OUT_OF_BUFFER__SINCE: u32 = 1;
334 /// Since when the error.no_surface enum variant is available.
335 #[allow(dead_code)]
336 pub const ENM__ERROR_NO_SURFACE__SINCE: u32 = 1;
337}
338
339#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
340#[allow(dead_code)]
341pub struct WpViewportError(pub u32);
342
343impl WpViewportError {
344 /// negative or zero values in width or height
345 #[allow(dead_code)]
346 pub const BAD_VALUE: Self = Self(0);
347
348 /// destination size is not integer
349 #[allow(dead_code)]
350 pub const BAD_SIZE: Self = Self(1);
351
352 /// source rectangle extends outside of the content area
353 #[allow(dead_code)]
354 pub const OUT_OF_BUFFER: Self = Self(2);
355
356 /// the wl_surface was destroyed
357 #[allow(dead_code)]
358 pub const NO_SURFACE: Self = Self(3);
359}
360
361impl Debug for WpViewportError {
362 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
363 let name = match *self {
364 Self::BAD_VALUE => "BAD_VALUE",
365 Self::BAD_SIZE => "BAD_SIZE",
366 Self::OUT_OF_BUFFER => "OUT_OF_BUFFER",
367 Self::NO_SURFACE => "NO_SURFACE",
368 _ => return Debug::fmt(&self.0, f),
369 };
370 f.write_str(name)
371 }
372}
373
374/// Functional event handlers.
375pub mod event_handlers {
376 use super::*;
377
378 impl WpViewport {}
379}