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}