async_roundtrip/common/protocols/wayland/
wl_surface.rs

1//! an onscreen surface
2//!
3//! A surface is a rectangular area that may be displayed on zero
4//! or more outputs, and shown any number of times at the compositor's
5//! discretion. They can present wl_buffers, receive user input, and
6//! define a local coordinate system.
7//!
8//! The size of a surface (and relative positions on it) is described
9//! in surface-local coordinates, which may differ from the buffer
10//! coordinates of the pixel content, in case a buffer_transform
11//! or a buffer_scale is used.
12//!
13//! A surface without a "role" is fairly useless: a compositor does
14//! not know where, when or how to present it. The role is the
15//! purpose of a wl_surface. Examples of roles are a cursor for a
16//! pointer (as set by wl_pointer.set_cursor), a drag icon
17//! (wl_data_device.start_drag), a sub-surface
18//! (wl_subcompositor.get_subsurface), and a window as defined by a
19//! shell protocol (e.g. wl_shell.get_shell_surface).
20//!
21//! A surface can have only one role at a time. Initially a
22//! wl_surface does not have a role. Once a wl_surface is given a
23//! role, it is set permanently for the whole lifetime of the
24//! wl_surface object. Giving the current role again is allowed,
25//! unless explicitly forbidden by the relevant interface
26//! specification.
27//!
28//! Surface roles are given by requests in other interfaces such as
29//! wl_pointer.set_cursor. The request should explicitly mention
30//! that this request gives a role to a wl_surface. Often, this
31//! request also creates a new protocol object that represents the
32//! role and adds additional functionality to wl_surface. When a
33//! client wants to destroy a wl_surface, they must destroy this role
34//! object before the wl_surface, otherwise a defunct_role_object error is
35//! sent.
36//!
37//! Destroying the role object does not remove the role from the
38//! wl_surface, but it may stop the wl_surface from "playing the role".
39//! For instance, if a wl_subsurface object is destroyed, the wl_surface
40//! it was created for will be unmapped and forget its position and
41//! z-order. It is allowed to create a wl_subsurface for the same
42//! wl_surface again, but it is not allowed to use the wl_surface as
43//! a cursor (cursor is a different role than sub-surface, and role
44//! switching is not allowed).
45
46use {super::super::all_types::*, ::wl_client::builder::prelude::*};
47
48static INTERFACE: wl_interface = wl_interface {
49    name: c"wl_surface".as_ptr(),
50    version: 6,
51    method_count: 11,
52    methods: {
53        static MESSAGES: [wl_message; 11] = [
54            wl_message {
55                name: c"destroy".as_ptr(),
56                signature: c"".as_ptr(),
57                types: {
58                    static TYPES: [Option<&'static wl_interface>; 0] = [];
59                    TYPES.as_ptr().cast()
60                },
61            },
62            wl_message {
63                name: c"attach".as_ptr(),
64                signature: c"?oii".as_ptr(),
65                types: {
66                    static TYPES: [Option<&'static wl_interface>; 3] =
67                        [Some(WlBuffer::WL_INTERFACE), None, None];
68                    TYPES.as_ptr().cast()
69                },
70            },
71            wl_message {
72                name: c"damage".as_ptr(),
73                signature: c"iiii".as_ptr(),
74                types: {
75                    static TYPES: [Option<&'static wl_interface>; 4] = [None, None, None, None];
76                    TYPES.as_ptr().cast()
77                },
78            },
79            wl_message {
80                name: c"frame".as_ptr(),
81                signature: c"n".as_ptr(),
82                types: {
83                    static TYPES: [Option<&'static wl_interface>; 1] =
84                        [Some(WlCallback::WL_INTERFACE)];
85                    TYPES.as_ptr().cast()
86                },
87            },
88            wl_message {
89                name: c"set_opaque_region".as_ptr(),
90                signature: c"?o".as_ptr(),
91                types: {
92                    static TYPES: [Option<&'static wl_interface>; 1] =
93                        [Some(WlRegion::WL_INTERFACE)];
94                    TYPES.as_ptr().cast()
95                },
96            },
97            wl_message {
98                name: c"set_input_region".as_ptr(),
99                signature: c"?o".as_ptr(),
100                types: {
101                    static TYPES: [Option<&'static wl_interface>; 1] =
102                        [Some(WlRegion::WL_INTERFACE)];
103                    TYPES.as_ptr().cast()
104                },
105            },
106            wl_message {
107                name: c"commit".as_ptr(),
108                signature: c"".as_ptr(),
109                types: {
110                    static TYPES: [Option<&'static wl_interface>; 0] = [];
111                    TYPES.as_ptr().cast()
112                },
113            },
114            wl_message {
115                name: c"set_buffer_transform".as_ptr(),
116                signature: c"i".as_ptr(),
117                types: {
118                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
119                    TYPES.as_ptr().cast()
120                },
121            },
122            wl_message {
123                name: c"set_buffer_scale".as_ptr(),
124                signature: c"i".as_ptr(),
125                types: {
126                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
127                    TYPES.as_ptr().cast()
128                },
129            },
130            wl_message {
131                name: c"damage_buffer".as_ptr(),
132                signature: c"iiii".as_ptr(),
133                types: {
134                    static TYPES: [Option<&'static wl_interface>; 4] = [None, None, None, None];
135                    TYPES.as_ptr().cast()
136                },
137            },
138            wl_message {
139                name: c"offset".as_ptr(),
140                signature: c"ii".as_ptr(),
141                types: {
142                    static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
143                    TYPES.as_ptr().cast()
144                },
145            },
146        ];
147        MESSAGES.as_ptr()
148    },
149    event_count: 4,
150    events: {
151        static MESSAGES: [wl_message; 4] = [
152            wl_message {
153                name: c"enter".as_ptr(),
154                signature: c"o".as_ptr(),
155                types: {
156                    static TYPES: [Option<&'static wl_interface>; 1] =
157                        [Some(WlOutput::WL_INTERFACE)];
158                    TYPES.as_ptr().cast()
159                },
160            },
161            wl_message {
162                name: c"leave".as_ptr(),
163                signature: c"o".as_ptr(),
164                types: {
165                    static TYPES: [Option<&'static wl_interface>; 1] =
166                        [Some(WlOutput::WL_INTERFACE)];
167                    TYPES.as_ptr().cast()
168                },
169            },
170            wl_message {
171                name: c"preferred_buffer_scale".as_ptr(),
172                signature: c"i".as_ptr(),
173                types: {
174                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
175                    TYPES.as_ptr().cast()
176                },
177            },
178            wl_message {
179                name: c"preferred_buffer_transform".as_ptr(),
180                signature: c"u".as_ptr(),
181                types: {
182                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
183                    TYPES.as_ptr().cast()
184                },
185            },
186        ];
187        MESSAGES.as_ptr()
188    },
189};
190
191/// An owned wl_surface proxy.
192///
193/// See the documentation of [the module][self] for the interface description.
194#[derive(Clone, Eq, PartialEq)]
195#[repr(transparent)]
196pub struct WlSurface {
197    /// This proxy has the interface INTERFACE.
198    proxy: UntypedOwnedProxy,
199}
200
201/// A borrowed wl_surface proxy.
202///
203/// See the documentation of [the module][self] for the interface description.
204#[derive(Eq, PartialEq)]
205#[repr(transparent)]
206pub struct WlSurfaceRef {
207    /// This proxy has the interface INTERFACE.
208    proxy: UntypedBorrowedProxy,
209}
210
211// SAFETY: WlSurface is a transparent wrapper around UntypedOwnedProxy
212unsafe impl UntypedOwnedProxyWrapper for WlSurface {}
213
214// SAFETY: - INTERFACE is a valid wl_interface
215//         - The only invariant is that self.proxy has a compatible interface
216unsafe impl OwnedProxy for WlSurface {
217    const INTERFACE: &'static str = "wl_surface";
218    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
219    const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
220        private::EventHandler(private::NoOpEventHandler);
221    const MAX_VERSION: u32 = 6;
222
223    type Borrowed = WlSurfaceRef;
224    type Api = private::ProxyApi;
225    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
226}
227
228// SAFETY: WlSurfaceRef is a transparent wrapper around UntypedBorrowedProxy
229unsafe impl UntypedBorrowedProxyWrapper for WlSurfaceRef {}
230
231// SAFETY: - The only invariant is that self.proxy has a compatible interface
232unsafe impl BorrowedProxy for WlSurfaceRef {
233    type Owned = WlSurface;
234}
235
236impl Deref for WlSurface {
237    type Target = WlSurfaceRef;
238
239    fn deref(&self) -> &Self::Target {
240        proxy::low_level::deref(self)
241    }
242}
243
244mod private {
245    pub struct ProxyApi;
246
247    #[allow(dead_code)]
248    pub struct EventHandler<H>(pub(super) H);
249
250    #[allow(dead_code)]
251    pub struct NoOpEventHandler;
252}
253
254impl Debug for WlSurface {
255    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
256        write!(f, "wl_surface#{}", self.proxy.id())
257    }
258}
259
260impl Debug for WlSurfaceRef {
261    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
262        write!(f, "wl_surface#{}", self.proxy.id())
263    }
264}
265
266impl PartialEq<WlSurfaceRef> for WlSurface {
267    fn eq(&self, other: &WlSurfaceRef) -> bool {
268        self.proxy == other.proxy
269    }
270}
271
272impl PartialEq<WlSurface> for WlSurfaceRef {
273    fn eq(&self, other: &WlSurface) -> bool {
274        self.proxy == other.proxy
275    }
276}
277
278#[allow(dead_code)]
279impl WlSurface {
280    /// Since when the destroy request is available.
281    #[allow(dead_code)]
282    pub const REQ__DESTROY__SINCE: u32 = 1;
283
284    /// delete surface
285    ///
286    /// Deletes the surface and invalidates its object ID.
287    #[inline]
288    pub fn destroy(&self) {
289        let mut args = [];
290        // SAFETY: - self.proxy has the interface INTERFACE
291        //         - 0 < INTERFACE.method_count = 11
292        //         - the request signature is ``
293        unsafe {
294            self.proxy.send_destructor(0, &mut args);
295        }
296    }
297
298    /// Since when the frame request is available.
299    #[allow(dead_code)]
300    pub const REQ__FRAME__SINCE: u32 = 1;
301
302    /// request a frame throttling hint
303    ///
304    /// Request a notification when it is a good time to start drawing a new
305    /// frame, by creating a frame callback. This is useful for throttling
306    /// redrawing operations, and driving animations.
307    ///
308    /// When a client is animating on a wl_surface, it can use the 'frame'
309    /// request to get notified when it is a good time to draw and commit the
310    /// next frame of animation. If the client commits an update earlier than
311    /// that, it is likely that some updates will not make it to the display,
312    /// and the client is wasting resources by drawing too often.
313    ///
314    /// The frame request will take effect on the next wl_surface.commit.
315    /// The notification will only be posted for one frame unless
316    /// requested again. For a wl_surface, the notifications are posted in
317    /// the order the frame requests were committed.
318    ///
319    /// The server must send the notifications so that a client
320    /// will not send excessive updates, while still allowing
321    /// the highest possible update rate for clients that wait for the reply
322    /// before drawing again. The server should give some time for the client
323    /// to draw and commit after sending the frame callback events to let it
324    /// hit the next output refresh.
325    ///
326    /// A server should avoid signaling the frame callbacks if the
327    /// surface is not visible in any way, e.g. the surface is off-screen,
328    /// or completely obscured by other opaque surfaces.
329    ///
330    /// The object returned by this request will be destroyed by the
331    /// compositor after the callback is fired and as such the client must not
332    /// attempt to use it after that point.
333    ///
334    /// The callback_data passed in the callback is the current time, in
335    /// milliseconds, with an undefined base.
336    #[inline]
337    pub fn frame(&self) -> WlCallback {
338        let mut args = [wl_argument { n: 0 }];
339        // SAFETY: - self.proxy has the interface INTERFACE
340        //         - 3 < INTERFACE.method_count = 11
341        //         - the request signature is `n`
342        //         - OwnedProxy::WL_INTERFACE is always a valid interface
343        let data = unsafe {
344            self.proxy
345                .send_constructor::<false>(3, &mut args, WlCallback::WL_INTERFACE, None)
346        };
347        // SAFETY: data has the interface WlCallback::WL_INTERFACE
348        unsafe { proxy::low_level::from_untyped_owned(data) }
349    }
350}
351
352#[allow(dead_code)]
353impl WlSurfaceRef {
354    /// set the surface contents
355    ///
356    /// Set a buffer as the content of this surface.
357    ///
358    /// The new size of the surface is calculated based on the buffer
359    /// size transformed by the inverse buffer_transform and the
360    /// inverse buffer_scale. This means that at commit time the supplied
361    /// buffer size must be an integer multiple of the buffer_scale. If
362    /// that's not the case, an invalid_size error is sent.
363    ///
364    /// The x and y arguments specify the location of the new pending
365    /// buffer's upper left corner, relative to the current buffer's upper
366    /// left corner, in surface-local coordinates. In other words, the
367    /// x and y, combined with the new surface size define in which
368    /// directions the surface's size changes. Setting anything other than 0
369    /// as x and y arguments is discouraged, and should instead be replaced
370    /// with using the separate wl_surface.offset request.
371    ///
372    /// When the bound wl_surface version is 5 or higher, passing any
373    /// non-zero x or y is a protocol violation, and will result in an
374    /// 'invalid_offset' error being raised. The x and y arguments are ignored
375    /// and do not change the pending state. To achieve equivalent semantics,
376    /// use wl_surface.offset.
377    ///
378    /// Surface contents are double-buffered state, see wl_surface.commit.
379    ///
380    /// The initial surface contents are void; there is no content.
381    /// wl_surface.attach assigns the given wl_buffer as the pending
382    /// wl_buffer. wl_surface.commit makes the pending wl_buffer the new
383    /// surface contents, and the size of the surface becomes the size
384    /// calculated from the wl_buffer, as described above. After commit,
385    /// there is no pending buffer until the next attach.
386    ///
387    /// Committing a pending wl_buffer allows the compositor to read the
388    /// pixels in the wl_buffer. The compositor may access the pixels at
389    /// any time after the wl_surface.commit request. When the compositor
390    /// will not access the pixels anymore, it will send the
391    /// wl_buffer.release event. Only after receiving wl_buffer.release,
392    /// the client may reuse the wl_buffer. A wl_buffer that has been
393    /// attached and then replaced by another attach instead of committed
394    /// will not receive a release event, and is not used by the
395    /// compositor.
396    ///
397    /// If a pending wl_buffer has been committed to more than one wl_surface,
398    /// the delivery of wl_buffer.release events becomes undefined. A well
399    /// behaved client should not rely on wl_buffer.release events in this
400    /// case. Alternatively, a client could create multiple wl_buffer objects
401    /// from the same backing storage or use wp_linux_buffer_release.
402    ///
403    /// Destroying the wl_buffer after wl_buffer.release does not change
404    /// the surface contents. Destroying the wl_buffer before wl_buffer.release
405    /// is allowed as long as the underlying buffer storage isn't re-used (this
406    /// can happen e.g. on client process termination). However, if the client
407    /// destroys the wl_buffer before receiving the wl_buffer.release event and
408    /// mutates the underlying buffer storage, the surface contents become
409    /// undefined immediately.
410    ///
411    /// If wl_surface.attach is sent with a NULL wl_buffer, the
412    /// following wl_surface.commit will remove the surface content.
413    ///
414    /// If a pending wl_buffer has been destroyed, the result is not specified.
415    /// Many compositors are known to remove the surface content on the following
416    /// wl_surface.commit, but this behaviour is not universal. Clients seeking to
417    /// maximise compatibility should not destroy pending buffers and should
418    /// ensure that they explicitly remove content from surfaces, even after
419    /// destroying buffers.
420    ///
421    /// # Arguments
422    ///
423    /// - `buffer`: buffer of surface contents
424    /// - `x`: surface-local x coordinate
425    /// - `y`: surface-local y coordinate
426    #[inline]
427    pub fn attach(&self, buffer: Option<&WlBufferRef>, x: i32, y: i32) {
428        let (arg0, arg1, arg2) = (buffer, x, y);
429        let obj0_lock = arg0.map(|arg0| proxy::lock(arg0));
430        let obj0 = obj0_lock
431            .map(|obj0_lock| check_argument_proxy("buffer", obj0_lock.wl_proxy()))
432            .unwrap_or(ptr::null_mut());
433        let mut args = [
434            wl_argument { o: obj0 },
435            wl_argument { i: arg1 },
436            wl_argument { i: arg2 },
437        ];
438        // SAFETY: - self.proxy has the interface INTERFACE
439        //         - 1 < INTERFACE.method_count = 11
440        //         - the request signature is `?oii`
441        unsafe {
442            self.proxy.send_request(1, &mut args);
443        }
444    }
445
446    /// mark part of the surface damaged
447    ///
448    /// This request is used to describe the regions where the pending
449    /// buffer is different from the current surface contents, and where
450    /// the surface therefore needs to be repainted. The compositor
451    /// ignores the parts of the damage that fall outside of the surface.
452    ///
453    /// Damage is double-buffered state, see wl_surface.commit.
454    ///
455    /// The damage rectangle is specified in surface-local coordinates,
456    /// where x and y specify the upper left corner of the damage rectangle.
457    ///
458    /// The initial value for pending damage is empty: no damage.
459    /// wl_surface.damage adds pending damage: the new pending damage
460    /// is the union of old pending damage and the given rectangle.
461    ///
462    /// wl_surface.commit assigns pending damage as the current damage,
463    /// and clears pending damage. The server will clear the current
464    /// damage as it repaints the surface.
465    ///
466    /// Note! New clients should not use this request. Instead damage can be
467    /// posted with wl_surface.damage_buffer which uses buffer coordinates
468    /// instead of surface coordinates.
469    ///
470    /// # Arguments
471    ///
472    /// - `x`: surface-local x coordinate
473    /// - `y`: surface-local y coordinate
474    /// - `width`: width of damage rectangle
475    /// - `height`: height of damage rectangle
476    #[inline]
477    pub fn damage(&self, x: i32, y: i32, width: i32, height: i32) {
478        let (arg0, arg1, arg2, arg3) = (x, y, width, height);
479        let mut args = [
480            wl_argument { i: arg0 },
481            wl_argument { i: arg1 },
482            wl_argument { i: arg2 },
483            wl_argument { i: arg3 },
484        ];
485        // SAFETY: - self.proxy has the interface INTERFACE
486        //         - 2 < INTERFACE.method_count = 11
487        //         - the request signature is `iiii`
488        unsafe {
489            self.proxy.send_request(2, &mut args);
490        }
491    }
492
493    /// request a frame throttling hint
494    ///
495    /// Request a notification when it is a good time to start drawing a new
496    /// frame, by creating a frame callback. This is useful for throttling
497    /// redrawing operations, and driving animations.
498    ///
499    /// When a client is animating on a wl_surface, it can use the 'frame'
500    /// request to get notified when it is a good time to draw and commit the
501    /// next frame of animation. If the client commits an update earlier than
502    /// that, it is likely that some updates will not make it to the display,
503    /// and the client is wasting resources by drawing too often.
504    ///
505    /// The frame request will take effect on the next wl_surface.commit.
506    /// The notification will only be posted for one frame unless
507    /// requested again. For a wl_surface, the notifications are posted in
508    /// the order the frame requests were committed.
509    ///
510    /// The server must send the notifications so that a client
511    /// will not send excessive updates, while still allowing
512    /// the highest possible update rate for clients that wait for the reply
513    /// before drawing again. The server should give some time for the client
514    /// to draw and commit after sending the frame callback events to let it
515    /// hit the next output refresh.
516    ///
517    /// A server should avoid signaling the frame callbacks if the
518    /// surface is not visible in any way, e.g. the surface is off-screen,
519    /// or completely obscured by other opaque surfaces.
520    ///
521    /// The object returned by this request will be destroyed by the
522    /// compositor after the callback is fired and as such the client must not
523    /// attempt to use it after that point.
524    ///
525    /// The callback_data passed in the callback is the current time, in
526    /// milliseconds, with an undefined base.
527    ///
528    /// # Arguments
529    ///
530    /// - `_queue`: The queue that the returned proxy is assigned to.
531    #[inline]
532    pub fn frame(&self, _queue: &Queue) -> WlCallback {
533        let mut args = [wl_argument { n: 0 }];
534        // SAFETY: - self.proxy has the interface INTERFACE
535        //         - 3 < INTERFACE.method_count = 11
536        //         - the request signature is `n`
537        //         - OwnedProxy::WL_INTERFACE is always a valid interface
538        let data = unsafe {
539            self.proxy
540                .send_constructor(_queue, 3, &mut args, WlCallback::WL_INTERFACE, None)
541        };
542        // SAFETY: data has the interface WlCallback::WL_INTERFACE
543        unsafe { proxy::low_level::from_untyped_owned(data) }
544    }
545
546    /// set opaque region
547    ///
548    /// This request sets the region of the surface that contains
549    /// opaque content.
550    ///
551    /// The opaque region is an optimization hint for the compositor
552    /// that lets it optimize the redrawing of content behind opaque
553    /// regions.  Setting an opaque region is not required for correct
554    /// behaviour, but marking transparent content as opaque will result
555    /// in repaint artifacts.
556    ///
557    /// The opaque region is specified in surface-local coordinates.
558    ///
559    /// The compositor ignores the parts of the opaque region that fall
560    /// outside of the surface.
561    ///
562    /// Opaque region is double-buffered state, see wl_surface.commit.
563    ///
564    /// wl_surface.set_opaque_region changes the pending opaque region.
565    /// wl_surface.commit copies the pending region to the current region.
566    /// Otherwise, the pending and current regions are never changed.
567    ///
568    /// The initial value for an opaque region is empty. Setting the pending
569    /// opaque region has copy semantics, and the wl_region object can be
570    /// destroyed immediately. A NULL wl_region causes the pending opaque
571    /// region to be set to empty.
572    ///
573    /// # Arguments
574    ///
575    /// - `region`: opaque region of the surface
576    #[inline]
577    pub fn set_opaque_region(&self, region: Option<&WlRegionRef>) {
578        let (arg0,) = (region,);
579        let obj0_lock = arg0.map(|arg0| proxy::lock(arg0));
580        let obj0 = obj0_lock
581            .map(|obj0_lock| check_argument_proxy("region", obj0_lock.wl_proxy()))
582            .unwrap_or(ptr::null_mut());
583        let mut args = [wl_argument { o: obj0 }];
584        // SAFETY: - self.proxy has the interface INTERFACE
585        //         - 4 < INTERFACE.method_count = 11
586        //         - the request signature is `?o`
587        unsafe {
588            self.proxy.send_request(4, &mut args);
589        }
590    }
591
592    /// set input region
593    ///
594    /// This request sets the region of the surface that can receive
595    /// pointer and touch events.
596    ///
597    /// Input events happening outside of this region will try the next
598    /// surface in the server surface stack. The compositor ignores the
599    /// parts of the input region that fall outside of the surface.
600    ///
601    /// The input region is specified in surface-local coordinates.
602    ///
603    /// Input region is double-buffered state, see wl_surface.commit.
604    ///
605    /// wl_surface.set_input_region changes the pending input region.
606    /// wl_surface.commit copies the pending region to the current region.
607    /// Otherwise the pending and current regions are never changed,
608    /// except cursor and icon surfaces are special cases, see
609    /// wl_pointer.set_cursor and wl_data_device.start_drag.
610    ///
611    /// The initial value for an input region is infinite. That means the
612    /// whole surface will accept input. Setting the pending input region
613    /// has copy semantics, and the wl_region object can be destroyed
614    /// immediately. A NULL wl_region causes the input region to be set
615    /// to infinite.
616    ///
617    /// # Arguments
618    ///
619    /// - `region`: input region of the surface
620    #[inline]
621    pub fn set_input_region(&self, region: Option<&WlRegionRef>) {
622        let (arg0,) = (region,);
623        let obj0_lock = arg0.map(|arg0| proxy::lock(arg0));
624        let obj0 = obj0_lock
625            .map(|obj0_lock| check_argument_proxy("region", obj0_lock.wl_proxy()))
626            .unwrap_or(ptr::null_mut());
627        let mut args = [wl_argument { o: obj0 }];
628        // SAFETY: - self.proxy has the interface INTERFACE
629        //         - 5 < INTERFACE.method_count = 11
630        //         - the request signature is `?o`
631        unsafe {
632            self.proxy.send_request(5, &mut args);
633        }
634    }
635
636    /// commit pending surface state
637    ///
638    /// Surface state (input, opaque, and damage regions, attached buffers,
639    /// etc.) is double-buffered. Protocol requests modify the pending state,
640    /// as opposed to the active state in use by the compositor.
641    ///
642    /// A commit request atomically creates a content update from the pending
643    /// state, even if the pending state has not been touched. The content
644    /// update is placed in a queue until it becomes active. After commit, the
645    /// new pending state is as documented for each related request.
646    ///
647    /// When the content update is applied, the wl_buffer is applied before all
648    /// other state. This means that all coordinates in double-buffered state
649    /// are relative to the newly attached wl_buffers, except for
650    /// wl_surface.attach itself. If there is no newly attached wl_buffer, the
651    /// coordinates are relative to the previous content update.
652    ///
653    /// All requests that need a commit to become effective are documented
654    /// to affect double-buffered state.
655    ///
656    /// Other interfaces may add further double-buffered surface state.
657    #[inline]
658    pub fn commit(&self) {
659        let mut args = [];
660        // SAFETY: - self.proxy has the interface INTERFACE
661        //         - 6 < INTERFACE.method_count = 11
662        //         - the request signature is ``
663        unsafe {
664            self.proxy.send_request(6, &mut args);
665        }
666    }
667
668    /// sets the buffer transformation
669    ///
670    /// This request sets the transformation that the client has already applied
671    /// to the content of the buffer. The accepted values for the transform
672    /// parameter are the values for wl_output.transform.
673    ///
674    /// The compositor applies the inverse of this transformation whenever it
675    /// uses the buffer contents.
676    ///
677    /// Buffer transform is double-buffered state, see wl_surface.commit.
678    ///
679    /// A newly created surface has its buffer transformation set to normal.
680    ///
681    /// wl_surface.set_buffer_transform changes the pending buffer
682    /// transformation. wl_surface.commit copies the pending buffer
683    /// transformation to the current one. Otherwise, the pending and current
684    /// values are never changed.
685    ///
686    /// The purpose of this request is to allow clients to render content
687    /// according to the output transform, thus permitting the compositor to
688    /// use certain optimizations even if the display is rotated. Using
689    /// hardware overlays and scanning out a client buffer for fullscreen
690    /// surfaces are examples of such optimizations. Those optimizations are
691    /// highly dependent on the compositor implementation, so the use of this
692    /// request should be considered on a case-by-case basis.
693    ///
694    /// Note that if the transform value includes 90 or 270 degree rotation,
695    /// the width of the buffer will become the surface height and the height
696    /// of the buffer will become the surface width.
697    ///
698    /// If transform is not one of the values from the
699    /// wl_output.transform enum the invalid_transform protocol error
700    /// is raised.
701    ///
702    /// # Arguments
703    ///
704    /// - `transform`: transform for interpreting buffer contents
705    #[inline]
706    pub fn set_buffer_transform(&self, transform: WlOutputTransform) {
707        let (arg0,) = (transform,);
708        let mut args = [wl_argument { u: arg0.0 }];
709        // SAFETY: - self.proxy has the interface INTERFACE
710        //         - 7 < INTERFACE.method_count = 11
711        //         - the request signature is `i`
712        unsafe {
713            self.proxy.send_request(7, &mut args);
714        }
715    }
716
717    /// sets the buffer scaling factor
718    ///
719    /// This request sets an optional scaling factor on how the compositor
720    /// interprets the contents of the buffer attached to the window.
721    ///
722    /// Buffer scale is double-buffered state, see wl_surface.commit.
723    ///
724    /// A newly created surface has its buffer scale set to 1.
725    ///
726    /// wl_surface.set_buffer_scale changes the pending buffer scale.
727    /// wl_surface.commit copies the pending buffer scale to the current one.
728    /// Otherwise, the pending and current values are never changed.
729    ///
730    /// The purpose of this request is to allow clients to supply higher
731    /// resolution buffer data for use on high resolution outputs. It is
732    /// intended that you pick the same buffer scale as the scale of the
733    /// output that the surface is displayed on. This means the compositor
734    /// can avoid scaling when rendering the surface on that output.
735    ///
736    /// Note that if the scale is larger than 1, then you have to attach
737    /// a buffer that is larger (by a factor of scale in each dimension)
738    /// than the desired surface size.
739    ///
740    /// If scale is not greater than 0 the invalid_scale protocol error is
741    /// raised.
742    ///
743    /// # Arguments
744    ///
745    /// - `scale`: scale for interpreting buffer contents
746    #[inline]
747    pub fn set_buffer_scale(&self, scale: i32) {
748        let (arg0,) = (scale,);
749        let mut args = [wl_argument { i: arg0 }];
750        // SAFETY: - self.proxy has the interface INTERFACE
751        //         - 8 < INTERFACE.method_count = 11
752        //         - the request signature is `i`
753        unsafe {
754            self.proxy.send_request(8, &mut args);
755        }
756    }
757
758    /// mark part of the surface damaged using buffer coordinates
759    ///
760    /// This request is used to describe the regions where the pending
761    /// buffer is different from the current surface contents, and where
762    /// the surface therefore needs to be repainted. The compositor
763    /// ignores the parts of the damage that fall outside of the surface.
764    ///
765    /// Damage is double-buffered state, see wl_surface.commit.
766    ///
767    /// The damage rectangle is specified in buffer coordinates,
768    /// where x and y specify the upper left corner of the damage rectangle.
769    ///
770    /// The initial value for pending damage is empty: no damage.
771    /// wl_surface.damage_buffer adds pending damage: the new pending
772    /// damage is the union of old pending damage and the given rectangle.
773    ///
774    /// wl_surface.commit assigns pending damage as the current damage,
775    /// and clears pending damage. The server will clear the current
776    /// damage as it repaints the surface.
777    ///
778    /// This request differs from wl_surface.damage in only one way - it
779    /// takes damage in buffer coordinates instead of surface-local
780    /// coordinates. While this generally is more intuitive than surface
781    /// coordinates, it is especially desirable when using wp_viewport
782    /// or when a drawing library (like EGL) is unaware of buffer scale
783    /// and buffer transform.
784    ///
785    /// Note: Because buffer transformation changes and damage requests may
786    /// be interleaved in the protocol stream, it is impossible to determine
787    /// the actual mapping between surface and buffer damage until
788    /// wl_surface.commit time. Therefore, compositors wishing to take both
789    /// kinds of damage into account will have to accumulate damage from the
790    /// two requests separately and only transform from one to the other
791    /// after receiving the wl_surface.commit.
792    ///
793    /// # Arguments
794    ///
795    /// - `x`: buffer-local x coordinate
796    /// - `y`: buffer-local y coordinate
797    /// - `width`: width of damage rectangle
798    /// - `height`: height of damage rectangle
799    #[inline]
800    pub fn damage_buffer(&self, x: i32, y: i32, width: i32, height: i32) {
801        let (arg0, arg1, arg2, arg3) = (x, y, width, height);
802        let mut args = [
803            wl_argument { i: arg0 },
804            wl_argument { i: arg1 },
805            wl_argument { i: arg2 },
806            wl_argument { i: arg3 },
807        ];
808        // SAFETY: - self.proxy has the interface INTERFACE
809        //         - 9 < INTERFACE.method_count = 11
810        //         - the request signature is `iiii`
811        unsafe {
812            self.proxy.send_request(9, &mut args);
813        }
814    }
815
816    /// set the surface contents offset
817    ///
818    /// The x and y arguments specify the location of the new pending
819    /// buffer's upper left corner, relative to the current buffer's upper
820    /// left corner, in surface-local coordinates. In other words, the
821    /// x and y, combined with the new surface size define in which
822    /// directions the surface's size changes.
823    ///
824    /// The exact semantics of wl_surface.offset are role-specific. Refer to
825    /// the documentation of specific roles for more information.
826    ///
827    /// Surface location offset is double-buffered state, see
828    /// wl_surface.commit.
829    ///
830    /// This request is semantically equivalent to and the replaces the x and y
831    /// arguments in the wl_surface.attach request in wl_surface versions prior
832    /// to 5. See wl_surface.attach for details.
833    ///
834    /// # Arguments
835    ///
836    /// - `x`: surface-local x coordinate
837    /// - `y`: surface-local y coordinate
838    #[inline]
839    pub fn offset(&self, x: i32, y: i32) {
840        let (arg0, arg1) = (x, y);
841        let mut args = [wl_argument { i: arg0 }, wl_argument { i: arg1 }];
842        // SAFETY: - self.proxy has the interface INTERFACE
843        //         - 10 < INTERFACE.method_count = 11
844        //         - the request signature is `ii`
845        unsafe {
846            self.proxy.send_request(10, &mut args);
847        }
848    }
849}
850
851impl WlSurface {
852    /// Since when the enter event is available.
853    #[allow(dead_code)]
854    pub const EVT__ENTER__SINCE: u32 = 1;
855
856    /// Since when the leave event is available.
857    #[allow(dead_code)]
858    pub const EVT__LEAVE__SINCE: u32 = 1;
859
860    /// Since when the preferred_buffer_scale event is available.
861    #[allow(dead_code)]
862    pub const EVT__PREFERRED_BUFFER_SCALE__SINCE: u32 = 6;
863
864    /// Since when the preferred_buffer_transform event is available.
865    #[allow(dead_code)]
866    pub const EVT__PREFERRED_BUFFER_TRANSFORM__SINCE: u32 = 6;
867}
868
869/// An event handler for [WlSurface] proxies.
870#[allow(dead_code)]
871pub trait WlSurfaceEventHandler {
872    /// surface enters an output
873    ///
874    /// This is emitted whenever a surface's creation, movement, or resizing
875    /// results in some part of it being within the scanout region of an
876    /// output.
877    ///
878    /// Note that a surface may be overlapping with zero or more outputs.
879    ///
880    /// # Arguments
881    ///
882    /// - `output`: output entered by the surface
883    ///
884    /// All borrowed proxies passed to this function are guaranteed to be
885    /// immutable and non-null.
886    #[inline]
887    fn enter(&self, _slf: &WlSurfaceRef, output: Option<&WlOutputRef>) {
888        let _ = output;
889    }
890
891    /// surface leaves an output
892    ///
893    /// This is emitted whenever a surface's creation, movement, or resizing
894    /// results in it no longer having any part of it within the scanout region
895    /// of an output.
896    ///
897    /// Clients should not use the number of outputs the surface is on for frame
898    /// throttling purposes. The surface might be hidden even if no leave event
899    /// has been sent, and the compositor might expect new surface content
900    /// updates even if no enter event has been sent. The frame event should be
901    /// used instead.
902    ///
903    /// # Arguments
904    ///
905    /// - `output`: output left by the surface
906    ///
907    /// All borrowed proxies passed to this function are guaranteed to be
908    /// immutable and non-null.
909    #[inline]
910    fn leave(&self, _slf: &WlSurfaceRef, output: Option<&WlOutputRef>) {
911        let _ = output;
912    }
913
914    /// preferred buffer scale for the surface
915    ///
916    /// This event indicates the preferred buffer scale for this surface. It is
917    /// sent whenever the compositor's preference changes.
918    ///
919    /// Before receiving this event the preferred buffer scale for this surface
920    /// is 1.
921    ///
922    /// It is intended that scaling aware clients use this event to scale their
923    /// content and use wl_surface.set_buffer_scale to indicate the scale they
924    /// have rendered with. This allows clients to supply a higher detail
925    /// buffer.
926    ///
927    /// The compositor shall emit a scale value greater than 0.
928    ///
929    /// # Arguments
930    ///
931    /// - `factor`: preferred scaling factor
932    #[inline]
933    fn preferred_buffer_scale(&self, _slf: &WlSurfaceRef, factor: i32) {
934        let _ = factor;
935    }
936
937    /// preferred buffer transform for the surface
938    ///
939    /// This event indicates the preferred buffer transform for this surface.
940    /// It is sent whenever the compositor's preference changes.
941    ///
942    /// Before receiving this event the preferred buffer transform for this
943    /// surface is normal.
944    ///
945    /// Applying this transformation to the surface buffer contents and using
946    /// wl_surface.set_buffer_transform might allow the compositor to use the
947    /// surface buffer more efficiently.
948    ///
949    /// # Arguments
950    ///
951    /// - `transform`: preferred transform
952    #[inline]
953    fn preferred_buffer_transform(&self, _slf: &WlSurfaceRef, transform: WlOutputTransform) {
954        let _ = transform;
955    }
956}
957
958impl WlSurfaceEventHandler for private::NoOpEventHandler {}
959
960// SAFETY: - INTERFACE is a valid wl_interface
961unsafe impl<H> EventHandler for private::EventHandler<H>
962where
963    H: WlSurfaceEventHandler,
964{
965    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
966
967    #[allow(unused_variables)]
968    unsafe fn handle_event(
969        &self,
970        queue: &Queue,
971        data: *mut u8,
972        slf: &UntypedBorrowedProxy,
973        opcode: u32,
974        args: *mut wl_argument,
975    ) {
976        // SAFETY: This function requires that slf has the interface INTERFACE
977        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlSurfaceRef>(slf) };
978        match opcode {
979            0 => {
980                // SAFETY: INTERFACE requires that there are 1 arguments
981                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
982                // SAFETY: - INTERFACE requires that args[0] contains an object
983                let arg0 = unsafe {
984                    if let Some(p) = NonNull::new(args[0].o.cast()) {
985                        Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
986                    } else {
987                        None
988                    }
989                };
990                // SAFETY: - INTERFACE requires that the object has the interface WlOutput::WL_INTERFACE
991                let arg0 = arg0.as_ref().map(|arg0| unsafe {
992                    proxy::low_level::from_untyped_borrowed::<WlOutputRef>(arg0)
993                });
994                self.0.enter(slf, arg0);
995            }
996            1 => {
997                // SAFETY: INTERFACE requires that there are 1 arguments
998                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
999                // SAFETY: - INTERFACE requires that args[0] contains an object
1000                let arg0 = unsafe {
1001                    if let Some(p) = NonNull::new(args[0].o.cast()) {
1002                        Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
1003                    } else {
1004                        None
1005                    }
1006                };
1007                // SAFETY: - INTERFACE requires that the object has the interface WlOutput::WL_INTERFACE
1008                let arg0 = arg0.as_ref().map(|arg0| unsafe {
1009                    proxy::low_level::from_untyped_borrowed::<WlOutputRef>(arg0)
1010                });
1011                self.0.leave(slf, arg0);
1012            }
1013            2 => {
1014                // SAFETY: INTERFACE requires that there are 1 arguments
1015                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
1016                // SAFETY: - INTERFACE requires that args[0] contains an int
1017                let arg0 = unsafe { args[0].i };
1018                self.0.preferred_buffer_scale(slf, arg0);
1019            }
1020            3 => {
1021                // SAFETY: INTERFACE requires that there are 1 arguments
1022                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
1023                // SAFETY: - INTERFACE requires that args[0] contains a uint
1024                let arg0 = unsafe { WlOutputTransform(args[0].u) };
1025                self.0.preferred_buffer_transform(slf, arg0);
1026            }
1027            _ => {
1028                invalid_opcode("wl_surface", opcode);
1029            }
1030        }
1031    }
1032}
1033
1034impl<H> CreateEventHandler<H> for private::ProxyApi
1035where
1036    H: WlSurfaceEventHandler,
1037{
1038    type EventHandler = private::EventHandler<H>;
1039
1040    #[inline]
1041    fn create_event_handler(handler: H) -> Self::EventHandler {
1042        private::EventHandler(handler)
1043    }
1044}
1045
1046impl WlSurface {
1047    /// Since when the error.invalid_scale enum variant is available.
1048    #[allow(dead_code)]
1049    pub const ENM__ERROR_INVALID_SCALE__SINCE: u32 = 1;
1050    /// Since when the error.invalid_transform enum variant is available.
1051    #[allow(dead_code)]
1052    pub const ENM__ERROR_INVALID_TRANSFORM__SINCE: u32 = 1;
1053    /// Since when the error.invalid_size enum variant is available.
1054    #[allow(dead_code)]
1055    pub const ENM__ERROR_INVALID_SIZE__SINCE: u32 = 1;
1056    /// Since when the error.invalid_offset enum variant is available.
1057    #[allow(dead_code)]
1058    pub const ENM__ERROR_INVALID_OFFSET__SINCE: u32 = 1;
1059    /// Since when the error.defunct_role_object enum variant is available.
1060    #[allow(dead_code)]
1061    pub const ENM__ERROR_DEFUNCT_ROLE_OBJECT__SINCE: u32 = 1;
1062}
1063
1064/// wl_surface error values
1065///
1066/// These errors can be emitted in response to wl_surface requests.
1067#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1068#[allow(dead_code)]
1069pub struct WlSurfaceError(pub u32);
1070
1071impl WlSurfaceError {
1072    /// buffer scale value is invalid
1073    #[allow(dead_code)]
1074    pub const INVALID_SCALE: Self = Self(0);
1075
1076    /// buffer transform value is invalid
1077    #[allow(dead_code)]
1078    pub const INVALID_TRANSFORM: Self = Self(1);
1079
1080    /// buffer size is invalid
1081    #[allow(dead_code)]
1082    pub const INVALID_SIZE: Self = Self(2);
1083
1084    /// buffer offset is invalid
1085    #[allow(dead_code)]
1086    pub const INVALID_OFFSET: Self = Self(3);
1087
1088    /// surface was destroyed before its role object
1089    #[allow(dead_code)]
1090    pub const DEFUNCT_ROLE_OBJECT: Self = Self(4);
1091}
1092
1093impl Debug for WlSurfaceError {
1094    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1095        let name = match *self {
1096            Self::INVALID_SCALE => "INVALID_SCALE",
1097            Self::INVALID_TRANSFORM => "INVALID_TRANSFORM",
1098            Self::INVALID_SIZE => "INVALID_SIZE",
1099            Self::INVALID_OFFSET => "INVALID_OFFSET",
1100            Self::DEFUNCT_ROLE_OBJECT => "DEFUNCT_ROLE_OBJECT",
1101            _ => return Debug::fmt(&self.0, f),
1102        };
1103        f.write_str(name)
1104    }
1105}
1106
1107/// Functional event handlers.
1108pub mod event_handlers {
1109    use super::*;
1110
1111    /// Event handler for enter events.
1112    pub struct Enter<F>(F);
1113    impl<F> WlSurfaceEventHandler for Enter<F>
1114    where
1115        F: Fn(&WlSurfaceRef, Option<&WlOutputRef>),
1116    {
1117        #[inline]
1118        fn enter(&self, _slf: &WlSurfaceRef, output: Option<&WlOutputRef>) {
1119            self.0(_slf, output)
1120        }
1121    }
1122
1123    /// Event handler for leave events.
1124    pub struct Leave<F>(F);
1125    impl<F> WlSurfaceEventHandler for Leave<F>
1126    where
1127        F: Fn(&WlSurfaceRef, Option<&WlOutputRef>),
1128    {
1129        #[inline]
1130        fn leave(&self, _slf: &WlSurfaceRef, output: Option<&WlOutputRef>) {
1131            self.0(_slf, output)
1132        }
1133    }
1134
1135    /// Event handler for preferred_buffer_scale events.
1136    pub struct PreferredBufferScale<F>(F);
1137    impl<F> WlSurfaceEventHandler for PreferredBufferScale<F>
1138    where
1139        F: Fn(&WlSurfaceRef, i32),
1140    {
1141        #[inline]
1142        fn preferred_buffer_scale(&self, _slf: &WlSurfaceRef, factor: i32) {
1143            self.0(_slf, factor)
1144        }
1145    }
1146
1147    /// Event handler for preferred_buffer_transform events.
1148    pub struct PreferredBufferTransform<F>(F);
1149    impl<F> WlSurfaceEventHandler for PreferredBufferTransform<F>
1150    where
1151        F: Fn(&WlSurfaceRef, WlOutputTransform),
1152    {
1153        #[inline]
1154        fn preferred_buffer_transform(&self, _slf: &WlSurfaceRef, transform: WlOutputTransform) {
1155            self.0(_slf, transform)
1156        }
1157    }
1158
1159    impl WlSurface {
1160        /// Creates an event handler for enter events.
1161        ///
1162        /// The event handler ignores all other events.
1163        #[allow(dead_code)]
1164        pub fn on_enter<F>(f: F) -> Enter<F>
1165        where
1166            F: Fn(&WlSurfaceRef, Option<&WlOutputRef>),
1167        {
1168            Enter(f)
1169        }
1170
1171        /// Creates an event handler for leave events.
1172        ///
1173        /// The event handler ignores all other events.
1174        #[allow(dead_code)]
1175        pub fn on_leave<F>(f: F) -> Leave<F>
1176        where
1177            F: Fn(&WlSurfaceRef, Option<&WlOutputRef>),
1178        {
1179            Leave(f)
1180        }
1181
1182        /// Creates an event handler for preferred_buffer_scale events.
1183        ///
1184        /// The event handler ignores all other events.
1185        #[allow(dead_code)]
1186        pub fn on_preferred_buffer_scale<F>(f: F) -> PreferredBufferScale<F>
1187        where
1188            F: Fn(&WlSurfaceRef, i32),
1189        {
1190            PreferredBufferScale(f)
1191        }
1192
1193        /// Creates an event handler for preferred_buffer_transform events.
1194        ///
1195        /// The event handler ignores all other events.
1196        #[allow(dead_code)]
1197        pub fn on_preferred_buffer_transform<F>(f: F) -> PreferredBufferTransform<F>
1198        where
1199            F: Fn(&WlSurfaceRef, WlOutputTransform),
1200        {
1201            PreferredBufferTransform(f)
1202        }
1203    }
1204}