async_roundtrip/common/protocols_data/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    type Data: 'static;
873
874    /// surface enters an output
875    ///
876    /// This is emitted whenever a surface's creation, movement, or resizing
877    /// results in some part of it being within the scanout region of an
878    /// output.
879    ///
880    /// Note that a surface may be overlapping with zero or more outputs.
881    ///
882    /// # Arguments
883    ///
884    /// - `output`: output entered by the surface
885    ///
886    /// All borrowed proxies passed to this function are guaranteed to be
887    /// immutable and non-null.
888    #[inline]
889    fn enter(&self, _data: &mut Self::Data, _slf: &WlSurfaceRef, output: Option<&WlOutputRef>) {
890        let _ = output;
891    }
892
893    /// surface leaves an output
894    ///
895    /// This is emitted whenever a surface's creation, movement, or resizing
896    /// results in it no longer having any part of it within the scanout region
897    /// of an output.
898    ///
899    /// Clients should not use the number of outputs the surface is on for frame
900    /// throttling purposes. The surface might be hidden even if no leave event
901    /// has been sent, and the compositor might expect new surface content
902    /// updates even if no enter event has been sent. The frame event should be
903    /// used instead.
904    ///
905    /// # Arguments
906    ///
907    /// - `output`: output left by the surface
908    ///
909    /// All borrowed proxies passed to this function are guaranteed to be
910    /// immutable and non-null.
911    #[inline]
912    fn leave(&self, _data: &mut Self::Data, _slf: &WlSurfaceRef, output: Option<&WlOutputRef>) {
913        let _ = output;
914    }
915
916    /// preferred buffer scale for the surface
917    ///
918    /// This event indicates the preferred buffer scale for this surface. It is
919    /// sent whenever the compositor's preference changes.
920    ///
921    /// Before receiving this event the preferred buffer scale for this surface
922    /// is 1.
923    ///
924    /// It is intended that scaling aware clients use this event to scale their
925    /// content and use wl_surface.set_buffer_scale to indicate the scale they
926    /// have rendered with. This allows clients to supply a higher detail
927    /// buffer.
928    ///
929    /// The compositor shall emit a scale value greater than 0.
930    ///
931    /// # Arguments
932    ///
933    /// - `factor`: preferred scaling factor
934    #[inline]
935    fn preferred_buffer_scale(&self, _data: &mut Self::Data, _slf: &WlSurfaceRef, factor: i32) {
936        let _ = factor;
937    }
938
939    /// preferred buffer transform for the surface
940    ///
941    /// This event indicates the preferred buffer transform for this surface.
942    /// It is sent whenever the compositor's preference changes.
943    ///
944    /// Before receiving this event the preferred buffer transform for this
945    /// surface is normal.
946    ///
947    /// Applying this transformation to the surface buffer contents and using
948    /// wl_surface.set_buffer_transform might allow the compositor to use the
949    /// surface buffer more efficiently.
950    ///
951    /// # Arguments
952    ///
953    /// - `transform`: preferred transform
954    #[inline]
955    fn preferred_buffer_transform(
956        &self,
957        _data: &mut Self::Data,
958        _slf: &WlSurfaceRef,
959        transform: WlOutputTransform,
960    ) {
961        let _ = transform;
962    }
963}
964
965impl WlSurfaceEventHandler for private::NoOpEventHandler {
966    type Data = ();
967}
968
969// SAFETY: - INTERFACE is a valid wl_interface
970//         - mutable_type always returns the same value
971unsafe impl<H> EventHandler for private::EventHandler<H>
972where
973    H: WlSurfaceEventHandler,
974{
975    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
976
977    #[inline]
978    fn mutable_type() -> Option<(TypeId, &'static str)> {
979        let id = TypeId::of::<H::Data>();
980        let name = std::any::type_name::<H::Data>();
981        Some((id, name))
982    }
983
984    #[allow(unused_variables)]
985    unsafe fn handle_event(
986        &self,
987        queue: &Queue,
988        data: *mut u8,
989        slf: &UntypedBorrowedProxy,
990        opcode: u32,
991        args: *mut wl_argument,
992    ) {
993        // SAFETY: This function requires that slf has the interface INTERFACE
994        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlSurfaceRef>(slf) };
995        // SAFETY: This function requires that data is `&mut T` where `T`
996        //         has the type id returned by `Self::mutable_type`, i.e.,
997        //         `T = H::Data`.
998        let data: &mut H::Data = unsafe { &mut *data.cast() };
999        match opcode {
1000            0 => {
1001                // SAFETY: INTERFACE requires that there are 1 arguments
1002                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
1003                // SAFETY: - INTERFACE requires that args[0] contains an object
1004                let arg0 = unsafe {
1005                    if let Some(p) = NonNull::new(args[0].o.cast()) {
1006                        Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
1007                    } else {
1008                        None
1009                    }
1010                };
1011                // SAFETY: - INTERFACE requires that the object has the interface WlOutput::WL_INTERFACE
1012                let arg0 = arg0.as_ref().map(|arg0| unsafe {
1013                    proxy::low_level::from_untyped_borrowed::<WlOutputRef>(arg0)
1014                });
1015                self.0.enter(data, slf, arg0);
1016            }
1017            1 => {
1018                // SAFETY: INTERFACE requires that there are 1 arguments
1019                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
1020                // SAFETY: - INTERFACE requires that args[0] contains an object
1021                let arg0 = unsafe {
1022                    if let Some(p) = NonNull::new(args[0].o.cast()) {
1023                        Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
1024                    } else {
1025                        None
1026                    }
1027                };
1028                // SAFETY: - INTERFACE requires that the object has the interface WlOutput::WL_INTERFACE
1029                let arg0 = arg0.as_ref().map(|arg0| unsafe {
1030                    proxy::low_level::from_untyped_borrowed::<WlOutputRef>(arg0)
1031                });
1032                self.0.leave(data, slf, arg0);
1033            }
1034            2 => {
1035                // SAFETY: INTERFACE requires that there are 1 arguments
1036                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
1037                // SAFETY: - INTERFACE requires that args[0] contains an int
1038                let arg0 = unsafe { args[0].i };
1039                self.0.preferred_buffer_scale(data, slf, arg0);
1040            }
1041            3 => {
1042                // SAFETY: INTERFACE requires that there are 1 arguments
1043                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
1044                // SAFETY: - INTERFACE requires that args[0] contains a uint
1045                let arg0 = unsafe { WlOutputTransform(args[0].u) };
1046                self.0.preferred_buffer_transform(data, slf, arg0);
1047            }
1048            _ => {
1049                invalid_opcode("wl_surface", opcode);
1050            }
1051        }
1052    }
1053}
1054
1055impl<H> CreateEventHandler<H> for private::ProxyApi
1056where
1057    H: WlSurfaceEventHandler,
1058{
1059    type EventHandler = private::EventHandler<H>;
1060
1061    #[inline]
1062    fn create_event_handler(handler: H) -> Self::EventHandler {
1063        private::EventHandler(handler)
1064    }
1065}
1066
1067impl WlSurface {
1068    /// Since when the error.invalid_scale enum variant is available.
1069    #[allow(dead_code)]
1070    pub const ENM__ERROR_INVALID_SCALE__SINCE: u32 = 1;
1071    /// Since when the error.invalid_transform enum variant is available.
1072    #[allow(dead_code)]
1073    pub const ENM__ERROR_INVALID_TRANSFORM__SINCE: u32 = 1;
1074    /// Since when the error.invalid_size enum variant is available.
1075    #[allow(dead_code)]
1076    pub const ENM__ERROR_INVALID_SIZE__SINCE: u32 = 1;
1077    /// Since when the error.invalid_offset enum variant is available.
1078    #[allow(dead_code)]
1079    pub const ENM__ERROR_INVALID_OFFSET__SINCE: u32 = 1;
1080    /// Since when the error.defunct_role_object enum variant is available.
1081    #[allow(dead_code)]
1082    pub const ENM__ERROR_DEFUNCT_ROLE_OBJECT__SINCE: u32 = 1;
1083}
1084
1085/// wl_surface error values
1086///
1087/// These errors can be emitted in response to wl_surface requests.
1088#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1089#[allow(dead_code)]
1090pub struct WlSurfaceError(pub u32);
1091
1092impl WlSurfaceError {
1093    /// buffer scale value is invalid
1094    #[allow(dead_code)]
1095    pub const INVALID_SCALE: Self = Self(0);
1096
1097    /// buffer transform value is invalid
1098    #[allow(dead_code)]
1099    pub const INVALID_TRANSFORM: Self = Self(1);
1100
1101    /// buffer size is invalid
1102    #[allow(dead_code)]
1103    pub const INVALID_SIZE: Self = Self(2);
1104
1105    /// buffer offset is invalid
1106    #[allow(dead_code)]
1107    pub const INVALID_OFFSET: Self = Self(3);
1108
1109    /// surface was destroyed before its role object
1110    #[allow(dead_code)]
1111    pub const DEFUNCT_ROLE_OBJECT: Self = Self(4);
1112}
1113
1114impl Debug for WlSurfaceError {
1115    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1116        let name = match *self {
1117            Self::INVALID_SCALE => "INVALID_SCALE",
1118            Self::INVALID_TRANSFORM => "INVALID_TRANSFORM",
1119            Self::INVALID_SIZE => "INVALID_SIZE",
1120            Self::INVALID_OFFSET => "INVALID_OFFSET",
1121            Self::DEFUNCT_ROLE_OBJECT => "DEFUNCT_ROLE_OBJECT",
1122            _ => return Debug::fmt(&self.0, f),
1123        };
1124        f.write_str(name)
1125    }
1126}
1127
1128/// Functional event handlers.
1129pub mod event_handlers {
1130    use super::*;
1131
1132    /// Event handler for enter events.
1133    pub struct Enter<T, F>(F, PhantomData<fn(&mut T)>);
1134    impl<T, F> WlSurfaceEventHandler for Enter<T, F>
1135    where
1136        T: 'static,
1137        F: Fn(&mut T, &WlSurfaceRef, Option<&WlOutputRef>),
1138    {
1139        type Data = T;
1140
1141        #[inline]
1142        fn enter(&self, _data: &mut T, _slf: &WlSurfaceRef, output: Option<&WlOutputRef>) {
1143            self.0(_data, _slf, output)
1144        }
1145    }
1146
1147    /// Event handler for leave events.
1148    pub struct Leave<T, F>(F, PhantomData<fn(&mut T)>);
1149    impl<T, F> WlSurfaceEventHandler for Leave<T, F>
1150    where
1151        T: 'static,
1152        F: Fn(&mut T, &WlSurfaceRef, Option<&WlOutputRef>),
1153    {
1154        type Data = T;
1155
1156        #[inline]
1157        fn leave(&self, _data: &mut T, _slf: &WlSurfaceRef, output: Option<&WlOutputRef>) {
1158            self.0(_data, _slf, output)
1159        }
1160    }
1161
1162    /// Event handler for preferred_buffer_scale events.
1163    pub struct PreferredBufferScale<T, F>(F, PhantomData<fn(&mut T)>);
1164    impl<T, F> WlSurfaceEventHandler for PreferredBufferScale<T, F>
1165    where
1166        T: 'static,
1167        F: Fn(&mut T, &WlSurfaceRef, i32),
1168    {
1169        type Data = T;
1170
1171        #[inline]
1172        fn preferred_buffer_scale(&self, _data: &mut T, _slf: &WlSurfaceRef, factor: i32) {
1173            self.0(_data, _slf, factor)
1174        }
1175    }
1176
1177    /// Event handler for preferred_buffer_transform events.
1178    pub struct PreferredBufferTransform<T, F>(F, PhantomData<fn(&mut T)>);
1179    impl<T, F> WlSurfaceEventHandler for PreferredBufferTransform<T, F>
1180    where
1181        T: 'static,
1182        F: Fn(&mut T, &WlSurfaceRef, WlOutputTransform),
1183    {
1184        type Data = T;
1185
1186        #[inline]
1187        fn preferred_buffer_transform(
1188            &self,
1189            _data: &mut T,
1190            _slf: &WlSurfaceRef,
1191            transform: WlOutputTransform,
1192        ) {
1193            self.0(_data, _slf, transform)
1194        }
1195    }
1196
1197    impl WlSurface {
1198        /// Creates an event handler for enter events.
1199        ///
1200        /// The event handler ignores all other events.
1201        #[allow(dead_code)]
1202        pub fn on_enter<T, F>(f: F) -> Enter<T, F>
1203        where
1204            T: 'static,
1205            F: Fn(&mut T, &WlSurfaceRef, Option<&WlOutputRef>),
1206        {
1207            Enter(f, PhantomData)
1208        }
1209
1210        /// Creates an event handler for leave events.
1211        ///
1212        /// The event handler ignores all other events.
1213        #[allow(dead_code)]
1214        pub fn on_leave<T, F>(f: F) -> Leave<T, F>
1215        where
1216            T: 'static,
1217            F: Fn(&mut T, &WlSurfaceRef, Option<&WlOutputRef>),
1218        {
1219            Leave(f, PhantomData)
1220        }
1221
1222        /// Creates an event handler for preferred_buffer_scale events.
1223        ///
1224        /// The event handler ignores all other events.
1225        #[allow(dead_code)]
1226        pub fn on_preferred_buffer_scale<T, F>(f: F) -> PreferredBufferScale<T, F>
1227        where
1228            T: 'static,
1229            F: Fn(&mut T, &WlSurfaceRef, i32),
1230        {
1231            PreferredBufferScale(f, PhantomData)
1232        }
1233
1234        /// Creates an event handler for preferred_buffer_transform events.
1235        ///
1236        /// The event handler ignores all other events.
1237        #[allow(dead_code)]
1238        pub fn on_preferred_buffer_transform<T, F>(f: F) -> PreferredBufferTransform<T, F>
1239        where
1240            T: 'static,
1241            F: Fn(&mut T, &WlSurfaceRef, WlOutputTransform),
1242        {
1243            PreferredBufferTransform(f, PhantomData)
1244        }
1245    }
1246}